Beispiel #1
0
        public void TestTakeLock()
        {
            ThreadPoolQueueController q = new ThreadPoolQueueController(100, 1000);

            bool takeCompleted = false;
            int  takeItem      = 0;
            int  startedFlag   = 0;

            Task.Run(() =>
            {
                Interlocked.Exchange(ref startedFlag, 1);
                takeItem = (TestThreadPoolItem)q.Take(null);
                Volatile.Write(ref takeCompleted, true);
            });

            TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1);
            Thread.Sleep(100);
            Assert.IsFalse(takeCompleted);

            q.Add(new TestThreadPoolItem(10), null);

            TimingAssert.IsTrue(5000, () => Volatile.Read(ref takeCompleted));
            Assert.AreEqual(10, takeItem);

            Assert.AreEqual(0, q.GlobalQueue.OccupiedNodesCount);
        }
Beispiel #2
0
        public void TestTakeBlocks()
        {
            PrioritizedElementsContainer <int> testInst = new PrioritizedElementsContainer <int>(new PoolElementComparer());
            CancellationTokenSource            tokSrc   = new CancellationTokenSource();

            bool wasCancelled = false;
            bool wasEntered   = false;
            bool wasExited    = false;

            Task.Run(() =>
            {
                try
                {
                    Volatile.Write(ref wasEntered, true);
                    PoolElementWrapper <int> item;
                    testInst.TryTake(out item, -1, tokSrc.Token);
                }
                catch (OperationCanceledException)
                {
                    Volatile.Write(ref wasCancelled, true);
                }
                Volatile.Write(ref wasExited, true);
            });


            TimingAssert.IsTrue(10000, () => Volatile.Read(ref wasEntered));
            Thread.Sleep(100);

            Assert.IsFalse(Volatile.Read(ref wasExited));

            tokSrc.Cancel();
            TimingAssert.IsTrue(10000, () => Volatile.Read(ref wasExited));

            Assert.IsTrue(Volatile.Read(ref wasCancelled));
        }
Beispiel #3
0
        public void TestCancellationOnStop()
        {
            int threadEnter             = 0;
            int threadExit              = 0;
            ManualResetEventSlim waiter = new ManualResetEventSlim(false);

            using (DelegateThreadSetManager testInst = new DelegateThreadSetManager(Environment.ProcessorCount, "name", (id, state, token) =>
            {
                try
                {
                    Interlocked.Increment(ref threadEnter);
                    waiter.Wait(token);
                }
                finally
                {
                    Interlocked.Increment(ref threadExit);
                }
            }))
            {
                testInst.Start();

                TimingAssert.IsTrue(15000, () => testInst.State == ThreadSetManagerState.Running);
                TimingAssert.IsTrue(15000, () => testInst.ActiveThreadCount == Environment.ProcessorCount);
                TimingAssert.IsTrue(15000, () => Volatile.Read(ref threadEnter) == Environment.ProcessorCount);

                testInst.Stop();
                Assert.IsTrue(testInst.State == ThreadSetManagerState.Stopped);
                Assert.AreEqual(0, testInst.ActiveThreadCount);
                Assert.AreEqual(Environment.ProcessorCount, threadExit, "threadExit != configurated thread count");
            }
        }
        public void TestSendOrPostCallbackSyncThreadPoolWorkItem()
        {
            int value = 0;

            System.Threading.SendOrPostCallback act = (s) =>
            {
                Interlocked.Increment(ref value);
            };

            var item = new SendOrPostCallbackSyncThreadPoolWorkItem(act, null);

            bool waitFinished = false;
            int  startedFlag  = 0;

            Task.Run(() =>
            {
                Interlocked.Exchange(ref startedFlag, 1);
                item.Wait();
                Volatile.Write(ref waitFinished, true);
            });

            TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1);
            Thread.Sleep(100);
            Assert.AreEqual(0, value);
            Assert.AreEqual(false, waitFinished);

            item.Run(false, false);

            TimingAssert.AreEqual(5000, 1, () => Volatile.Read(ref value));
            TimingAssert.AreEqual(5000, true, () => Volatile.Read(ref waitFinished));
        }
