public void TestCheckingEnterExitOwnership() { var monitor = new MonitorSimple(); var finished = 0; var th = new Thread(() => { monitor.Enter(); while (finished == 0) { } }) { IsBackground = true }; th.Start(); WaitAlittle(); AssertEx.Throws<SynchronizationLockException>(() => monitor.Exit()); Thread.VolatileWrite(ref finished, 1); }
public LockHandle(MonitorSimple source) { _source = source; }
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 TestWait() { var e = new ManualResetEvent(false); var m = new MonitorSimple(); var testValue = 0; var th1 = new Thread(() => { m.Enter(); testValue = 1; e.WaitOne(); m.Wait(); testValue = 2; m.Exit(); }) { Name = "th1" }; var th2 = new Thread(() => { m.Enter(); testValue = 100; m.Exit(); }) { Name = "th2" }; th1.Start(); WaitAlittle(); th2.Start(); WaitAlittle(); Assert.AreEqual(1, testValue); e.Set(); WaitAlittle(); Assert.AreEqual(100, testValue); m.Enter(); m.PulseAll(); m.Exit(); WaitAlittle(); Assert.AreEqual(2, testValue); }
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 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); }