public void TestSingleDecreaseWork() { PartialThreadBlocker inst = new PartialThreadBlocker(4); Barrier startBar = new Barrier(1 + 1); int exitedCount = 0; Task.Run(() => { startBar.SignalAndWait(); inst.Wait(); Interlocked.Increment(ref exitedCount); }); startBar.SignalAndWait(); TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount); TimingAssert.AreEqual(5000, 1, () => inst.RealWaiterCount, "RealWaiterCount != 1"); for (int i = 1; i <= 4; i++) { inst.SubstractExpectedWaiterCount(1); TimingAssert.AreEqual(5000, 4 - i, () => inst.ExpectedWaiterCount); TimingAssert.AreEqual(5000, i == 4 ? 0 : 1, () => inst.RealWaiterCount); } TimingAssert.AreEqual(5000, 1, () => Volatile.Read(ref exitedCount), "exitedCount != 1"); }
/// <summary> /// Активировать поток /// </summary> /// <returns>Успешность</returns> private bool ActivateThread() { if (EvaluatePausedThreadCountFromCombination(Volatile.Read(ref _dieSlotActiveFullThreadCountCombination)) == 0) { return(false); } bool wasThreadActivated = false; lock (_syncObject) { try { } finally { if (IncrementActiveThreadCount()) { _extThreadBlocker.SubstractExpectedWaiterCount(1); //Console.WriteLine("Thread activated = " + ActiveThreadCount.ToString()); wasThreadActivated = true; } } } return(wasThreadActivated); }
public void TestFullCycle() { PartialThreadBlocker inst = new PartialThreadBlocker(0); Barrier startBar = new Barrier(8 + 1); int exitedCount = 0; CancellationTokenSource tokenSrc = new CancellationTokenSource(); Thread[] threads = new Thread[8]; Func <int> sleepThCount = () => { int result = 0; foreach (var th in threads) { if ((th.ThreadState & ThreadState.WaitSleepJoin) != 0) { result++; } } return(result); }; for (int i = 0; i < threads.Length; i++) { threads[i] = new Thread(() => { startBar.SignalAndWait(); while (!tokenSrc.IsCancellationRequested) { inst.Wait(); SpinWaitHelper.SpinWait(1200); Thread.Yield(); } Interlocked.Increment(ref exitedCount); }); threads[i].Start(); } startBar.SignalAndWait(); for (int i = 0; i < threads.Length; i++) { TimingAssert.AreEqual(5000, i, sleepThCount, "UP. Sleeping thread count != i"); TimingAssert.AreEqual(5000, i, () => inst.RealWaiterCount, "UP. RealWaiterCount != i"); TimingAssert.AreEqual(5000, i, () => inst.ExpectedWaiterCount, "UP. ExpectedWaiterCount != i"); inst.AddExpectedWaiterCount(1); Thread.Sleep(10); } TimingAssert.AreEqual(5000, threads.Length, sleepThCount); TimingAssert.AreEqual(5000, threads.Length, () => inst.RealWaiterCount); TimingAssert.AreEqual(5000, threads.Length, () => inst.ExpectedWaiterCount); for (int i = threads.Length; i > 0; i--) { TimingAssert.AreEqual(5000, i, sleepThCount); TimingAssert.AreEqual(5000, i, () => inst.RealWaiterCount); TimingAssert.AreEqual(5000, i, () => inst.ExpectedWaiterCount); inst.SubstractExpectedWaiterCount(1); Thread.Sleep(10); } TimingAssert.AreEqual(5000, 0, sleepThCount, "Sleeping thread count != 0"); TimingAssert.AreEqual(5000, 0, () => inst.RealWaiterCount, "RealWaiterCount != 0"); TimingAssert.AreEqual(5000, 0, () => inst.ExpectedWaiterCount, "ExpectedWaiterCount != 0"); tokenSrc.Cancel(); TimingAssert.AreEqual(5000, threads.Length, () => Volatile.Read(ref exitedCount)); }