Пример #1
0
        // =========================

        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();
        }
Пример #2
0
        // =========================

        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();
        }
Пример #3
0
        // ==============================


        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);
        }
Пример #4
0
        // =========================

        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();
        }
Пример #5
0
        // ======================

        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]}");
                }
            }
        }