Beispiel #5
0
        public void TestSilentTakeCancellation()
        {
            ThreadPoolQueueController q    = new ThreadPoolQueueController(100, 1000);
            CancellationTokenSource   cSrc = new CancellationTokenSource();


            bool takeCompleted           = false;
            bool takeResult              = false;
            ThreadPoolWorkItem takenItem = null;
            int startedFlag              = 0;

            Task.Run(() =>
            {
                Interlocked.Exchange(ref startedFlag, 1);
                var res = q.TryTake(null, out takenItem, -1, cSrc.Token, false);
                Volatile.Write(ref takeResult, res);
                Volatile.Write(ref takeCompleted, true);
            });

            TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1);
            Thread.Sleep(100);
            Assert.IsFalse(takeCompleted);

            cSrc.Cancel();
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref takeCompleted));
            Assert.IsFalse(takeResult);

            Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(1), null, false, 0, CancellationToken.None));
            Assert2.AreEqual(1, q.Take(null));

            Assert.AreEqual(0, q.GlobalQueue.OccupiedNodesCount);
            Assert.AreEqual(100, q.GlobalQueue.FreeNodesCount);
        }
Beispiel #6
0
        public void TestUnlockWhenItemReceive()
        {
            int processed = 0;
            ManualResetEventSlim waiter = new ManualResetEventSlim(false);

            using (DelegateQueueAsyncProcessor <int> proc = new DelegateQueueAsyncProcessor <int>(Environment.ProcessorCount, 1000, "name", (elem, token) =>
            {
                Interlocked.Increment(ref processed);
                waiter.Wait(token);
            }))
            {
                proc.Start();

                for (int i = 0; i < proc.ThreadCount; i++)
                {
                    proc.Add(i);
                }

                //if (!SpinWait.SpinUntil(() => Volatile.Read(ref processed) == proc.ThreadCount, 5000))
                //{
                //    System.Diagnostics.Debugger.Launch();
                //    throw new Exception("Proc: " + Volatile.Read(ref processed).ToString() + ", threads: " + proc.ActiveThreadCount.ToString() +
                //                        ", tasks: " + proc.ElementCount.ToString());
                //}

                TimingAssert.IsTrue(15000, () => Volatile.Read(ref processed) == proc.ThreadCount, "FAILED: wait for all thread start");

                waiter.Set();
                proc.Stop(true, true, true);

                Assert.IsTrue(proc.State == QueueAsyncProcessorState.Stopped, "proc.State == QueueAsyncProcessorState.Stopped");
            }
        }
        public void CaptureContextNoSyncContextTest()
        {
            var originalContext = SynchronizationContext.Current;
            var syncContext     = new CustomSyncContext();

            try
            {
                SynchronizationContext.SetSynchronizationContext(syncContext);
                var eContext = ExecutionContextHelper.CaptureContextNoSyncContextIfPossible();
                Assert.IsNotNull(eContext);

                AtomicBool isDefaulContext = new AtomicBool(false);
                var        task            = Task.Run(() =>
                {
                    SynchronizationContext.SetSynchronizationContext(null);
                    ExecutionContextHelper.RunInContext(eContext, (st) =>
                    {
                        isDefaulContext.Value = SynchronizationContext.Current == null;
                    }, null, true);
                });


                task.Wait();
                TimingAssert.IsTrue(10000, isDefaulContext, "Default context expected");
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(originalContext);
            }
        }
Beispiel #8
0
        public void TestCancellation()
        {
            SemaphoreLight          inst     = new SemaphoreLight(0);
            CancellationTokenSource tokenSrc = new CancellationTokenSource();
            bool cancelled = false;

            Task.Run(() =>
            {
                try
                {
                    inst.Wait(tokenSrc.Token);
                }
                catch (OperationCanceledException)
                {
                    Volatile.Write(ref cancelled, true);
                    Thread.MemoryBarrier();
                }
            });

            TimingAssert.IsTrue(5000, () => inst.WaiterCount > 0);
            Assert.IsFalse(Volatile.Read(ref cancelled));

            tokenSrc.Cancel();
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref cancelled));

            Assert.AreEqual(0, inst.CurrentCount);
            Assert.AreEqual(0, inst.WaiterCount);
        }
