// ========================= 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(); }
// ========================= private void AddWakesUpTest(LevelingQueue <int> queue) { while (queue.TryAdd(100)) { ; // Fill queue } if (queue.IsBackgroundTransferingEnabled) { SpinWait sw = new SpinWait(); while (queue.IsBackgroundInWork && sw.Count < 100) { sw.SpinOnce(); } for (int i = 0; i < 100; i++) { queue.TryAdd(100); SpinWaitHelper.SpinWait(12); } } Barrier bar = new Barrier(2); int addResult = 0; Task task = Task.Run(() => { bar.SignalAndWait(); AtomicSet(ref addResult, queue.TryAdd(-100, 60000)); }); bar.SignalAndWait(); Thread.Sleep(10); Assert.AreEqual(0, Volatile.Read(ref addResult)); queue.Take(); if (queue.AddingMode == LevelingQueueAddingMode.PreserveOrder && !queue.IsBackgroundTransferingEnabled) { int item; while (queue.TryTake(out item)) { ; } } TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref addResult)); task.Wait(); }
// =============== private void AddTakeTest(LevelingQueue <int> queue, int bound) { Assert.AreEqual(bound, queue.BoundedCapacity); Assert.AreEqual(0, queue.Count); Assert.IsTrue(queue.IsEmpty); queue.Add(-1); Assert.AreEqual(1, queue.Count); Assert.IsFalse(queue.IsEmpty); int peekVal = queue.Peek(); Assert.AreEqual(-1, peekVal); Assert.AreEqual(1, queue.Count); Assert.IsFalse(queue.IsEmpty); int takeVal = queue.Take(); Assert.AreEqual(-1, takeVal); Assert.AreEqual(0, queue.Count); Assert.IsTrue(queue.IsEmpty); int itemCount = 1; while (queue.TryAdd(itemCount)) { itemCount++; } itemCount--; Assert.AreEqual(itemCount, queue.Count); Assert.IsFalse(queue.IsEmpty); queue.AddForced(++itemCount); Assert.AreEqual(itemCount, queue.Count); List <int> takenItems = new List <int>(); while (queue.TryTake(out takeVal)) { takenItems.Add(takeVal); Assert.AreEqual(itemCount - takenItems.Count, queue.Count); } Assert.AreEqual(itemCount, takenItems.Count, "count diff"); Assert.IsTrue(queue.IsEmpty); if (queue.AddingMode != LevelingQueueAddingMode.PreserveOrder) { takenItems.Sort(); } for (int i = 0; i < takenItems.Count; i++) { Assert.AreEqual(i + 1, takenItems[i]); } }
// ========================= private void CancellationWorksTest(LevelingQueue <int> queue) { Barrier bar = new Barrier(2); CancellationTokenSource takeSource = new CancellationTokenSource(); int takeResult = 0; CancellationTokenSource peekSource = new CancellationTokenSource(); int peekResult = 0; CancellationTokenSource addSource = new CancellationTokenSource(); int addResult = 0; Task task = Task.Run(() => { bar.SignalAndWait(); int item = 0; try { AtomicSet(ref takeResult, queue.TryTake(out item, 60000, takeSource.Token)); } catch (OperationCanceledException) { Interlocked.Exchange(ref takeResult, 3); } try { AtomicSet(ref peekResult, queue.TryPeek(out item, 60000, peekSource.Token)); } catch (OperationCanceledException) { Interlocked.Exchange(ref peekResult, 3); } while (queue.TryAdd(-1)) { ; } if (queue.IsBackgroundTransferingEnabled) { queue.AddForced(-1); } try { AtomicSet(ref addResult, queue.TryAdd(100, 60000, addSource.Token)); } catch (OperationCanceledException) { Interlocked.Exchange(ref addResult, 3); } }); bar.SignalAndWait(); Thread.Sleep(10); Assert.AreEqual(0, takeResult); takeSource.Cancel(); TimingAssert.AreEqual(10000, 3, () => Volatile.Read(ref takeResult)); Thread.Sleep(10); Assert.AreEqual(0, peekResult); peekSource.Cancel(); TimingAssert.AreEqual(10000, 3, () => Volatile.Read(ref peekResult)); Thread.Sleep(10); Assert.AreEqual(0, addResult); addSource.Cancel(); TimingAssert.AreEqual(10000, 3, () => Volatile.Read(ref addResult)); task.Wait(); }