/// <summary> /// Causes the calling thread to enter a condition variable wait using the specified ResourceLock. /// </summary> /// <param name="resourceLock">A reference to the ResourceLock object that will be /// temporarily released while waiting for the condition to change.</param> /// <param name="reacquireForWriting">true if the ResourceLock should be reacquired for writing when the condition changes; /// false if the lock should be reacquired for reading when the condition changes.</param> public void CVWait(ResourceLock resourceLock, Boolean reacquireForWriting) { Contract.Requires(resourceLock != null); // We can't wait on a lock that is free; the lock must currently be held if (resourceLock.CurrentlyFree()) throw new InvalidOperationException("Can't wait on free lock."); // Indicate that this thread is going to pause // This value is "decremented" in Unpause Interlocked.Increment(ref m_numPausedThreads); //Console.WriteLine("{0}: Inc to {1}", Thread.CurrentThread.ManagedThreadId, m_numPausedThreads); AutoResetEvent are = new AutoResetEvent(false); m_waitingThreads.AddLast(are); // Find out if the lock is held by readers or a writer //Boolean reading = resourceLock.CurrentReaderCount() > 0; // Release the lock held by this thread resourceLock.Leave(); // Make this thread paused until unpaused are.WaitOne(); //m_semaphore.WaitOne(); // Make this thread regain the lock it used to hold resourceLock.Enter(reacquireForWriting); }
private void StressLoop(ResourceLock rl) { Random random = new Random((Int32)DateTime.Now.Ticks); for (Int32 i = 0; i < m_iterations; i++) { if ((i > 0) && (i % (m_iterations / 10)) == 0) Console.WriteLine(" {0}: iteration={1}", Thread.CurrentThread.Name, i); rl.Enter(random.Next(m_readerWriterRatio) == 0); for (Int32 work = 0; work < m_workSpinCount; work++) ; rl.Leave(); } }
private void Loop(Boolean write, ResourceLock rl) { Int32 z = 0; for (Int32 x = 0; x < m_iterations; x++) { if (write) { rl.Enter(true); z = x; rl.Leave(); } else { rl.Enter(false); Int32 y = z; rl.Leave(); } } }
public TimeSpan Test(Boolean write, Int32 threadCount, ResourceLock rl) { // Make sure that the methods are JITted so that JIT time is not included in the results rl.Enter(false); rl.Leave(); rl.Enter(true); rl.Leave(); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); try { Thread.CurrentThread.Priority = ThreadPriority.Highest; Stopwatch stopWatch = Stopwatch.StartNew(); Thread[] threads = new Thread[threadCount - 1]; for (Int32 t = 0; t < threads.Length - 1; t++) { threads[t] = new Thread((ThreadStart)delegate { Loop(write, rl); }); threads[t].Name = "FuncTest_Deadlock_Test thread #" + t; threads[t].Start(); } Loop(write, rl); for (Int32 t = 0; t < threads.Length - 1; t++) { threads[t].Join(); //threads[ls].Dispose(); } return stopWatch.Elapsed; } finally { Thread.CurrentThread.Priority = ThreadPriority.Normal; } }
private static void FuncTest_Deadlock_Test(ResourceLock l, Boolean write1st, Boolean write2nd, Boolean expectedToFail) { try { try { l.Enter(write1st); { l.Enter(write2nd); l.Leave(); } l.Leave(); if (expectedToFail) throw new InvalidProgramException("No deadlock detected when expected."); } catch (Exception<DeadlockExceptionArgs>) { if (!expectedToFail) throw new InvalidProgramException("Deadlock detected when not expected."); } } catch (InvalidOperationException) { // This can happen if deadlock detector throws before taking // a lock and the we try to release the lock anyway } //DeadlockDetector.ForceClear(); }