public void TestStressWait() { const int iterations = 1000000; const int doHardWorkBeforeEachNthProducing = iterations / 100; var threadCount = Environment.ProcessorCount; var src = 0; var dst = 0; var addingCompleted = false; var m = new MonitorSimple(); var readers = RunSimultanously(threadCount, () => { while (true) { using (m.GetLocked()) using (m.GetLocked()) using (m.GetLocked()) { while (src == 0 && !addingCompleted) m.Wait(); if (addingCompleted && src == 0) break; src = src - 1; dst = dst + 1; } } }, false); RunSimultanously(threadCount, () => { for (var i = 0; i < iterations; i++) { if (i % doHardWorkBeforeEachNthProducing == 0) DoHardWork(); using (m.GetLocked()) using (m.GetLocked()) //for extra stressing { src = src + 1; // such a weird construct is for extra stressing if (i % 2 == 0) m.Pulse(); else m.PulseAll(); } } }, true); using (m.GetLocked()) { addingCompleted = true; m.PulseAll(); } readers.ForEach(r => r.Join()); var expected = Enumerable.Repeat(1, iterations).Sum() * threadCount; Assert.AreEqual(expected, dst); }
public void TestEnterExitInGeneral() { const int threadCount = 10; const int iterations = 100000; long n = 0; var montor = new MonitorSimple(); RunSimultanously(threadCount, () => { for (var i = 0; i < iterations; i++) { using (montor.GetLocked()) using (montor.GetLocked()) using (montor.GetLocked()) { n = n + 1; if (i % 100 == 0) Thread.SpinWait(10000); } } }, true); var expected = Enumerable.Repeat(1, iterations).Sum() * threadCount; Assert.AreEqual(expected, n); }
public void TestStressLockedSectionsDoNotOverlapp() { const int iterations = 100000; var entered = 0; var overlapped = false; var m = new MonitorSimple(); RunSimultanously(5, () => { for (var i = 0; i < iterations; i++) { using (m.GetLocked()) using (m.GetLocked()) { if (Interlocked.CompareExchange(ref entered, 1, 0) != 0) overlapped = true; Thread.SpinWait(i % 100 == 0 ? 10000 : 1); if (Interlocked.CompareExchange(ref entered, 0, 1) != 1) overlapped = true; } } }, true); Assert.IsTrue(entered == 0); Assert.IsFalse(overlapped); }