Exemple #1
0
        // =========================

        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();
        }
Exemple #2
0
        // ===============

        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]);
            }
        }
Exemple #3
0
        // ==========================

        private void RunComplexTest(LevelingQueue <int> q, int elemCount, int thCount)
        {
            int atomicRandom = 0;

            int trackElemCount = elemCount;
            int addFinished    = 0;

            Thread[] threadsTake = new Thread[thCount];
            Thread[] threadsAdd  = new Thread[thCount];

            CancellationTokenSource tokSrc = new CancellationTokenSource();

            List <int> global = new List <int>(elemCount);

            Action addAction = () =>
            {
                Random rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * thCount * 2);

                while (true)
                {
                    int item = Interlocked.Decrement(ref trackElemCount);
                    if (item < 0)
                    {
                        break;
                    }

                    if (rnd.Next(100) == 0)
                    {
                        q.AddForced(item);
                    }
                    else
                    {
                        q.Add(item);
                    }


                    int sleepTime = rnd.Next(12);

                    int tmpItem = 0;
                    if (q.TryPeek(out tmpItem) && tmpItem == item)
                    {
                        sleepTime += 12;
                    }

                    if (sleepTime > 0)
                    {
                        SpinWaitHelper.SpinWait(sleepTime);
                    }
                }

                Interlocked.Increment(ref addFinished);
            };


            Action takeAction = () =>
            {
                Random rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * thCount * 2);

                List <int> data = new List <int>();

                try
                {
                    while (Volatile.Read(ref addFinished) < thCount)
                    {
                        int tmp = 0;
                        if (q.TryTake(out tmp, -1, tokSrc.Token))
                        {
                            data.Add((int)tmp);
                        }

                        int sleepTime = rnd.Next(12);
                        if (sleepTime > 0)
                        {
                            SpinWaitHelper.SpinWait(sleepTime);
                        }
                    }
                }
                catch (OperationCanceledException) { }

                int tmp2;
                while (q.TryTake(out tmp2))
                {
                    data.Add((int)tmp2);
                }

                lock (global)
                    global.AddRange(data);
            };


            for (int i = 0; i < threadsTake.Length; i++)
            {
                threadsTake[i] = new Thread(new ThreadStart(takeAction));
            }
            for (int i = 0; i < threadsAdd.Length; i++)
            {
                threadsAdd[i] = new Thread(new ThreadStart(addAction));
            }


            for (int i = 0; i < threadsTake.Length; i++)
            {
                threadsTake[i].Start();
            }
            for (int i = 0; i < threadsAdd.Length; i++)
            {
                threadsAdd[i].Start();
            }


            for (int i = 0; i < threadsAdd.Length; i++)
            {
                threadsAdd[i].Join();
            }
            tokSrc.Cancel();
            for (int i = 0; i < threadsTake.Length; i++)
            {
                threadsTake[i].Join();
            }


            Assert.AreEqual(elemCount, global.Count);
            global.Sort();

            for (int i = 0; i < elemCount; i++)
            {
                Assert.AreEqual(i, global[i]);
            }
        }
Exemple #4
0
        // ==========================


        private void PreserveOrderTest(LevelingQueue <int> queue, int elemCount)
        {
            Barrier bar = new Barrier(2);
            CancellationTokenSource cancelled = new CancellationTokenSource();
            List <int> takenElems             = new List <int>(elemCount + 1);

            Action addAction = () =>
            {
                int    curElem = 0;
                Random rnd     = new Random(Environment.TickCount + Thread.CurrentThread.ManagedThreadId);

                bar.SignalAndWait();
                while (curElem < elemCount)
                {
                    if (rnd.Next(100) == 0)
                    {
                        queue.AddForced(curElem);
                    }
                    else
                    {
                        queue.Add(curElem);
                    }

                    if (rnd.Next(100) == 0)
                    {
                        Thread.Yield();
                    }
                    SpinWaitHelper.SpinWait(rnd.Next(12));

                    curElem++;
                }

                cancelled.Cancel();
            };

            StringBuilder badInfo = new StringBuilder();

            Action takeAction = () =>
            {
                Random rnd = new Random(Environment.TickCount + Thread.CurrentThread.ManagedThreadId);

                bar.SignalAndWait();
                try
                {
                    while (!cancelled.IsCancellationRequested)
                    {
                        takenElems.Add(queue.Take(cancelled.Token));
                        //if (takenElems[takenElems.Count - 1] != takenElems.Count - 1)
                        //    badInfo.Append("Is taken from high = " + queue.LastTakeTop.ToString());

                        if (rnd.Next(100) == 0)
                        {
                            Thread.Yield();
                        }
                        SpinWaitHelper.SpinWait(rnd.Next(12));
                    }
                }
                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]}, badInfo = '{badInfo}'");
                }
            }
        }
Exemple #5
0
        // =========================

        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();
        }