Beispiel #1
0
        public void TestIsEmpty()
        {
            ThreadPoolConcurrentQueue q = new ThreadPoolConcurrentQueue();

            Assert.IsTrue(q.IsEmpty);

            for (int i = 0; i < 10000; i++)
            {
                q.Add(new TestThreadPoolItem(i));
                Assert.IsFalse(q.IsEmpty);
            }

            for (int i = 0; i < 10000; i++)
            {
                Assert.IsFalse(q.IsEmpty);
                ThreadPoolWorkItem res = null;
                Assert.IsTrue(q.TryTake(out res));
            }

            Assert.IsTrue(q.IsEmpty);


            ThreadPoolWorkItem tmp = null;

            Assert.IsFalse(q.TryTake(out tmp));
            Assert.IsNull(tmp);
            Assert.IsTrue(q.IsEmpty);
        }
Beispiel #2
0
        public void ConcurrentTest()
        {
            ThreadPoolConcurrentQueue q = new ThreadPoolConcurrentQueue();

            for (int i = 0; i < 5; i++)
            {
                RunThreadPoolConcurrentQueueTest(q, 300000, Math.Max(Environment.ProcessorCount / 2, 1));
            }
        }
Beispiel #3
0
        public void TestSingleAddTake()
        {
            ThreadPoolConcurrentQueue q = new ThreadPoolConcurrentQueue();

            q.Add(new TestThreadPoolItem(10));
            ThreadPoolWorkItem res = null;

            Assert.IsTrue(q.TryTake(out res));
            Assert.IsNotNull(res);
            Assert2.AreEqual(10, res);
        }
Beispiel #4
0
        public void TestManyAddTake()
        {
            ThreadPoolConcurrentQueue q = new ThreadPoolConcurrentQueue();

            for (int i = 0; i < 100000; i++)
            {
                q.Add(new TestThreadPoolItem(i));
            }

            for (int i = 0; i < 100000; i++)
            {
                ThreadPoolWorkItem res = null;
                Assert.IsTrue(q.TryTake(out res));
                Assert.IsNotNull(res);
                Assert2.AreEqual(i, res);
            }
        }
Beispiel #5
0
        private void RunThreadPoolConcurrentQueueTest(ThreadPoolConcurrentQueue q, int elemCount, int thCount)
        {
            int atomicRandom = 0;

            int trackElemCount = elemCount;
            int addFinished    = 0;

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

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

                    q.Add(new TestThreadPoolItem(item));

                    int sleepTime = rnd.Next(1000);
                    if (sleepTime > 0)
                    {
                        Thread.SpinWait(sleepTime);
                    }
                }

                Interlocked.Increment(ref addFinished);
            };

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

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

                while (Volatile.Read(ref addFinished) < thCount)
                {
                    ThreadPoolWorkItem tmp;
                    if (q.TryTake(out tmp))
                    {
                        data.Add((TestThreadPoolItem)tmp);
                    }

                    int sleepTime = rnd.Next(1000);
                    if (sleepTime > 0)
                    {
                        Thread.SpinWait(sleepTime);
                    }
                }

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

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


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

            for (int i = 0; i < threadsRemove.Length; i++)
            {
                threadsRemove[i] = new Thread(new ThreadStart(removeAction));
            }


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


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


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

            for (int i = 0; i < elemCount; i++)
            {
                Assert.AreEqual(i, global[i]);
            }
        }
Beispiel #6
0
        private static bool TestThreadPoolConcurrentQueue(int elemCount, int thCount, bool useRandom)
        {
            ThreadPoolConcurrentQueue q = new ThreadPoolConcurrentQueue();

            int atomicRandom = 0;

            int trackElemCount = elemCount;
            int addFinished    = 0;

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

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

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

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

                    q.Add(new TestThreadPoolItem(item));

                    int sleepTime = 0;
                    if (rnd != null)
                    {
                        sleepTime = rnd.Next(elemCount / 10000) - elemCount / 10000 + 2;
                    }
                    if (sleepTime > 0)
                    {
                        Thread.Sleep(sleepTime);
                    }
                }

                Interlocked.Increment(ref addFinished);
            };

            Action removeAction = () =>
            {
                Random rnd = null;
                if (useRandom)
                {
                    rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * thCount * 2);
                }

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

                while (Volatile.Read(ref addFinished) < thCount)
                {
                    ThreadPoolWorkItem tmp;
                    if (q.TryTake(out tmp))
                    {
                        data.Add((TestThreadPoolItem)tmp);
                    }

                    int sleepTime = 0;
                    if (rnd != null)
                    {
                        sleepTime = rnd.Next(elemCount / 10000) - elemCount / 10000 + 2;
                    }
                    if (sleepTime > 0)
                    {
                        Thread.Sleep(sleepTime);
                    }
                }

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

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


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

            for (int i = 0; i < threadsRemove.Length; i++)
            {
                threadsRemove[i] = new Thread(new ThreadStart(removeAction));
            }

            Stopwatch sw = Stopwatch.StartNew();

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


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


            sw.Stop();

            bool result = true;

            global.Sort();
            if (global.Count != elemCount)
            {
                result = false;
                Console.WriteLine("Incorrect element count");
            }

            HashSet <int> set = new HashSet <int>(global);

            if (set.Count != global.Count)
            {
                result = false;
                Console.WriteLine("Incorrect distinct element count");
            }

            for (int i = 0; i < Math.Min(elemCount, global.Count); i++)
            {
                if (global[i] != i)
                {
                    result = false;
                    Console.WriteLine("Incorrect data");
                    break;
                }
            }


            Console.WriteLine(q.GetType().Name + ". Element count = " + elemCount.ToString() + ", Time = " + sw.ElapsedMilliseconds.ToString() + "ms");
            Console.WriteLine();
            return(result);
        }