Beispiel #9
0
        public void TestRunAndStopWithLongWork()
        {
            int threadExit = 0;

            using (DelegateThreadSetManager testInst = new DelegateThreadSetManager(Environment.ProcessorCount, "name", (id, state, token) =>
            {
                Thread.Sleep(2500);
                Interlocked.Increment(ref threadExit);
            }))
            {
                Assert.IsTrue(testInst.State == ThreadSetManagerState.Created);

                Assert.AreEqual(Environment.ProcessorCount, testInst.ThreadCount);
                Assert.IsFalse(testInst.IsWork);

                testInst.Start();

                TimingAssert.IsTrue(15000, () => testInst.ActiveThreadCount == Environment.ProcessorCount);

                testInst.Stop();
                Assert.IsTrue(testInst.State == ThreadSetManagerState.Stopped);
                Assert.AreEqual(0, testInst.ActiveThreadCount);
                Assert.AreEqual(Environment.ProcessorCount, threadExit);
            }
        }
Beispiel #10
0
        public void TestSimpleRunAndStop()
        {
            int threadStart = 0;

            using (DelegateThreadSetManager testInst = new DelegateThreadSetManager(Environment.ProcessorCount, "name", (id, state, token) =>
            {
                Interlocked.Increment(ref threadStart);
            }))
            {
                Assert.IsTrue(testInst.State == ThreadSetManagerState.Created, "State != Created");

                Assert.AreEqual(Environment.ProcessorCount, testInst.ThreadCount);
                Assert.IsFalse(testInst.IsWork);

                testInst.Start();

                SpinWait.SpinUntil(() => Volatile.Read(ref threadStart) >= testInst.ThreadCount, 10000);
                TestContext.WriteLine("All thread started");
                bool byCondition = SpinWait.SpinUntil(() => testInst.ActiveThreadCount == 0, 5000);
                TestContext.WriteLine(byCondition ? "ActiveThreadCount == 0" : "ActiveThreadCount != 0 (timeout)");

                TimingAssert.AreEqual(15000, Environment.ProcessorCount, () => Volatile.Read(ref threadStart));
                TimingAssert.IsTrue(5000, () => testInst.State == ThreadSetManagerState.AllThreadsExited, "State != AllThreadsExited");

                testInst.Stop();
                Assert.IsTrue(testInst.State == ThreadSetManagerState.Stopped, "State != Stopped");
            }
        }
Beispiel #11
0
        private void RunComplexTest()
        {
            using (EntryCountingEvent inst = new EntryCountingEvent())
            {
                Barrier     bar            = new Barrier(7);
                int         threadFinished = 0;
                int         entryCount     = 0;
                bool        isTestDispose  = false;
                List <Task> taskList       = new List <Task>();

                for (int i = 0; i < 6; i++)
                {
                    int a    = i;
                    var task = Task.Run(() =>
                    {
                        Random rnd = new Random(a);
                        bar.SignalAndWait();
                        for (int j = 0; j < 1000; j++)
                        {
                            using (var eee = inst.TryEnter())
                            {
                                if (!eee.IsAcquired)
                                {
                                    break;
                                }

                                Interlocked.Increment(ref entryCount);

                                if (isTestDispose)
                                {
                                    throw new Exception();
                                }

                                Thread.Sleep(rnd.Next(10, 100));
                                if (isTestDispose)
                                {
                                    throw new Exception();
                                }
                            }
                        }

                        Interlocked.Increment(ref threadFinished);
                    });
                    taskList.Add(task);
                }

                bar.SignalAndWait();
                TimingAssert.IsTrue(5000, () => Volatile.Read(ref entryCount) > 12);
                inst.TerminateAndWait();
                isTestDispose = true;
                inst.Dispose();
                TimingAssert.AreEqual(5000, 6, () => Volatile.Read(ref threadFinished));

                Task.WhenAll(taskList);
            }
        }
