private void AssertState(int numReleasers, int numStallers, int numWaiters, ThreadClass[] threads, DocumentsWriterStallControl ctrl) { int millisToSleep = 100; while (true) { if (ctrl.HasBlocked() && ctrl.Healthy) { for (int n = numReleasers + numStallers; n < numReleasers + numStallers + numWaiters; n++) { if (ctrl.IsThreadQueued(threads[n])) { if (millisToSleep < 60000) { Thread.Sleep(millisToSleep); millisToSleep *= 2; break; } else { Assert.Fail("control claims no stalled threads but waiter seems to be blocked "); } } } break; } else { break; } } }
public virtual void TestSimpleStall() { DocumentsWriterStallControl ctrl = new DocumentsWriterStallControl(); ctrl.UpdateStalled(false); ThreadClass[] waitThreads = WaitThreads(AtLeast(1), ctrl); Start(waitThreads); Assert.IsFalse(ctrl.HasBlocked()); Assert.IsFalse(ctrl.AnyStalledThreads()); Join(waitThreads); // now stall threads and wake them up again ctrl.UpdateStalled(true); waitThreads = WaitThreads(AtLeast(1), ctrl); Start(waitThreads); AwaitState(ThreadState.WaitSleepJoin, waitThreads); Assert.IsTrue(ctrl.HasBlocked()); Assert.IsTrue(ctrl.AnyStalledThreads()); ctrl.UpdateStalled(false); Assert.IsFalse(ctrl.AnyStalledThreads()); Join(waitThreads); }
public virtual void TestAccquireReleaseRace() { DocumentsWriterStallControl ctrl = new DocumentsWriterStallControl(); ctrl.UpdateStalled(false); AtomicBoolean stop = new AtomicBoolean(false); AtomicBoolean checkPoint = new AtomicBoolean(true); int numStallers = AtLeast(1); int numReleasers = AtLeast(1); int numWaiters = AtLeast(1); var sync = new Synchronizer(numStallers + numReleasers, numStallers + numReleasers + numWaiters); var threads = new ThreadClass[numReleasers + numStallers + numWaiters]; IList <Exception> exceptions = new SynchronizedCollection <Exception>(); for (int i = 0; i < numReleasers; i++) { threads[i] = new Updater(stop, checkPoint, ctrl, sync, true, exceptions); } for (int i = numReleasers; i < numReleasers + numStallers; i++) { threads[i] = new Updater(stop, checkPoint, ctrl, sync, false, exceptions); } for (int i = numReleasers + numStallers; i < numReleasers + numStallers + numWaiters; i++) { threads[i] = new Waiter(stop, checkPoint, ctrl, sync, exceptions); } Start(threads); int iters = AtLeast(10000); float checkPointProbability = TEST_NIGHTLY ? 0.5f : 0.1f; for (int i = 0; i < iters; i++) { if (checkPoint.Get()) { Assert.IsTrue(sync.UpdateJoin.@await(new TimeSpan(0, 0, 0, 10)), "timed out waiting for update threads - deadlock?"); if (exceptions.Count > 0) { foreach (Exception throwable in exceptions) { Console.WriteLine(throwable.ToString()); Console.Write(throwable.StackTrace); } Assert.Fail("got exceptions in threads"); } if (ctrl.HasBlocked() && ctrl.Healthy) { AssertState(numReleasers, numStallers, numWaiters, threads, ctrl); } checkPoint.Set(false); sync.Waiter.countDown(); sync.LeftCheckpoint.@await(); } Assert.IsFalse(checkPoint.Get()); Assert.AreEqual(0, sync.Waiter.Remaining); if (checkPointProbability >= (float)Random().NextDouble()) { sync.Reset(numStallers + numReleasers, numStallers + numReleasers + numWaiters); checkPoint.Set(true); } } if (!checkPoint.Get()) { sync.Reset(numStallers + numReleasers, numStallers + numReleasers + numWaiters); checkPoint.Set(true); } Assert.IsTrue(sync.UpdateJoin.@await(new TimeSpan(0, 0, 0, 10))); AssertState(numReleasers, numStallers, numWaiters, threads, ctrl); checkPoint.Set(false); stop.Set(true); sync.Waiter.countDown(); sync.LeftCheckpoint.@await(); for (int i = 0; i < threads.Length; i++) { ctrl.UpdateStalled(false); threads[i].Join(2000); if (threads[i].IsAlive && threads[i] is Waiter) { if (threads[i].State == ThreadState.WaitSleepJoin) { Assert.Fail("waiter is not released - anyThreadsStalled: " + ctrl.AnyStalledThreads()); } } } }
public virtual void TestAccquireReleaseRace() { DocumentsWriterStallControl ctrl = new DocumentsWriterStallControl(); ctrl.UpdateStalled(false); AtomicBoolean stop = new AtomicBoolean(false); AtomicBoolean checkPoint = new AtomicBoolean(true); int numStallers = AtLeast(1); int numReleasers = AtLeast(1); int numWaiters = AtLeast(1); var sync = new Synchronizer(numStallers + numReleasers, numStallers + numReleasers + numWaiters); var threads = new ThreadClass[numReleasers + numStallers + numWaiters]; IList<Exception> exceptions = new SynchronizedCollection<Exception>(); for (int i = 0; i < numReleasers; i++) { threads[i] = new Updater(stop, checkPoint, ctrl, sync, true, exceptions); } for (int i = numReleasers; i < numReleasers + numStallers; i++) { threads[i] = new Updater(stop, checkPoint, ctrl, sync, false, exceptions); } for (int i = numReleasers + numStallers; i < numReleasers + numStallers + numWaiters; i++) { threads[i] = new Waiter(stop, checkPoint, ctrl, sync, exceptions); } Start(threads); int iters = AtLeast(10000); float checkPointProbability = TEST_NIGHTLY ? 0.5f : 0.1f; for (int i = 0; i < iters; i++) { if (checkPoint.Get()) { Assert.IsTrue(sync.UpdateJoin.@await(new TimeSpan(0, 0, 0, 10)), "timed out waiting for update threads - deadlock?"); if (exceptions.Count > 0) { foreach (Exception throwable in exceptions) { Console.WriteLine(throwable.ToString()); Console.Write(throwable.StackTrace); } Assert.Fail("got exceptions in threads"); } if (ctrl.HasBlocked() && ctrl.Healthy) { AssertState(numReleasers, numStallers, numWaiters, threads, ctrl); } checkPoint.Set(false); sync.Waiter.countDown(); sync.LeftCheckpoint.@await(); } Assert.IsFalse(checkPoint.Get()); Assert.AreEqual(0, sync.Waiter.Remaining); if (checkPointProbability >= (float)Random().NextDouble()) { sync.Reset(numStallers + numReleasers, numStallers + numReleasers + numWaiters); checkPoint.Set(true); } } if (!checkPoint.Get()) { sync.Reset(numStallers + numReleasers, numStallers + numReleasers + numWaiters); checkPoint.Set(true); } Assert.IsTrue(sync.UpdateJoin.@await(new TimeSpan(0, 0, 0, 10))); AssertState(numReleasers, numStallers, numWaiters, threads, ctrl); checkPoint.Set(false); stop.Set(true); sync.Waiter.countDown(); sync.LeftCheckpoint.@await(); for (int i = 0; i < threads.Length; i++) { ctrl.UpdateStalled(false); threads[i].Join(2000); if (threads[i].IsAlive && threads[i] is Waiter) { if (threads[i].State == ThreadState.WaitSleepJoin) { Assert.Fail("waiter is not released - anyThreadsStalled: " + ctrl.AnyStalledThreads()); } } } }