コード例 #1
0
        public void TestSingleAddSteal()
        {
            ThreadPoolLocalQueue q = new ThreadPoolLocalQueue();

            Assert.IsTrue(q.TryAddLocal(new TestThreadPoolItem(1)));
            ThreadPoolWorkItem item = null;

            Assert.IsTrue(q.TrySteal(out item));
            Assert.IsNotNull(item);
            Assert2.AreEqual(1, item);
        }
コード例 #2
0
        private void RunLocalThreadQueueAddStealTest(ThreadPoolLocalQueue q, int elemCount, int fillFactor)
        {
            Random rnd      = new Random();
            int    addElem  = 0;
            int    takeElem = 0;

            List <int> takenIndexes = new List <int>(elemCount + 1);

            while (takeElem < elemCount)
            {
                int addCount = rnd.Next(fillFactor);
                for (int i = 0; i < addCount; i++)
                {
                    if (addElem >= elemCount || !q.TryAddLocal(new TestThreadPoolItem(addElem)))
                    {
                        break;
                    }
                    addElem++;
                }

                int removeCount = rnd.Next(fillFactor);
                for (int i = 0; i < removeCount; i++)
                {
                    ThreadPoolWorkItem tmp = null;
                    if (!q.TrySteal(out tmp))
                    {
                        break;
                    }

                    Assert.IsNotNull(tmp);
                    takenIndexes.Add((TestThreadPoolItem)tmp);
                    takeElem++;
                }
            }

            Assert.AreEqual(elemCount, takenIndexes.Count);

            takenIndexes.Sort();

            for (int i = 0; i < elemCount; i++)
            {
                Assert.AreEqual(i, takenIndexes[i]);
            }
        }
コード例 #3
0
        public void TestAddStealUpToTheLimit()
        {
            ThreadPoolLocalQueue q = new ThreadPoolLocalQueue();
            int index = 0;

            while (q.TryAddLocal(new TestThreadPoolItem(index)))
            {
                index++;
                Assert.IsTrue(index < int.MaxValue);
            }

            int index2 = 0;
            ThreadPoolWorkItem item = null;

            while (q.TrySteal(out item))
            {
                Assert.IsNotNull(item);
                Assert.IsTrue((TestThreadPoolItem)item == index2++);
            }

            Assert.AreEqual(index, index2);
        }
コード例 #4
0
        private void RunLocalThreadQueuePrimaryScenario(ThreadPoolLocalQueue q, int elemCount, int slealThCount, int fillFactor)
        {
            int trackElemCount = elemCount;
            int addFinished    = 0;

            int atomicRandom = 0;

            Thread mainThread = null;

            Thread[] stealThreads = new Thread[slealThCount];

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

            Action mainAction = () =>
            {
                List <int> data = new List <int>(elemCount);

                Random rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * slealThCount);

                while (Volatile.Read(ref trackElemCount) >= 0)
                {
                    int addCount = fillFactor;
                    if (rnd != null)
                    {
                        addCount = rnd.Next(fillFactor);
                    }

                    for (int i = 0; i < addCount; i++)
                    {
                        int item = --trackElemCount;
                        if (item < 0)
                        {
                            break;
                        }
                        if (!q.TryAddLocal(new TestThreadPoolItem(item)))
                        {
                            ++trackElemCount;
                            break;
                        }
                    }

                    int removeCount = rnd.Next(fillFactor);

                    for (int i = 0; i < removeCount; i++)
                    {
                        ThreadPoolWorkItem item = null;
                        if (!q.TryTakeLocal(out item))
                        {
                            break;
                        }
                        data.Add((TestThreadPoolItem)item);
                    }
                }

                Interlocked.Increment(ref addFinished);

                ThreadPoolWorkItem finalItem = null;
                while (q.TryTakeLocal(out finalItem))
                {
                    data.Add((TestThreadPoolItem)finalItem);
                }

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

            Action stealAction = () =>
            {
                Random rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * slealThCount);

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

                while (Volatile.Read(ref addFinished) < 1 && Volatile.Read(ref trackElemCount) > elemCount / 1000)
                {
                    ThreadPoolWorkItem tmp;
                    if (q.TrySteal(out tmp))
                    {
                        data.Add((TestThreadPoolItem)tmp);
                    }

                    int sleepTime = rnd.Next(5) - 3;
                    if (sleepTime > 0)
                    {
                        Thread.Sleep(sleepTime);
                    }
                }

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


            mainThread = new Thread(new ThreadStart(mainAction));
            for (int i = 0; i < stealThreads.Length; i++)
            {
                stealThreads[i] = new Thread(new ThreadStart(stealAction));
            }


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


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


            Assert.AreEqual(elemCount, global.Count, "Incorrect element count");

            global.Sort();


            for (int i = 0; i < elemCount; i++)
            {
                Assert.AreEqual(i, global[i], "Incorrect data");
            }
        }