Beispiel #12
0
        public void TestExtensionWork()
        {
            ThreadPoolQueueController q = new ThreadPoolQueueController(100, 1000);

            Assert.AreEqual(100, q.GlobalQueue.ExtendedCapacity);

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

            bool addCompleted = false;
            int  startedFlag  = 0;

            Task.Run(() =>
            {
                Interlocked.Exchange(ref startedFlag, 1);
                q.Add(new TestThreadPoolItem(100), null);
                Volatile.Write(ref addCompleted, true);
            });

            TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1);
            Thread.Sleep(100);
            Assert.IsFalse(addCompleted);

            q.ExtendGlobalQueueCapacity(100);
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref addCompleted));

            Assert.AreEqual(200, q.GlobalQueue.ExtendedCapacity);

            for (int i = 101; i < 200; i++)
            {
                Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(i), null, false, 0, CancellationToken.None));
            }

            Assert.IsFalse(q.TryAdd(new TestThreadPoolItem(int.MaxValue), null, false, 0, CancellationToken.None));

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

            Assert.AreEqual(0, q.GlobalQueue.OccupiedNodesCount);
            Assert.AreEqual(100, q.GlobalQueue.ExtendedCapacity);
            Assert.AreEqual(100, q.GlobalQueue.FreeNodesCount);
        }
Beispiel #13
0
        public void TestTaskSchedulerSetted()
        {
            using (DynamicThreadPool testInst = new DynamicThreadPool(0, Environment.ProcessorCount, -1, "name", false, new DynamicThreadPoolOptions()
            {
                UseOwnTaskScheduler = true, UseOwnSyncContext = true
            }))
            {
                AtomicBool isPropperSceduller = new AtomicBool(false);

                testInst.Run(() =>
                {
                    isPropperSceduller.Value = TaskScheduler.Current == testInst.TaskScheduler;
                });

                TimingAssert.IsTrue(10000, isPropperSceduller, "isPropperSceduller");
                testInst.Dispose(true, true, false);
            }
        }
        public void TestIncreaseWaiters()
        {
            PartialThreadBlocker inst        = new PartialThreadBlocker(4);
            Barrier startBar                 = new Barrier(8 + 1);
            int     exitedCount              = 0;
            int     somethingWork            = 0;
            CancellationTokenSource tokenSrc = new CancellationTokenSource();

            for (int i = 0; i < 8; i++)
            {
                Task.Run(() =>
                {
                    startBar.SignalAndWait();
                    while (!tokenSrc.IsCancellationRequested)
                    {
                        inst.Wait();
                        Interlocked.Increment(ref somethingWork);
                        Thread.Sleep(10);
                    }
                    Interlocked.Increment(ref exitedCount);
                });
            }

            startBar.SignalAndWait();

            TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount);
            TimingAssert.AreEqual(5000, 4, () => inst.RealWaiterCount, "Real waiter count != 4 (can be caused by slow processing)");
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref somethingWork) > 0);

            inst.SetExpectedWaiterCount(8);
            Assert.AreEqual(8, inst.ExpectedWaiterCount);

            TimingAssert.AreEqual(5000, 8, () => inst.RealWaiterCount);
            Interlocked.Exchange(ref somethingWork, 0);

            TimingAssert.IsTrue(5000, () => Volatile.Read(ref somethingWork) == 0);

            tokenSrc.Cancel();
            inst.SetExpectedWaiterCount(0);

            TimingAssert.AreEqual(5000, 8, () => Volatile.Read(ref exitedCount));
            TimingAssert.AreEqual(5000, 0, () => inst.ExpectedWaiterCount);
            TimingAssert.AreEqual(500, 0, () => inst.RealWaiterCount);
        }
