Esempio n. 1
0
        public void TestStealingWakeUp()
        {
            ThreadPoolLocalQueue[] locQ = new ThreadPoolLocalQueue[]
            {
                new ThreadPoolLocalQueue(),
                new ThreadPoolLocalQueue(),
                new ThreadPoolLocalQueue(),
                new ThreadPoolLocalQueue(),
            };

            ThreadPoolQueueController q = new ThreadPoolQueueController(100, 50);

            for (int i = 0; i < locQ.Length; i++)
            {
                q.AddLocalQueue(locQ[i]);
            }

            bool       takeCompleted = false;
            List <int> takenItems    = new List <int>();

            Task.Run(() =>
            {
                for (int i = 0; i < 100; i++)
                {
                    takenItems.Add((TestThreadPoolItem)q.Take(locQ[0]));
                }
                takeCompleted = true;
            });

            Thread.Sleep(1000);
            Assert.IsFalse(takeCompleted);


            for (int i = 0; i < 100; i++)
            {
                locQ[1 + (i % (locQ.Length - 1))].TryAddLocal(new TestThreadPoolItem(i));
                Thread.Sleep(100);
            }

            Thread.Sleep(1000);
            Assert.IsTrue(takeCompleted);

            Assert.AreEqual(100, takenItems.Count);
            takenItems.Sort();

            for (int i = 0; i < 100; i++)
            {
                Assert.AreEqual(i, takenItems[i]);
            }
        }
Esempio n. 2
0
        public void TestItemStealingWork()
        {
            ThreadPoolLocalQueue[] locQ = new ThreadPoolLocalQueue[]
            {
                new ThreadPoolLocalQueue(),
                new ThreadPoolLocalQueue(),
                new ThreadPoolLocalQueue(),
                new ThreadPoolLocalQueue(),
            };

            ThreadPoolQueueController q = new ThreadPoolQueueController(100, 1000);

            for (int i = 0; i < locQ.Length; i++)
            {
                q.AddLocalQueue(locQ[i]);
            }

            locQ[0].TryAddLocal(new TestThreadPoolItem(0));
            locQ[1].TryAddLocal(new TestThreadPoolItem(1));
            locQ[2].TryAddLocal(new TestThreadPoolItem(2));
            locQ[3].TryAddLocal(new TestThreadPoolItem(3));

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

            for (int i = 0; i < 4; i++)
            {
                ThreadPoolWorkItem item = null;
                Assert.IsTrue(q.TryTake(locQ[0], out item, 0, CancellationToken.None, true));
                extractedItems.Add((TestThreadPoolItem)item);
            }

            ThreadPoolWorkItem tmp = null;

            Assert.IsFalse(q.TryTake(locQ[0], out tmp, 0, CancellationToken.None, true));

            extractedItems.Sort();
            Assert.AreEqual(4, extractedItems.Count);
            for (int i = 0; i < extractedItems.Count; i++)
            {
                Assert.AreEqual(i, extractedItems[i]);
            }
        }
Esempio n. 3
0
        public void TestLocalThreadQueueUsage()
        {
            ThreadPoolLocalQueue      local = new ThreadPoolLocalQueue();
            ThreadPoolQueueController q     = new ThreadPoolQueueController(100, 1000);

            q.AddLocalQueue(local);

            q.Add(new TestThreadPoolItem(1), local);

            ThreadPoolWorkItem item = null;

            Assert.IsTrue(local.TryTakeLocal(out item));
            Assert2.AreEqual(1, item);

            local.TryAddLocal(new TestThreadPoolItem(1));

            item = null;
            Assert.IsTrue(q.TryTake(local, out item, 0, CancellationToken.None, true));
            Assert2.AreEqual(1, item);
        }
