Ejemplo n.º 1
0
        public void TestMoveFromLocalQueueToGlobal()
        {
            ThreadPoolQueueController q     = new ThreadPoolQueueController(100, 50);
            ThreadPoolLocalQueue      local = new ThreadPoolLocalQueue();

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

            Assert.AreEqual(100, q.GlobalQueue.OccupiedNodesCount);
            Assert.AreEqual(0, q.GlobalQueue.FreeNodesCount);

            for (int i = 100; i < 110; i++)
            {
                Assert.IsTrue(local.TryAddLocal(new TestThreadPoolItem(i)));
            }

            q.MoveItemsFromLocalQueueToGlobal(local);
            Assert.AreEqual(0, q.GlobalQueue.FreeNodesCount);
            Assert.AreEqual(110, q.GlobalQueue.OccupiedNodesCount);
            Assert.AreEqual(110, q.GlobalQueue.ExtendedCapacity);

            for (int i = 0; i < 110; i++)
            {
                Assert2.AreEqual(i, q.Take(null));
            }

            Assert.AreEqual(100, q.GlobalQueue.FreeNodesCount);
            Assert.AreEqual(0, q.GlobalQueue.OccupiedNodesCount);
            Assert.AreEqual(100, q.GlobalQueue.ExtendedCapacity);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
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]);
            }
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
0
        public void TestAddTakeUpToTheLimit()
        {
            ThreadPoolLocalQueue q = new ThreadPoolLocalQueue();
            int index = 0;

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

            ThreadPoolWorkItem item = null;

            while (q.TryTakeLocal(out item))
            {
                Assert.IsNotNull(item);
                Assert.IsTrue((TestThreadPoolItem)item == --index);
            }

            Assert.AreEqual(0, index);
        }
Ejemplo n.º 6
0
        //private static void TestLocalThreadQueueAsQueue(ILocalThreadQueue q, int elemCount, int fillFactor)
        //{
        //    int trackElemCount = elemCount;

        //    Stopwatch sw = Stopwatch.StartNew();


        //    while (trackElemCount > 0)
        //    {
        //        int initial = trackElemCount;

        //        for (int i = 0; i < fillFactor; i++)
        //        {
        //            if (!q.TryAddGlobal(initial--))
        //                Console.WriteLine("11");
        //        }

        //        initial = trackElemCount;
        //        for (int i = 0; i < fillFactor; i++)
        //        {
        //            object tmp = null;
        //            //q.TryRemove(out tmp);
        //            if (!q.TryRemoveGlobal(out tmp))
        //                Console.WriteLine("22");
        //            if ((int)tmp != initial--)
        //                Console.WriteLine("33");
        //        }
        //        trackElemCount -= fillFactor;
        //    }

        //    sw.Stop();

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


        //private static void TestLocalThreadQueue2AsQueue(ILocalThreadQueue2 q, int elemCount, int fillFactor)
        //{
        //    int trackElemCount = elemCount;

        //    Stopwatch sw = Stopwatch.StartNew();


        //    while (trackElemCount > 0)
        //    {
        //        int initial = trackElemCount;

        //        for (int i = 0; i < fillFactor; i++)
        //        {
        //            if (!q.TryAddLocal(initial--))
        //                Console.WriteLine("11");
        //        }

        //        initial = trackElemCount;
        //        for (int i = 0; i < fillFactor; i++)
        //        {
        //            object tmp = null;
        //            //q.TryRemove(out tmp);
        //            if (!q.TryTakeLocal(out tmp))
        //                Console.WriteLine("22");
        //            if ((int)tmp != initial--)
        //                Console.WriteLine("33");
        //        }
        //        trackElemCount -= fillFactor;
        //    }

        //    sw.Stop();

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


        //private static void TestLocalThreadQueueAsStack(LocalThreadQueue q, int elemCount, int fillFactor)
        //{
        //    int trackElemCount = elemCount;

        //    Stopwatch sw = Stopwatch.StartNew();


        //    while (trackElemCount > 0)
        //    {
        //        int initial = trackElemCount;
        //        for (int i = 0; i < fillFactor; i++)
        //        {
        //            if (!q.TryAddGlobal(initial--))
        //                Console.WriteLine("11");
        //        }

        //        for (int i = 0; i < fillFactor; i++)
        //        {
        //            object tmp = null;
        //            //q.TryRemove(out tmp);
        //            if (!q.TryRemoveGlobal(out tmp))
        //                Console.WriteLine("22");
        //            if ((int)tmp != ++initial)
        //                Console.WriteLine("33");
        //        }
        //        trackElemCount -= fillFactor;
        //    }

        //    sw.Stop();

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


        private static void TestLocalThreadQueue2AsStack(ThreadPoolLocalQueue q, int elemCount, int fillFactor)
        {
            int trackElemCount = elemCount;

            Stopwatch sw = Stopwatch.StartNew();


            while (trackElemCount > 0)
            {
                int initial = trackElemCount;
                for (int i = 0; i < fillFactor; i++)
                {
                    if (!q.TryAddLocal(new TestThreadPoolItem(initial--)))
                    {
                        Console.WriteLine("11");
                    }
                }

                for (int i = 0; i < fillFactor; i++)
                {
                    ThreadPoolWorkItem tmp = null;
                    //q.TryRemove(out tmp);
                    if (!q.TryTakeLocal(out tmp))
                    {
                        Console.WriteLine("22");
                    }
                    if ((TestThreadPoolItem)tmp != ++initial)
                    {
                        Console.WriteLine("33");
                    }
                }
                trackElemCount -= fillFactor;
            }

            sw.Stop();

            Console.WriteLine(q.GetType().Name + ". Element count = " + elemCount.ToString() + ", FillFactor = " + fillFactor.ToString() + ", Time = " + sw.ElapsedMilliseconds.ToString() + "ms");
            Console.WriteLine();
        }
Ejemplo n.º 7
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");
            }
        }
Ejemplo n.º 8
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);
        }