Beispiel #15
0
        public void TestAddCancellation()
        {
            ThreadPoolQueueController q    = new ThreadPoolQueueController(100, 1000);
            CancellationTokenSource   cSrc = new CancellationTokenSource();

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

            bool addCompleted = false;
            int  startedFlag  = 0;

            Task.Run(() =>
            {
                try
                {
                    Interlocked.Exchange(ref startedFlag, 1);
                    q.TryAdd(new TestThreadPoolItem(int.MaxValue), null, false, -1, cSrc.Token);
                }
                catch (OperationCanceledException)
                {
                }
                Volatile.Write(ref addCompleted, true);
            });

            TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1);
            Thread.Sleep(100);
            Assert.IsFalse(addCompleted);

            cSrc.Cancel();
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref addCompleted));


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

            Assert.AreEqual(0, q.GlobalQueue.OccupiedNodesCount);
            Assert.AreEqual(100, q.GlobalQueue.FreeNodesCount);
        }
        public void TestRegisterDeregister()
        {
            int calledCount = 0;

            ManagementThreadControllerCallback act = (elapsed) =>
            {
                Interlocked.Increment(ref calledCount);
                return(true);
            };


            ManagementThreadController.Instance.RegisterCallback(act);

            TimingAssert.IsTrue(10 * ManagementThreadController.SleepPeriod, () => Volatile.Read(ref calledCount) > 0);

            ManagementThreadController.Instance.UnregisterCallback(act);
            int lastCallCount = calledCount;

            TimingAssert.AreEqual(2 * ManagementThreadController.SleepPeriod, lastCallCount, () => Volatile.Read(ref calledCount));
        }
Beispiel #17
0
        public void TestWakeUpOnRelease()
        {
            SemaphoreLight inst   = new SemaphoreLight(0);
            bool           wakeUp = false;

            Task.Run(() =>
            {
                inst.Wait();
                wakeUp = true;
            });

            TimingAssert.IsTrue(5000, () => inst.WaiterCount > 0);
            Assert.IsFalse(wakeUp);

            inst.Release();
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref wakeUp));

            Assert.AreEqual(0, inst.CurrentCount);
            Assert.AreEqual(0, inst.WaiterCount);
        }
Beispiel #18
0
        public void SetTaskSchedulerAndExecuteEntryTest()
        {
            var sched = new TestTaskScheduler();

            int        val = 0;
            AtomicBool taskSchedullerSetted = new AtomicBool(false);

            Task tsk = null;

            tsk = new Task(() =>
            {
                taskSchedullerSetted.Value = TaskScheduler.Current == sched;
                Interlocked.Increment(ref val);
            });

            TaskHelper.SetTaskScheduler(tsk, sched);
            TaskHelper.ExecuteTaskEntry(tsk);

            TimingAssert.IsTrue(10000, taskSchedullerSetted, "taskSchedullerSetted");
        }
Beispiel #19
0
        public void TestTerminateWaiting()
        {
            using (EntryCountingEvent inst = new EntryCountingEvent())
            {
                bool finished = false;
                Task task     = null;
                using (inst.Enter())
                {
                    task = Task.Run(() =>
                    {
                        inst.TerminateAndWait();
                        finished = true;
                    });

                    TimingAssert.IsFalse(5000, () => finished);
                }
                TimingAssert.IsTrue(5000, () => finished);

                task.Wait();
            }
        }
