// ========================= private void TakeWakesUpTest(DiskQueue <int> queue) { Barrier bar = new Barrier(2); AtomicNullableBool takeResult = new AtomicNullableBool(); AtomicNullableBool takeResult2 = new AtomicNullableBool(); Task task = Task.Run(() => { bar.SignalAndWait(); int item = 0; takeResult.Value = queue.TryTake(out item, 60000); Assert.AreEqual(100, item); item = 0; takeResult2.Value = queue.TryTake(out item, 60000); Assert.AreEqual(200, item); }); bar.SignalAndWait(); Thread.Sleep(10); Assert.IsFalse(takeResult.HasValue); queue.Add(100); TimingAssert.AreEqual(10000, true, () => takeResult.Value); Thread.Sleep(10); Assert.IsFalse(takeResult2.HasValue); queue.Add(200); TimingAssert.AreEqual(10000, true, () => takeResult2.Value); task.Wait(); }
public void TestNotificationReceived() { object syncObj = new object(); using (var testInst = new ConditionVariable(syncObj)) { int result = 0; var task = Task.Run(() => { using (var waiter = testInst.Enter(60000)) { if (waiter.Wait()) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount); Assert.AreEqual(0, Volatile.Read(ref result)); lock (syncObj) { testInst.Pulse(); } TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result)); } }
public void TestWaitingPassed() { using (var inst = new MutuallyExclusivePrimitive()) { Barrier bar = new Barrier(2); int result = 0; var task = Task.Run(() => { bar.SignalAndWait(); using (var guard = inst.EnterBackground(60000, default(CancellationToken))) { if (guard.IsAcquired) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); bar.SignalAndWait(); Thread.Sleep(20); inst.AllowBackgroundGate(); TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result)); task.Wait(); } }
public void TestLongPredicateEstimatesOnceWithSmallTimeout() { object syncObj = new object(); using (var testInst = new ConditionVariable(syncObj)) { int result = 0; int estimCount = 0; var task = Task.Run(() => { using (var waiter = testInst.Enter(200)) { if (waiter.Wait(_ => { Interlocked.Increment(ref estimCount); Thread.Sleep(500); return(false); }, (object)null)) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); lock (syncObj) { testInst.Pulse(); } TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref result)); Assert.AreEqual(1, Volatile.Read(ref estimCount)); } }
public void TestInterruptOnDispose() { object syncObj = new object(); using (var testInst = new ConditionVariable(syncObj)) { int exitCount = 0; var task = Task.Run(() => { try { using (var waiter = testInst.Enter()) { waiter.Wait(_ => false, (object)null); } } catch (OperationInterruptedException) { } Interlocked.Increment(ref exitCount); }); TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount); testInst.Dispose(); TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref exitCount)); task.Wait(); } }
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"); }
public void TestBlockRequiredCount() { PartialThreadBlocker inst = new PartialThreadBlocker(4); Barrier startBar = new Barrier(8 + 1); int exitedCount = 0; for (int i = 0; i < 8; i++) { Task.Run(() => { startBar.SignalAndWait(); inst.Wait(); Interlocked.Increment(ref exitedCount); }); } startBar.SignalAndWait(); Assert.IsTrue(SpinWait.SpinUntil(() => Volatile.Read(ref exitedCount) >= 4 && inst.RealWaiterCount >= 4, 4000)); TimingAssert.AreEqual(5000, 8 - 4, () => Volatile.Read(ref exitedCount), "exitedCount != 8"); TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount, "ExpectedWaiterCount != 4"); TimingAssert.AreEqual(5000, 4, () => inst.RealWaiterCount, "RealWaiterCount != 4"); inst.SetExpectedWaiterCount(0); TimingAssert.AreEqual(5000, 8, () => Volatile.Read(ref exitedCount), "exitedCount != 8"); TimingAssert.AreEqual(5000, 0, () => inst.ExpectedWaiterCount, "ExpectedWaiterCount != 0"); TimingAssert.AreEqual(5000, 0, () => inst.RealWaiterCount, "RealWaiterCount != 0"); }
public void TestTakeLock() { ThreadPoolQueueController q = new ThreadPoolQueueController(100, 1000); bool takeCompleted = false; int takeItem = 0; int startedFlag = 0; Task.Run(() => { Interlocked.Exchange(ref startedFlag, 1); takeItem = (TestThreadPoolItem)q.Take(null); Volatile.Write(ref takeCompleted, true); }); TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1); Thread.Sleep(100); Assert.IsFalse(takeCompleted); q.Add(new TestThreadPoolItem(10), null); TimingAssert.IsTrue(5000, () => Volatile.Read(ref takeCompleted)); Assert.AreEqual(10, takeItem); Assert.AreEqual(0, q.GlobalQueue.OccupiedNodesCount); }
public void TestSilentTakeCancellation() { ThreadPoolQueueController q = new ThreadPoolQueueController(100, 1000); CancellationTokenSource cSrc = new CancellationTokenSource(); bool takeCompleted = false; bool takeResult = false; ThreadPoolWorkItem takenItem = null; int startedFlag = 0; Task.Run(() => { Interlocked.Exchange(ref startedFlag, 1); var res = q.TryTake(null, out takenItem, -1, cSrc.Token, false); Volatile.Write(ref takeResult, res); Volatile.Write(ref takeCompleted, true); }); TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1); Thread.Sleep(100); Assert.IsFalse(takeCompleted); cSrc.Cancel(); TimingAssert.IsTrue(5000, () => Volatile.Read(ref takeCompleted)); Assert.IsFalse(takeResult); Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(1), null, false, 0, CancellationToken.None)); Assert2.AreEqual(1, q.Take(null)); Assert.AreEqual(0, q.GlobalQueue.OccupiedNodesCount); Assert.AreEqual(100, q.GlobalQueue.FreeNodesCount); }
public void TestUnlockWhenItemReceive() { int processed = 0; ManualResetEventSlim waiter = new ManualResetEventSlim(false); using (DelegateQueueAsyncProcessor <int> proc = new DelegateQueueAsyncProcessor <int>(Environment.ProcessorCount, 1000, "name", (elem, token) => { Interlocked.Increment(ref processed); waiter.Wait(token); })) { proc.Start(); for (int i = 0; i < proc.ThreadCount; i++) { proc.Add(i); } //if (!SpinWait.SpinUntil(() => Volatile.Read(ref processed) == proc.ThreadCount, 5000)) //{ // System.Diagnostics.Debugger.Launch(); // throw new Exception("Proc: " + Volatile.Read(ref processed).ToString() + ", threads: " + proc.ActiveThreadCount.ToString() + // ", tasks: " + proc.ElementCount.ToString()); //} TimingAssert.IsTrue(15000, () => Volatile.Read(ref processed) == proc.ThreadCount, "FAILED: wait for all thread start"); waiter.Set(); proc.Stop(true, true, true); Assert.IsTrue(proc.State == QueueAsyncProcessorState.Stopped, "proc.State == QueueAsyncProcessorState.Stopped"); } }
public void TestTakeBlocks() { PrioritizedElementsContainer <int> testInst = new PrioritizedElementsContainer <int>(new PoolElementComparer()); CancellationTokenSource tokSrc = new CancellationTokenSource(); bool wasCancelled = false; bool wasEntered = false; bool wasExited = false; Task.Run(() => { try { Volatile.Write(ref wasEntered, true); PoolElementWrapper <int> item; testInst.TryTake(out item, -1, tokSrc.Token); } catch (OperationCanceledException) { Volatile.Write(ref wasCancelled, true); } Volatile.Write(ref wasExited, true); }); TimingAssert.IsTrue(10000, () => Volatile.Read(ref wasEntered)); Thread.Sleep(100); Assert.IsFalse(Volatile.Read(ref wasExited)); tokSrc.Cancel(); TimingAssert.IsTrue(10000, () => Volatile.Read(ref wasExited)); Assert.IsTrue(Volatile.Read(ref wasCancelled)); }
public void SegmentBackgroundCompactionTest() { var segmentFactory = new MemorySegmentFactory <int>(10); using (var queue = new DiskQueue <int>("dummy", segmentFactory, -1, true, 100)) { Assert.AreEqual(1, queue.SegmentCount); for (int i = 0; i < segmentFactory.Capacity; i++) { queue.Add(i); } Assert.AreEqual(1, queue.SegmentCount); queue.Add(-1); Assert.AreEqual(2, queue.SegmentCount); Assert.AreEqual(2, segmentFactory.AllocatedSegments.Count); for (int i = 0; i < segmentFactory.Capacity; i++) { queue.Take(); } Assert.IsTrue(segmentFactory.AllocatedSegments[0].IsCompleted); TimingAssert.AreEqual(10000, 1, () => { Interlocked.MemoryBarrier(); return(queue.SegmentCount); }); Assert.AreEqual(2, segmentFactory.AllocatedSegments.Count); } }
// ========================= private void TimeoutWorksTest(DiskQueue <int> queue) { Barrier bar = new Barrier(2); AtomicNullableBool takeResult = new AtomicNullableBool(); AtomicNullableBool peekResult = new AtomicNullableBool(); AtomicNullableBool addResult = new AtomicNullableBool(); Task task = Task.Run(() => { bar.SignalAndWait(); int item = 0; takeResult.Value = queue.TryTake(out item, 100); peekResult.Value = queue.TryPeek(out item, 100); while (queue.TryAdd(-1)) { ; } addResult.Value = queue.TryAdd(100, 100); }); bar.SignalAndWait(); TimingAssert.AreEqual(10000, false, () => takeResult.Value, "take"); TimingAssert.AreEqual(10000, false, () => peekResult.Value, "peek"); TimingAssert.AreEqual(10000, false, () => addResult.Value, "Add"); task.Wait(); }
// ========================= private void PeekWakesUpTest(DiskQueue <int> queue) { Barrier bar = new Barrier(3); AtomicNullableBool peekResult = new AtomicNullableBool(); AtomicNullableBool peekResult2 = new AtomicNullableBool(); Task task = Task.Run(() => { bar.SignalAndWait(); int item = 0; peekResult.Value = queue.TryPeek(out item, 60000); Assert.AreEqual(100, item); }); Task task2 = Task.Run(() => { bar.SignalAndWait(); int item = 0; peekResult2.Value = queue.TryPeek(out item, 60000); Assert.AreEqual(100, item); }); bar.SignalAndWait(); Thread.Sleep(10); Assert.IsFalse(peekResult.HasValue); Assert.IsFalse(peekResult2.HasValue); queue.Add(100); TimingAssert.AreEqual(10000, true, () => peekResult.Value); TimingAssert.AreEqual(10000, true, () => peekResult2.Value); Task.WaitAll(task, task2); }
public void TestSingleThreadWakeUpOnSignal() { using (var testInst = new MonitorObject()) { int exitCount = 0; int state = 0; List <Task> tasks = new List <Task>(); for (int i = 0; i < 6; i++) { var task = Task.Run(() => { using (var waiter = testInst.Enter()) { waiter.Wait(_ => { return(Volatile.Read(ref state) > 0); }, (object)null); Interlocked.Increment(ref exitCount); } }); tasks.Add(task); } TimingAssert.AreEqual(10000, 6, () => testInst.WaiterCount); Interlocked.Increment(ref state); for (int i = 0; i < 6; i++) { testInst.Pulse(); TimingAssert.AreEqual(10000, 5 - i, () => testInst.WaiterCount); Thread.Sleep(50); TimingAssert.AreEqual(10000, i + 1, () => Volatile.Read(ref exitCount)); } Task.WaitAll(tasks.ToArray()); } }
public void TestSendOrPostCallbackSyncThreadPoolWorkItem() { int value = 0; System.Threading.SendOrPostCallback act = (s) => { Interlocked.Increment(ref value); }; var item = new SendOrPostCallbackSyncThreadPoolWorkItem(act, null); bool waitFinished = false; int startedFlag = 0; Task.Run(() => { Interlocked.Exchange(ref startedFlag, 1); item.Wait(); Volatile.Write(ref waitFinished, true); }); TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1); Thread.Sleep(100); Assert.AreEqual(0, value); Assert.AreEqual(false, waitFinished); item.Run(false, false); TimingAssert.AreEqual(5000, 1, () => Volatile.Read(ref value)); TimingAssert.AreEqual(5000, true, () => Volatile.Read(ref waitFinished)); }
public void TestNotificationWithPredicateRef() { using (var testInst = new MonitorObject()) { int result = 0; int state = 0; var task = Task.Run(() => { using (var waiter = testInst.Enter(60000)) { if (waiter.Wait((ref int s) => Volatile.Read(ref s) > 0, ref state)) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount); Assert.AreEqual(0, Volatile.Read(ref result)); testInst.Pulse(); Thread.Sleep(100); Assert.AreEqual(0, Volatile.Read(ref result)); Interlocked.Increment(ref state); testInst.Pulse(); TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result)); task.Wait(); } }
// ========================= private void PeekWakesUpTest(LevelingQueue <int> queue) { Barrier bar = new Barrier(3); int peekResult = 0; int peekResult2 = 0; Task task = Task.Run(() => { bar.SignalAndWait(); int item = 0; AtomicSet(ref peekResult, queue.TryPeek(out item, 60000)); Assert.AreEqual(100, item); }); Task task2 = Task.Run(() => { bar.SignalAndWait(); int item = 0; AtomicSet(ref peekResult2, queue.TryPeek(out item, 60000)); Assert.AreEqual(100, item); }); bar.SignalAndWait(); Thread.Sleep(10); Assert.AreEqual(0, Volatile.Read(ref peekResult)); queue.Add(100); TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref peekResult)); TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref peekResult2)); Task.WaitAll(task, task2); }
public void TestCancellationWork() { PartialThreadBlocker inst = new PartialThreadBlocker(4); CancellationTokenSource tokSrc = new CancellationTokenSource(); int exitedCount = 0; Task.Run(() => { try { inst.Wait(tokSrc.Token); } catch (OperationCanceledException) { } Interlocked.Increment(ref exitedCount); }); TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount); TimingAssert.AreEqual(5000, 1, () => inst.RealWaiterCount); tokSrc.Cancel(); TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount); TimingAssert.AreEqual(5000, 0, () => inst.RealWaiterCount); TimingAssert.AreEqual(5000, 1, () => Volatile.Read(ref exitedCount)); }
// ========================= private void TimeoutWorksTest(LevelingQueue <int> queue) { Barrier bar = new Barrier(2); int takeResult = 0; int peekResult = 0; int addResult = 0; Task task = Task.Run(() => { bar.SignalAndWait(); int item = 0; AtomicSet(ref takeResult, queue.TryTake(out item, 100)); AtomicSet(ref peekResult, queue.TryPeek(out item, 100)); while (queue.TryAdd(-1)) { ; } if (queue.IsBackgroundTransferingEnabled) { queue.AddForcedToHighLevelQueue(-1); queue.AddForced(-1); // To prevent background transferer from freeing the space } AtomicSet(ref addResult, queue.TryAdd(100, 100)); }); bar.SignalAndWait(); TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref takeResult), "take"); TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref peekResult), "peek"); TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref addResult), "Add"); task.Wait(); }
public void TestTimeoutWorks() { object syncObj = new object(); using (var testInst = new ConditionVariable(syncObj)) { int result = 0; var task = Task.Run(() => { using (var waiter = testInst.Enter(500)) { if (waiter.Wait(_ => false, (object)null)) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); lock (syncObj) { testInst.Pulse(); } TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref result)); } }
public void BacgroundTransferingWorksNonOrdBcg() { MemoryQueue <int> high = new MemoryQueue <int>(10); MemoryQueue <int> low = new MemoryQueue <int>(10); high.Add(1); while (low.TryAdd(low.Count + 2)) { ; } using (var inst = new LevelingQueue <int>(high, low, LevelingQueueAddingMode.PreferLiveData, true)) { Assert.AreEqual(1, inst.Take()); TimingAssert.AreEqual(10000, 10, () => high.Count); Assert.AreEqual(0, low.Count); int item = 0; int expected = 2; while (inst.TryTake(out item)) { Assert.AreEqual(expected++, item); } } }
public void TestAllThreadWakeUpOnSignalAll() { object syncObj = new object(); using (var testInst = new ConditionVariable(syncObj)) { int exitCount = 0; int state = 0; List <Task> tasks = new List <Task>(); for (int i = 0; i < 6; i++) { var task = Task.Run(() => { using (var waiter = testInst.Enter()) { waiter.Wait(_ => { return(Volatile.Read(ref state) > 0); }, (object)null); Interlocked.Increment(ref exitCount); } }); tasks.Add(task); } TimingAssert.AreEqual(10000, 6, () => testInst.WaiterCount); Interlocked.Increment(ref state); lock (syncObj) { testInst.PulseAll(); } TimingAssert.AreEqual(10000, 0, () => testInst.WaiterCount); TimingAssert.AreEqual(10000, 6, () => Volatile.Read(ref exitCount)); } }
public void TestCustomTimeoutWorks() { using (var testInst = new MonitorObject()) { int result = 0; var task = Task.Run(() => { using (var waiter = testInst.Enter(60000)) { if (waiter.Wait(100)) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount); TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref result)); task.Wait(); } }
public void TestPredicateCalledOnTimeout() { object syncObj = new object(); using (var testInst = new ConditionVariable(syncObj)) { int result = 0; int state = 0; int called = 0; var task = Task.Run(() => { using (var waiter = testInst.Enter(100)) { if (waiter.Wait((s) => { Interlocked.Increment(ref called); return(Volatile.Read(ref state) > 0); }, new object())) { Interlocked.Exchange(ref result, 1); } else { Interlocked.Exchange(ref result, 2); } } }); TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount); TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref result)); TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref called)); } }
public void TestIsTimeoutedWorks() { using (var testInst = new MonitorObject()) { int result = 0; int cycleCount = 0; var task = Task.Run(() => { using (var waiter = testInst.Enter(200)) { while (!waiter.IsTimeouted) { waiter.Wait(10); Interlocked.Increment(ref cycleCount); } Interlocked.Exchange(ref result, 1); } }); TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount); TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result)); Assert.IsTrue(Volatile.Read(ref cycleCount) > 0); task.Wait(); } }
public void CaptureContextNoSyncContextTest() { var originalContext = SynchronizationContext.Current; var syncContext = new CustomSyncContext(); try { SynchronizationContext.SetSynchronizationContext(syncContext); var eContext = ExecutionContextHelper.CaptureContextNoSyncContextIfPossible(); Assert.IsNotNull(eContext); AtomicBool isDefaulContext = new AtomicBool(false); var task = Task.Run(() => { SynchronizationContext.SetSynchronizationContext(null); ExecutionContextHelper.RunInContext(eContext, (st) => { isDefaulContext.Value = SynchronizationContext.Current == null; }, null, true); }); task.Wait(); TimingAssert.IsTrue(10000, isDefaulContext, "Default context expected"); } finally { SynchronizationContext.SetSynchronizationContext(originalContext); } }
public void TestCancellationWorksInWaitNoParam() { using (var testInst = new MonitorObject()) { int result = 0; CancellationTokenSource tokenSrc = new CancellationTokenSource(); var task = Task.Run(() => { try { using (var waiter = testInst.Enter(60000, tokenSrc.Token)) { while (!waiter.Wait()) { } Interlocked.Exchange(ref result, 1); } } catch (OperationCanceledException) { Interlocked.Exchange(ref result, 3); } }); testInst.Pulse(); Thread.Sleep(100); Assert.AreEqual(0, Volatile.Read(ref result)); tokenSrc.Cancel(); TimingAssert.AreEqual(10000, 3, () => Volatile.Read(ref result)); } }
public void TestCancellation() { SemaphoreLight inst = new SemaphoreLight(0); CancellationTokenSource tokenSrc = new CancellationTokenSource(); bool cancelled = false; Task.Run(() => { try { inst.Wait(tokenSrc.Token); } catch (OperationCanceledException) { Volatile.Write(ref cancelled, true); Thread.MemoryBarrier(); } }); TimingAssert.IsTrue(5000, () => inst.WaiterCount > 0); Assert.IsFalse(Volatile.Read(ref cancelled)); tokenSrc.Cancel(); TimingAssert.IsTrue(5000, () => Volatile.Read(ref cancelled)); Assert.AreEqual(0, inst.CurrentCount); Assert.AreEqual(0, inst.WaiterCount); }
// ========================= private void AddWakesUpTest(DiskQueue <int> queue, int segmentCapacity) { while (queue.TryAdd(100)) { ; // Fill queue } queue.AddForced(200); Barrier bar = new Barrier(2); AtomicNullableBool addResult = new AtomicNullableBool(); Task task = Task.Run(() => { bar.SignalAndWait(); addResult.Value = queue.TryAdd(-100, 60000); }); bar.SignalAndWait(); Thread.Sleep(10); Assert.IsFalse(addResult.HasValue); queue.Take(); Thread.Sleep(10); Assert.IsFalse(addResult.HasValue); for (int i = 0; i < segmentCapacity; i++) { int tmp = 0; Assert.IsTrue(queue.TryTake(out tmp)); } TimingAssert.AreEqual(10000, true, () => addResult.Value); task.Wait(); }