// ========================= 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 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(); }
// ============================== private void TestSimpleAddTakePeek(DiskQueue <int> queue) { Assert.AreEqual(0, queue.Count); Assert.IsTrue(queue.IsEmpty); Assert.IsTrue(queue.TryAdd(1)); Assert.AreEqual(1, queue.Count); Assert.IsFalse(queue.IsEmpty); int item = 0; Assert.IsTrue(queue.TryPeek(out item)); Assert.AreEqual(1, item); Assert.IsFalse(queue.IsEmpty); item = 0; Assert.IsTrue(queue.TryTake(out item)); Assert.AreEqual(1, item); Assert.AreEqual(0, queue.Count); Assert.IsTrue(queue.IsEmpty); for (int i = 1; i < 1000; i++) { if (i % 2 == 0) { queue.Add(i); } else { queue.AddForced(i); } Assert.AreEqual(i, queue.Count); } int itemNum = 0; while (queue.TryTake(out item)) { itemNum++; Assert.AreEqual(itemNum, item); } Assert.AreEqual(999, itemNum); Assert.AreEqual(0, queue.Count); Assert.IsTrue(queue.IsEmpty); }
// ========================= private void CancellationWorksTest(DiskQueue <int> queue) { Barrier bar = new Barrier(2); CancellationTokenSource takeSource = new CancellationTokenSource(); AtomicInt takeResult = new AtomicInt(); CancellationTokenSource peekSource = new CancellationTokenSource(); AtomicInt peekResult = new AtomicInt(); CancellationTokenSource addSource = new CancellationTokenSource(); AtomicInt addResult = new AtomicInt(); Task task = Task.Run(() => { bar.SignalAndWait(); int item = 0; try { takeResult.Value = queue.TryTake(out item, 60000, takeSource.Token) ? 1 : -1; } catch (OperationCanceledException) { takeResult.Value = 3; } try { peekResult.Value = queue.TryPeek(out item, 60000, peekSource.Token) ? 1 : -1; } catch (OperationCanceledException) { peekResult.Value = 3; } while (queue.TryAdd(-1)) { ; } try { addResult.Value = queue.TryAdd(100, 60000, addSource.Token) ? 1 : -1; } catch (OperationCanceledException) { addResult.Value = 3; } }); bar.SignalAndWait(); Thread.Sleep(10); Assert.AreEqual(0, takeResult); takeSource.Cancel(); TimingAssert.AreEqual(10000, 3, () => takeResult); Thread.Sleep(10); Assert.AreEqual(0, peekResult); peekSource.Cancel(); TimingAssert.AreEqual(10000, 3, () => peekResult); Thread.Sleep(10); Assert.AreEqual(0, addResult); addSource.Cancel(); TimingAssert.AreEqual(10000, 3, () => addResult); task.Wait(); }
// ====================== private void ValidateCountTest(DiskQueue <int> queue, CommonSegmentFactory <int> factory, int elemCount) { Barrier bar = new Barrier(2); CancellationTokenSource cancelled = new CancellationTokenSource(); List <int> takenElems = new List <int>(elemCount + 1); AtomicBool needSync = new AtomicBool(); Action addAction = () => { int curElem = 0; Random rnd = new Random(Environment.TickCount + Thread.CurrentThread.ManagedThreadId); bar.SignalAndWait(); while (curElem < elemCount) { bool itemAdded = true; if (rnd.Next(100) == 0) { queue.AddForced(curElem); } else if (needSync.Value) { itemAdded = queue.TryAdd(curElem); } else { queue.Add(curElem); } if (rnd.Next(100) == 0) { Thread.Yield(); } SpinWaitHelper.SpinWait(rnd.Next(12)); if (itemAdded) { curElem++; } Assert.IsTrue(itemAdded || needSync.Value); if (curElem % 1000 == 0) { needSync.Value = true; } if (needSync.Value && bar.ParticipantsRemaining == 1) { Assert.AreEqual(factory.SumCountFromAllocated(), queue.Count); needSync.Value = false; bar.SignalAndWait(); } } cancelled.Cancel(); }; Action takeAction = () => { Random rnd = new Random(Environment.TickCount + Thread.CurrentThread.ManagedThreadId); bar.SignalAndWait(); try { while (!cancelled.IsCancellationRequested) { takenElems.Add(queue.Take(cancelled.Token)); if (rnd.Next(100) == 0) { Thread.Yield(); } SpinWaitHelper.SpinWait(rnd.Next(12)); if (needSync.Value) { bar.SignalAndWait(cancelled.Token); } } } catch (OperationCanceledException) { } int item = 0; while (queue.TryTake(out item)) { takenElems.Add(item); } }; var sw = System.Diagnostics.Stopwatch.StartNew(); Task addTask = Task.Factory.StartNew(addAction, TaskCreationOptions.LongRunning); Task takeTask = Task.Factory.StartNew(takeAction, TaskCreationOptions.LongRunning); Task.WaitAll(addTask, takeTask); Assert.AreEqual(elemCount, takenElems.Count); for (int i = 0; i < takenElems.Count; i++) { if (i != takenElems[i]) { Assert.AreEqual(i, takenElems[i], $"i != takenElems[i], nextItem = {takenElems[i + 1]}"); } } }