Beispiel #20
0
        public void TestHardStopWork()
        {
            int processed               = 0;
            int startedTask             = 0;
            ManualResetEventSlim waiter = new ManualResetEventSlim(false);

            using (DelegateQueueAsyncProcessor <int> proc = new DelegateQueueAsyncProcessor <int>(Environment.ProcessorCount, 1000, "name", (elem, token) =>
            {
                try
                {
                    Interlocked.Increment(ref startedTask);
                    waiter.Wait(token);
                }
                finally
                {
                    Interlocked.Increment(ref processed);
                }
            }))
            {
                proc.Start();

                for (int i = 0; i < 5 * Environment.ProcessorCount; i++)
                {
                    proc.Add(i);
                }

                Assert.IsTrue(proc.ThreadCount > 0, "proc.ThreadCount > 0");
                Assert.IsTrue(proc.ThreadCount == Environment.ProcessorCount, "proc.ThreadCount == Environment.ProcessorCount");

                TimingAssert.IsTrue(10000, () => proc.ActiveThreadCount >= 0, "FAILED: wait while thread activated");
                TimingAssert.IsTrue(10000, () => proc.ActiveThreadCount == proc.ThreadCount, "FAILED: wait while all threads activated");

                TimingAssert.IsTrue(10000, () => Volatile.Read(ref startedTask) >= 0, "FAILED: wait while first thread blocked");
                TimingAssert.IsTrue(10000, () => Volatile.Read(ref startedTask) == proc.ThreadCount, () => "FAILED: wait while all thread blocked. Currently blocked = " + Volatile.Read(ref startedTask).ToString() + ", expected = " + proc.ThreadCount.ToString());
                proc.Stop(true, false, true);

                Assert.IsTrue(proc.State == QueueAsyncProcessorState.Stopped, "proc.State == QueueAsyncProcessorState.Stopped");
                Assert.IsTrue(processed > 0, "processed > 0");
            }
        }
Beispiel #21
0
        public void TestPeekWait()
        {
            BlockingQueue <int> col = new BlockingQueue <int>(100);
            int startedFlag         = 0;

            int peekVal = 0;

            Task.Run(() =>
            {
                Interlocked.Exchange(ref startedFlag, 1);
                peekVal = col.Peek();
            });

            TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1);
            Thread.Sleep(100);
            Assert.AreEqual(0, peekVal);

            col.Add(100);

            TimingAssert.AreEqual(5000, 100, () => Volatile.Read(ref peekVal));
            TimingAssert.AreEqual(5000, 1, () => col.Count);
        }
        public void TestTimeoutWork()
        {
            PartialThreadBlocker inst = new PartialThreadBlocker(4);
            int  exitedCount          = 0;
            bool exitByTimeout        = false;

            Task.Run(() =>
            {
                Volatile.Write(ref exitByTimeout, !inst.Wait(1500));
                Interlocked.Increment(ref exitedCount);
            });


            TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount);
            TimingAssert.AreEqual(5000, 1, () => inst.RealWaiterCount);


            TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount);
            TimingAssert.AreEqual(5000, 0, () => inst.RealWaiterCount);
            TimingAssert.AreEqual(5000, 1, () => Volatile.Read(ref exitedCount));
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref exitByTimeout));
        }
Beispiel #23
0
        public void RegisterWithoutECTest()
        {
            var originalContext = SynchronizationContext.Current;
            var syncContext     = new CustomSyncContext();

            try
            {
                CancellationTokenSource tokenSource = new CancellationTokenSource();
                CancellationToken       token       = tokenSource.Token;

                AtomicBool isNoExecutionContext = new AtomicBool(false);

                using (CancellationTokenHelper.RegisterWithoutECIfPossible(token, (st) =>
                {
                    isNoExecutionContext.Value = SynchronizationContext.Current == null;
                }, null))
                {
                    Barrier barrier  = new Barrier(2);
                    Barrier barrier2 = new Barrier(2);

                    Task.Run(() =>
                    {
                        barrier.SignalAndWait();
                        barrier2.SignalAndWait();
                        tokenSource.Cancel();
                    });

                    barrier.SignalAndWait();
                    SynchronizationContext.SetSynchronizationContext(syncContext);
                    barrier2.SignalAndWait();
                    TimingAssert.IsTrue(10000, isNoExecutionContext, "isNoExecutionContext");
                }
            }
            finally
            {
                SynchronizationContext.SetSynchronizationContext(originalContext);
            }
        }