Esempio n. 4
0
        private void RunComplexTest(ThreadPoolQueueController q, int elemCount, int thCount)
        {
            int mainIndex    = -1;
            int atomicRandom = 0;

            int trackElemCount = elemCount;
            int addFinished    = 0;

            ThreadPoolLocalQueue[] locQ = new ThreadPoolLocalQueue[thCount];
            for (int i = 0; i < locQ.Length; i++)
            {
                locQ[i] = new ThreadPoolLocalQueue();
                q.AddLocalQueue(locQ[i]);
            }

            Thread[] threadsMain       = new Thread[thCount];
            Thread[] threadsAdditional = new Thread[thCount];

            CancellationTokenSource tokSrc = new CancellationTokenSource();

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

            Action additionalAction = () =>
            {
                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), null);

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

                    if (rnd.Next(100) == 0)
                    {
                        q.ExtendGlobalQueueCapacity(50);
                    }
                }

                Interlocked.Increment(ref addFinished);
            };


            Action mainAction = () =>
            {
                var localQ = locQ[Interlocked.Increment(ref mainIndex)];

                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)
                    {
                        ThreadPoolWorkItem tmp = null;
                        if (q.TryTake(localQ, out tmp, -1, tokSrc.Token, true))
                        {
                            data.Add((TestThreadPoolItem)tmp);
                        }

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

                        if (rnd.Next(10) == 0)
                        {
                            int item = Interlocked.Decrement(ref trackElemCount);
                            if (item >= 0)
                            {
                                while (!q.TryAdd(new TestThreadPoolItem(item), localQ, false, 0, CancellationToken.None))
                                {
                                    if (q.TryTake(localQ, out tmp, 0, CancellationToken.None, true))
                                    {
                                        data.Add((TestThreadPoolItem)tmp);
                                    }
                                }
                            }
                        }
                    }
                }
                catch (OperationCanceledException) { }

                ThreadPoolWorkItem tmp2;
                while (q.TryTake(localQ, out tmp2, 0, CancellationToken.None, true))
                {
                    data.Add((TestThreadPoolItem)tmp2);
                }

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

            Task.Delay(1000).ContinueWith(t => q.ExtendGlobalQueueCapacity(50));


            for (int i = 0; i < threadsMain.Length; i++)
            {
                threadsMain[i] = new Thread(new ThreadStart(mainAction));
            }
            for (int i = 0; i < threadsAdditional.Length; i++)
            {
                threadsAdditional[i] = new Thread(new ThreadStart(additionalAction));
            }


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


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


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

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

            for (int i = 0; i < locQ.Length; i++)
            {
                q.RemoveLocalQueue(locQ[i]);
            }
        }
        // ==============


        private static bool RunComplexTestOnThreadPoolQueue(int elemCount, int thCount)
        {
            ThreadPoolQueueController q = new ThreadPoolQueueController(1000, 100);
            int mainIndex = -1;

            int trackElemCount = elemCount;
            int addFinished    = 0;

            ThreadPoolLocalQueue[] locQ = new ThreadPoolLocalQueue[thCount];
            for (int i = 0; i < locQ.Length; i++)
            {
                locQ[i] = new ThreadPoolLocalQueue();
                q.AddLocalQueue(locQ[i]);
            }

            Thread[] threadsMain       = new Thread[thCount];
            Thread[] threadsAdditional = new Thread[thCount];

            CancellationTokenSource tokSrc = new CancellationTokenSource();

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

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

                    q.Add(new TestThreadPoolItem(item), null);
                }

                Interlocked.Increment(ref addFinished);
            };


            Action mainAction = () =>
            {
                var localQ = locQ[Interlocked.Increment(ref mainIndex)];

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

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

                        if (((index++) % 10) == 0)
                        {
                            int item = Interlocked.Decrement(ref trackElemCount);
                            if (item >= 0)
                            {
                                while (!q.TryAdd(new TestThreadPoolItem(item), localQ, false, 0, CancellationToken.None))
                                {
                                    if (q.TryTake(localQ, out tmp, 0, CancellationToken.None, true))
                                    {
                                        data.Add((TestThreadPoolItem)tmp);
                                    }
                                }
                            }
                        }
                    }
                }
                catch (OperationCanceledException) { }

                ThreadPoolWorkItem tmp2;
                while (q.TryTake(localQ, out tmp2, 0, CancellationToken.None, true))
                {
                    data.Add((TestThreadPoolItem)tmp2);
                }

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


            for (int i = 0; i < threadsMain.Length; i++)
            {
                threadsMain[i] = new Thread(new ThreadStart(mainAction));
            }
            for (int i = 0; i < threadsAdditional.Length; i++)
            {
                threadsAdditional[i] = new Thread(new ThreadStart(additionalAction));
            }

            Stopwatch sw = Stopwatch.StartNew();

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


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

            sw.Stop();

            bool result = true;

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

            global.Sort();

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

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