コード例 #5
0
        private static bool TestLocalThreadQueuePrimaryScenario(ThreadPoolLocalQueue q, int elemCount, int slealThCount, int fillFactor, bool useRandom)
        {
            int trackElemCount = elemCount;
            int addFinished    = 0;

            int atomicRandom = 0;

            Thread mainThread = null;

            Thread[] stealThreads = new Thread[slealThCount];

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

            Action mainAction = () =>
            {
                List <int> data = new List <int>(elemCount);

                Random rnd = null;
                if (useRandom)
                {
                    rnd = new Random(Environment.TickCount + Interlocked.Increment(ref atomicRandom) * slealThCount);
                }

                while (Volatile.Read(ref trackElemCount) >= 0)
                {
                    int addCount = fillFactor;
                    if (rnd != null)
                    {
                        addCount = rnd.Next(fillFactor);
                    }

                    for (int i = 0; i < addCount; i++)
                    {
                        int item = --trackElemCount;
                        if (item < 0)
                        {
                            break;
                        }
                        if (!q.TryAddLocal(new TestThreadPoolItem(item)))
                        {
                            ++trackElemCount;
                            break;
                        }
                    }

                    int removeCount = fillFactor;
                    if (rnd != null)
                    {
                        removeCount = rnd.Next(fillFactor);
                    }

                    for (int i = 0; i < removeCount; i++)
                    {
                        ThreadPoolWorkItem item = null;
                        if (!q.TryTakeLocal(out item))
                        {
                            break;
                        }
                        data.Add((TestThreadPoolItem)item);
                    }
                }

                Interlocked.Increment(ref addFinished);

                ThreadPoolWorkItem finalItem = null;
                while (q.TryTakeLocal(out finalItem))
                {
                    data.Add((TestThreadPoolItem)finalItem);
                }

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

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

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

                while (Volatile.Read(ref addFinished) < 1 && Volatile.Read(ref trackElemCount) > elemCount / 1000)
                {
                    ThreadPoolWorkItem tmp;
                    if (q.TrySteal(out tmp))
                    {
                        data.Add((TestThreadPoolItem)tmp);
                    }

                    int sleepTime = Volatile.Read(ref trackElemCount) % 2;
                    if (rnd != null)
                    {
                        sleepTime = rnd.Next(2);
                    }
                    if (sleepTime > 0)
                    {
                        Thread.Sleep(sleepTime);
                    }
                }

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


            mainThread = new Thread(new ThreadStart(mainAction));
            for (int i = 0; i < stealThreads.Length; i++)
            {
                stealThreads[i] = new Thread(new ThreadStart(stealAction));
            }

            Stopwatch sw = Stopwatch.StartNew();

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


            mainThread.Join();
            for (int i = 0; i < stealThreads.Length; i++)
            {
                stealThreads[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("PrimaryScenario " + q.GetType().Name + ". Element count = " + elemCount.ToString() + ", Time = " + sw.ElapsedMilliseconds.ToString() + "ms");
            Console.WriteLine();
            return(result);
        }