Beispiel #24
0
        public void TestAddLock()
        {
            ThreadPoolGlobalQueue q = new ThreadPoolGlobalQueue(100);

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

            bool addCompleted = false;
            int  startedFlag  = 0;

            Task.Run(() =>
            {
                Interlocked.Exchange(ref startedFlag, 1);
                q.Add(new TestThreadPoolItem(int.MaxValue));
                Volatile.Write(ref addCompleted, true);
            });

            TimingAssert.IsTrue(10000, () => Volatile.Read(ref startedFlag) == 1);
            Thread.Sleep(100);
            Assert.IsFalse(addCompleted);

            Assert2.AreEqual(0, q.Take());
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref addCompleted));

            Assert.IsFalse(q.TryAdd(new TestThreadPoolItem(int.MinValue), 0, CancellationToken.None));

            for (int i = 1; i < 100; i++)
            {
                Assert2.AreEqual(i, (TestThreadPoolItem)q.Take(), "(TestThreadPoolItem)q.Take(null, null) == i");
            }

            Assert2.AreEqual(int.MaxValue, q.Take(), "(TestThreadPoolItem)q.Take(null, null) == int.MaxValue");

            Assert.AreEqual(0, q.OccupiedNodesCount);
        }
Beispiel #25
0
        public void TestSyncContextSetted()
        {
            using (DynamicThreadPool testInst = new DynamicThreadPool(0, Environment.ProcessorCount, -1, "name", false, new DynamicThreadPoolOptions()
            {
                UseOwnTaskScheduler = true, UseOwnSyncContext = true
            }))
            {
                AtomicBool isPropperSyncContext = new AtomicBool(false);

                testInst.Run(() =>
                {
                    if (SynchronizationContext.Current != null)
                    {
                        SynchronizationContext.Current.Post((st) =>
                        {
                            isPropperSyncContext.Value = testInst.IsThreadPoolThread;
                        }, null);
                    }
                });

                TimingAssert.IsTrue(10000, isPropperSyncContext, "isPropperSyncContext");
                testInst.Dispose(true, true, false);
            }
        }
Beispiel #26
0
        public void TestNoSyncContextAndTaskSchedullerWhenNotConfigurated()
        {
            using (DynamicThreadPool testInst = new DynamicThreadPool(0, Environment.ProcessorCount, -1, "name", false, new DynamicThreadPoolOptions()
            {
                UseOwnTaskScheduler = false, UseOwnSyncContext = false
            }))
            {
                var defSyncContext    = SynchronizationContext.Current;
                var defTaskScheduller = TaskScheduler.Current;

                AtomicBool isDefaultSyncContext    = new AtomicBool(false);
                AtomicBool isDefaultTaskScheduller = new AtomicBool(false);

                testInst.Run(() =>
                {
                    isDefaultSyncContext.Value    = SynchronizationContext.Current == defSyncContext;
                    isDefaultTaskScheduller.Value = TaskScheduler.Current == defTaskScheduller;
                });

                TimingAssert.IsTrue(10000, isDefaultSyncContext, "isDefaultSyncContext");
                TimingAssert.IsTrue(10000, isDefaultTaskScheduller, "isDefaultTaskScheduller");
                testInst.Dispose(true, true, false);
            }
        }
        public void TestCycledBlockRequiredCount()
        {
            PartialThreadBlocker inst        = new PartialThreadBlocker(4);
            Barrier startBar                 = new Barrier(8 + 1);
            int     exitedCount              = 0;
            int     somethingWork            = 0;
            CancellationTokenSource tokenSrc = new CancellationTokenSource();

            for (int i = 0; i < 8; i++)
            {
                Task.Run(() =>
                {
                    startBar.SignalAndWait();
                    while (!tokenSrc.IsCancellationRequested)
                    {
                        inst.Wait();
                        Interlocked.Increment(ref somethingWork);
                        Thread.Sleep(10);
                    }
                    Interlocked.Increment(ref exitedCount);
                });
            }

            startBar.SignalAndWait();

            TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount);
            TimingAssert.AreEqual(5000, 4, () => inst.RealWaiterCount);
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref somethingWork) > 0);

            tokenSrc.Cancel();
            inst.SetExpectedWaiterCount(0);

            TimingAssert.AreEqual(5000, 8, () => Volatile.Read(ref exitedCount));
            TimingAssert.AreEqual(5000, 0, () => inst.ExpectedWaiterCount);
            TimingAssert.AreEqual(5000, 0, () => inst.RealWaiterCount);
        }
Beispiel #28
0
        public void TestTakeCancellation()
        {
            ThreadPoolGlobalQueue   q    = new ThreadPoolGlobalQueue(100);
            CancellationTokenSource cSrc = new CancellationTokenSource();


            bool takeCompleted           = false;
            ThreadPoolWorkItem takenItem = null;
            int startedFlag = 0;

            Task.Run(() =>
            {
                try
                {
                    Interlocked.Exchange(ref startedFlag, 1);
                    q.TryTake(out takenItem, -1, cSrc.Token, true);
                }
                catch (OperationCanceledException)
                {
                }
                Volatile.Write(ref takeCompleted, true);
            });

            TimingAssert.IsTrue(5000, () => Volatile.Read(ref startedFlag) == 1);
            Thread.Sleep(100);
            Assert.IsFalse(takeCompleted);

            cSrc.Cancel();
            TimingAssert.IsTrue(5000, () => Volatile.Read(ref takeCompleted));

            Assert.IsTrue(q.TryAdd(new TestThreadPoolItem(1), 0, CancellationToken.None));
            Assert2.AreEqual(1, q.Take());

            Assert.AreEqual(0, q.OccupiedNodesCount);
            Assert.AreEqual(100, q.FreeNodesCount);
        }
Beispiel #29
0
        public void DynamicThreadPoolPerformBalancing()
        {
            using (DynamicThreadPool testInst = new DynamicThreadPool(0, 4 * Environment.ProcessorCount, 1000, "name"))
            {
                Assert.AreEqual(0, testInst.ActiveThreadCount);

                // ========== Проверяем, что число потоков увеличивается автоматически от нуля ===========

                int executedTaskCount = 0;

                for (int i = 0; i < 1000; i++)
                {
                    testInst.Run(() =>
                    {
                        Interlocked.Increment(ref executedTaskCount);
                    });
                }

                TimingAssert.AreEqual(5000, 1000, () => Volatile.Read(ref executedTaskCount));
                Assert.IsTrue(testInst.ActiveThreadCount > 0, "1. testInst.ActiveThreadCount > 0");

                // ======== Проверяем, что на большом числе задач он рано или поздно дойдёт до числа потоков равного числу ядер ===========

                executedTaskCount = 0;
                for (int i = 0; i < testInst.MaxThreadCount * testInst.QueueCapacity; i++)
                {
                    testInst.Run(() =>
                    {
                        Thread.Sleep(1);
                        Interlocked.Increment(ref executedTaskCount);
                    });
                }


                TimingAssert.AreEqual(15000, testInst.MaxThreadCount * testInst.QueueCapacity, () => Volatile.Read(ref executedTaskCount));
                Assert.IsTrue(testInst.ActiveThreadCount >= Environment.ProcessorCount, "2. testInst.ActiveThreadCount >= Environment.ProcessorCount");


                // ======== Проверяем, что на долгих задачах число потоков может стать больше числа ядер ===========

                executedTaskCount = 0;
                for (int i = 0; i < 1000; i++)
                {
                    testInst.Run(() =>
                    {
                        Thread.Sleep(20);
                        Interlocked.Increment(ref executedTaskCount);
                    });
                }


                TimingAssert.IsTrue(30000, () => Volatile.Read(ref executedTaskCount) >= 500);

                Assert.IsTrue(testInst.ActiveThreadCount > Environment.ProcessorCount, "3. testInst.ActiveThreadCount > Environment.ProcessorCount");
                Assert.IsTrue(testInst.ActiveThreadCount <= testInst.MaxThreadCount, "3. testInst.ActiveThreadCount <= testInst.MaxThreadCount");

                TimingAssert.AreEqual(30000, 1000, () => Volatile.Read(ref executedTaskCount));

                TimingAssert.IsTrue(5000, () => testInst.ActiveThreadCount <= Environment.ProcessorCount, "4. testInst.ActiveThreadCount <= Environment.ProcessorCount");
            }
        }