예제 #1
0
        // =========================

        private void TakeWakesUpTest(DiskQueue <int> queue)
        {
            Barrier            bar         = new Barrier(2);
            AtomicNullableBool takeResult  = new AtomicNullableBool();
            AtomicNullableBool takeResult2 = new AtomicNullableBool();
            Task task = Task.Run(() =>
            {
                bar.SignalAndWait();
                int item         = 0;
                takeResult.Value = queue.TryTake(out item, 60000);
                Assert.AreEqual(100, item);

                item = 0;
                takeResult2.Value = queue.TryTake(out item, 60000);
                Assert.AreEqual(200, item);
            });

            bar.SignalAndWait();
            Thread.Sleep(10);
            Assert.IsFalse(takeResult.HasValue);

            queue.Add(100);
            TimingAssert.AreEqual(10000, true, () => takeResult.Value);

            Thread.Sleep(10);
            Assert.IsFalse(takeResult2.HasValue);

            queue.Add(200);
            TimingAssert.AreEqual(10000, true, () => takeResult2.Value);

            task.Wait();
        }
        public void TestSingleDecreaseWork()
        {
            PartialThreadBlocker inst = new PartialThreadBlocker(4);
            Barrier startBar          = new Barrier(1 + 1);
            int     exitedCount       = 0;

            Task.Run(() =>
            {
                startBar.SignalAndWait();
                inst.Wait();
                Interlocked.Increment(ref exitedCount);
            });

            startBar.SignalAndWait();

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

            for (int i = 1; i <= 4; i++)
            {
                inst.SubstractExpectedWaiterCount(1);
                TimingAssert.AreEqual(5000, 4 - i, () => inst.ExpectedWaiterCount);
                TimingAssert.AreEqual(5000, i == 4 ? 0 : 1, () => inst.RealWaiterCount);
            }

            TimingAssert.AreEqual(5000, 1, () => Volatile.Read(ref exitedCount), "exitedCount != 1");
        }
        public void TestCancellationWork()
        {
            PartialThreadBlocker    inst   = new PartialThreadBlocker(4);
            CancellationTokenSource tokSrc = new CancellationTokenSource();
            int exitedCount = 0;

            Task.Run(() =>
            {
                try
                {
                    inst.Wait(tokSrc.Token);
                }
                catch (OperationCanceledException)
                {
                }
                Interlocked.Increment(ref exitedCount);
            });


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

            tokSrc.Cancel();

            TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount);
            TimingAssert.AreEqual(5000, 0, () => inst.RealWaiterCount);
            TimingAssert.AreEqual(5000, 1, () => Volatile.Read(ref exitedCount));
        }
예제 #4
0
        public void TestNotificationWithPredicate()
        {
            using (var testInst = new MonitorObject())
            {
                int result = 0;
                int state  = 0;
                var task   = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(60000))
                    {
                        if (waiter.Wait((s) => Volatile.Read(ref state) > 0, new object()))
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);
                Assert.AreEqual(0, Volatile.Read(ref result));

                testInst.Pulse();
                Thread.Sleep(100);
                Assert.AreEqual(0, Volatile.Read(ref result));

                Interlocked.Increment(ref state);
                testInst.Pulse();
                TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result));

                task.Wait();
            }
        }
예제 #5
0
        public void PeekWakesUpTest()
        {
            var queue = new BlockingQueue <int>();

            Barrier            bar         = new Barrier(3);
            AtomicNullableBool peekResult  = new AtomicNullableBool();
            AtomicNullableBool peekResult2 = new AtomicNullableBool();
            Task task = Task.Run(() =>
            {
                bar.SignalAndWait();
                int item         = 0;
                peekResult.Value = queue.TryPeek(out item, 60000);
                Assert.AreEqual(100, item);
            });

            Task task2 = Task.Run(() =>
            {
                bar.SignalAndWait();
                int item          = 0;
                peekResult2.Value = queue.TryPeek(out item, 60000);
                Assert.AreEqual(100, item);
            });

            bar.SignalAndWait();
            Thread.Sleep(20);
            Assert.IsFalse(peekResult.HasValue);
            Assert.IsFalse(peekResult2.HasValue);

            queue.Add(100);
            TimingAssert.AreEqual(10000, true, () => peekResult.Value);
            TimingAssert.AreEqual(10000, true, () => peekResult2.Value);

            Task.WaitAll(task, task2);
        }
예제 #6
0
        public void TestNotificationReceived()
        {
            using (var testInst = new MonitorObject())
            {
                int result = 0;
                var task   = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(60000))
                    {
                        if (waiter.Wait())
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);
                Assert.AreEqual(0, Volatile.Read(ref result));

                testInst.Pulse();
                TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result));

                task.Wait();
            }
        }
예제 #7
0
        public void TestSingleThreadWakeUpOnSignal()
        {
            using (var testInst = new MonitorObject())
            {
                int         exitCount = 0;
                int         state     = 0;
                List <Task> tasks     = new List <Task>();
                for (int i = 0; i < 6; i++)
                {
                    var task = Task.Run(() =>
                    {
                        using (var waiter = testInst.Enter())
                        {
                            waiter.Wait(_ => { return(Volatile.Read(ref state) > 0); }, (object)null);
                            Interlocked.Increment(ref exitCount);
                        }
                    });
                    tasks.Add(task);
                }


                TimingAssert.AreEqual(10000, 6, () => testInst.WaiterCount);
                Interlocked.Increment(ref state);

                for (int i = 0; i < 6; i++)
                {
                    testInst.Pulse();
                    TimingAssert.AreEqual(10000, 5 - i, () => testInst.WaiterCount);
                    Thread.Sleep(50);
                    TimingAssert.AreEqual(10000, i + 1, () => Volatile.Read(ref exitCount));
                }

                Task.WaitAll(tasks.ToArray());
            }
        }
예제 #8
0
        public void TestIsTimeoutedWorks()
        {
            using (var testInst = new MonitorObject())
            {
                int result     = 0;
                int cycleCount = 0;
                var task       = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(200))
                    {
                        while (!waiter.IsTimeouted)
                        {
                            waiter.Wait(10);
                            Interlocked.Increment(ref cycleCount);
                        }
                        Interlocked.Exchange(ref result, 1);
                    }
                });

                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);
                TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result));
                Assert.IsTrue(Volatile.Read(ref cycleCount) > 0);

                task.Wait();
            }
        }
예제 #9
0
        public void TestCancellationWorksInWaitNoParam()
        {
            using (var testInst = new MonitorObject())
            {
                int result = 0;
                CancellationTokenSource tokenSrc = new CancellationTokenSource();
                var task = Task.Run(() =>
                {
                    try
                    {
                        using (var waiter = testInst.Enter(60000, tokenSrc.Token))
                        {
                            while (!waiter.Wait())
                            {
                            }
                            Interlocked.Exchange(ref result, 1);
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        Interlocked.Exchange(ref result, 3);
                    }
                });

                testInst.Pulse();

                Thread.Sleep(100);
                Assert.AreEqual(0, Volatile.Read(ref result));

                tokenSrc.Cancel();
                TimingAssert.AreEqual(10000, 3, () => Volatile.Read(ref result));
            }
        }
예제 #10
0
        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));
        }
예제 #11
0
        public void TestCustomTimeoutWorks()
        {
            using (var testInst = new MonitorObject())
            {
                int result = 0;
                var task   = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(60000))
                    {
                        if (waiter.Wait(100))
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);
                TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref result));

                task.Wait();
            }
        }
예제 #12
0
        public void TestWaitingPassed()
        {
            using (var inst = new MutuallyExclusivePrimitive())
            {
                Barrier bar    = new Barrier(2);
                int     result = 0;
                var     task   = Task.Run(() =>
                {
                    bar.SignalAndWait();
                    using (var guard = inst.EnterBackground(60000, default(CancellationToken)))
                    {
                        if (guard.IsAcquired)
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });


                bar.SignalAndWait();
                Thread.Sleep(20);
                inst.AllowBackgroundGate();

                TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result));


                task.Wait();
            }
        }
예제 #13
0
        public void SegmentBackgroundCompactionTest()
        {
            var segmentFactory = new MemorySegmentFactory <int>(10);

            using (var queue = new DiskQueue <int>("dummy", segmentFactory, -1, true, 100))
            {
                Assert.AreEqual(1, queue.SegmentCount);

                for (int i = 0; i < segmentFactory.Capacity; i++)
                {
                    queue.Add(i);
                }

                Assert.AreEqual(1, queue.SegmentCount);

                queue.Add(-1);
                Assert.AreEqual(2, queue.SegmentCount);
                Assert.AreEqual(2, segmentFactory.AllocatedSegments.Count);

                for (int i = 0; i < segmentFactory.Capacity; i++)
                {
                    queue.Take();
                }

                Assert.IsTrue(segmentFactory.AllocatedSegments[0].IsCompleted);

                TimingAssert.AreEqual(10000, 1, () => { Interlocked.MemoryBarrier(); return(queue.SegmentCount); });
                Assert.AreEqual(2, segmentFactory.AllocatedSegments.Count);
            }
        }
예제 #14
0
        // =========================

        private void TimeoutWorksTest(DiskQueue <int> queue)
        {
            Barrier            bar        = new Barrier(2);
            AtomicNullableBool takeResult = new AtomicNullableBool();
            AtomicNullableBool peekResult = new AtomicNullableBool();
            AtomicNullableBool addResult  = new AtomicNullableBool();
            Task task = Task.Run(() =>
            {
                bar.SignalAndWait();
                int item         = 0;
                takeResult.Value = queue.TryTake(out item, 100);
                peekResult.Value = queue.TryPeek(out item, 100);

                while (queue.TryAdd(-1))
                {
                    ;
                }

                addResult.Value = queue.TryAdd(100, 100);
            });

            bar.SignalAndWait();

            TimingAssert.AreEqual(10000, false, () => takeResult.Value, "take");
            TimingAssert.AreEqual(10000, false, () => peekResult.Value, "peek");
            TimingAssert.AreEqual(10000, false, () => addResult.Value, "Add");

            task.Wait();
        }
예제 #15
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");
            }
        }
        public void TestBlockRequiredCount()
        {
            PartialThreadBlocker inst = new PartialThreadBlocker(4);
            Barrier startBar          = new Barrier(8 + 1);
            int     exitedCount       = 0;


            for (int i = 0; i < 8; i++)
            {
                Task.Run(() =>
                {
                    startBar.SignalAndWait();
                    inst.Wait();
                    Interlocked.Increment(ref exitedCount);
                });
            }

            startBar.SignalAndWait();
            Assert.IsTrue(SpinWait.SpinUntil(() => Volatile.Read(ref exitedCount) >= 4 && inst.RealWaiterCount >= 4, 4000));

            TimingAssert.AreEqual(5000, 8 - 4, () => Volatile.Read(ref exitedCount), "exitedCount != 8");
            TimingAssert.AreEqual(5000, 4, () => inst.ExpectedWaiterCount, "ExpectedWaiterCount != 4");
            TimingAssert.AreEqual(5000, 4, () => inst.RealWaiterCount, "RealWaiterCount != 4");

            inst.SetExpectedWaiterCount(0);

            TimingAssert.AreEqual(5000, 8, () => Volatile.Read(ref exitedCount), "exitedCount != 8");
            TimingAssert.AreEqual(5000, 0, () => inst.ExpectedWaiterCount, "ExpectedWaiterCount != 0");
            TimingAssert.AreEqual(5000, 0, () => inst.RealWaiterCount, "RealWaiterCount != 0");
        }
예제 #17
0
        // =========================

        private void AddWakesUpTest(DiskQueue <int> queue, int segmentCapacity)
        {
            while (queue.TryAdd(100))
            {
                ;                       // Fill queue
            }
            queue.AddForced(200);

            Barrier            bar       = new Barrier(2);
            AtomicNullableBool addResult = new AtomicNullableBool();
            Task task = Task.Run(() =>
            {
                bar.SignalAndWait();
                addResult.Value = queue.TryAdd(-100, 60000);
            });

            bar.SignalAndWait();
            Thread.Sleep(10);
            Assert.IsFalse(addResult.HasValue);

            queue.Take();
            Thread.Sleep(10);
            Assert.IsFalse(addResult.HasValue);

            for (int i = 0; i < segmentCapacity; i++)
            {
                int tmp = 0;
                Assert.IsTrue(queue.TryTake(out tmp));
            }
            TimingAssert.AreEqual(10000, true, () => addResult.Value);

            task.Wait();
        }
예제 #18
0
        public void TestPredicateCalledOnTimeout()
        {
            object syncObj = new object();

            using (var testInst = new ConditionVariableAlt(syncObj))
            {
                int result = 0;
                int state  = 0;
                int called = 0;
                var task   = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(100))
                    {
                        if (waiter.Wait((s) => { Interlocked.Increment(ref called); return(Volatile.Read(ref state) > 0); }, new object()))
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);
                TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref result));
                TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref called));
            }
        }
예제 #19
0
        public void TestNotificationReceived()
        {
            object syncObj = new object();

            using (var testInst = new ConditionVariableAlt(syncObj))
            {
                int result = 0;
                var task   = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(60000))
                    {
                        if (waiter.Wait())
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);
                Assert.AreEqual(0, Volatile.Read(ref result));

                lock (syncObj)
                {
                    testInst.Pulse();
                }
                TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result));
            }
        }
예제 #20
0
        public void TestInterruptOnDispose()
        {
            object syncObj = new object();

            using (var testInst = new ConditionVariableAlt(syncObj))
            {
                int exitCount = 0;
                var task      = Task.Run(() =>
                {
                    try
                    {
                        using (var waiter = testInst.Enter())
                        {
                            waiter.Wait(_ => false, (object)null);
                        }
                    }
                    catch (OperationInterruptedException) { }
                    Interlocked.Increment(ref exitCount);
                });


                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);

                testInst.Dispose();
                TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref exitCount));

                task.Wait();
            }
        }
예제 #21
0
        public void TestAllThreadWakeUpOnSignalAll()
        {
            object syncObj = new object();

            using (var testInst = new ConditionVariableAlt(syncObj))
            {
                int         exitCount = 0;
                int         state     = 0;
                List <Task> tasks     = new List <Task>();
                for (int i = 0; i < 6; i++)
                {
                    var task = Task.Run(() =>
                    {
                        using (var waiter = testInst.Enter())
                        {
                            waiter.Wait(_ => { return(Volatile.Read(ref state) > 0); }, (object)null);
                            Interlocked.Increment(ref exitCount);
                        }
                    });
                    tasks.Add(task);
                }


                TimingAssert.AreEqual(10000, 6, () => testInst.WaiterCount);
                Interlocked.Increment(ref state);

                lock (syncObj)
                {
                    testInst.PulseAll();
                }
                TimingAssert.AreEqual(10000, 0, () => testInst.WaiterCount);
                TimingAssert.AreEqual(10000, 6, () => Volatile.Read(ref exitCount));
            }
        }
예제 #22
0
        public void TestLongPredicateEstimatesOnceWithSmallTimeout()
        {
            object syncObj = new object();

            using (var testInst = new ConditionVariableAlt(syncObj))
            {
                int result     = 0;
                int estimCount = 0;
                var task       = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(200))
                    {
                        if (waiter.Wait(_ => { Interlocked.Increment(ref estimCount); Thread.Sleep(500); return(false); }, (object)null))
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                lock (syncObj)
                {
                    testInst.Pulse();
                }
                TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref result));
                Assert.AreEqual(1, Volatile.Read(ref estimCount));
            }
        }
예제 #23
0
        public void TestTimeoutWorks()
        {
            object syncObj = new object();

            using (var testInst = new ConditionVariableAlt(syncObj))
            {
                int result = 0;
                var task   = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(500))
                    {
                        if (waiter.Wait(_ => false, (object)null))
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                lock (syncObj)
                {
                    testInst.Pulse();
                }
                TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref result));
            }
        }
예제 #24
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);
            }
        }
        public void TestPredicateCalledInsideLock()
        {
            object syncObj = new object();

            using (var testInst = new ConditionVariable(syncObj))
            {
                int result         = 0;
                int estimCount     = 0;
                int inMonitorCount = 0;
                int stopEstim      = 0;
                var task           = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(60000))
                    {
                        if (waiter.Wait(_ =>
                        {
                            if (Monitor.IsEntered(syncObj))
                            {
                                Interlocked.Increment(ref inMonitorCount);
                            }
                            Interlocked.Increment(ref estimCount);
                            return(Volatile.Read(ref stopEstim) != 0);
                        }, (object)null))
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);
                for (int i = 0; i < 20; i++)
                {
                    lock (syncObj)
                    {
                        testInst.Pulse();
                    }
                    Thread.Sleep(10);
                }
                Interlocked.Increment(ref stopEstim);
                lock (syncObj)
                {
                    testInst.Pulse();
                }

                TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref result));
                Assert.IsTrue(Volatile.Read(ref estimCount) > 1);
                Assert.AreEqual(Volatile.Read(ref inMonitorCount), Volatile.Read(ref estimCount));
            }
        }
예제 #26
0
        public void TestWaitingWithPredicate()
        {
            using (var ev = new SignalEvent())
            {
                int    waiterEntered = 0;
                int    waitResult    = 0;
                int    waitCondition = 0;
                int    condEvaluated = 0;
                object waiterRef     = null;

                var task = Task.Run(() =>
                {
                    using (var waiter = ev.Factory.CreateWaiter())
                    {
                        Interlocked.Exchange(ref waiterRef, waiter);
                        lock (waiter)
                        {
                            Interlocked.Increment(ref waiterEntered);
                            if (waiter.Wait(s => { Interlocked.Increment(ref condEvaluated); return(Volatile.Read(ref waitCondition) > 0); }, (object)null, 60000))
                            {
                                Interlocked.Exchange(ref waitResult, 1);
                            }
                            else
                            {
                                Interlocked.Exchange(ref waitResult, 2);
                            }
                        }
                    }
                });


                TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref waiterEntered));
                lock (waiterRef)
                {
                    ev.Signal();
                }
                TimingAssert.AreEqual(10000, 2, () => Volatile.Read(ref condEvaluated));
                lock (waiterRef)
                {
                    Assert.AreEqual(0, Volatile.Read(ref waitResult));
                }
                lock (waiterRef)
                {
                    Interlocked.Increment(ref waitCondition);
                    ev.Signal();
                }
                TimingAssert.AreEqual(10000, 3, () => Volatile.Read(ref condEvaluated));
                TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref waitResult));


                task.Wait();
            }
        }
예제 #27
0
        public void TestTryRunWork()
        {
            using (DynamicThreadPool testInst = new DynamicThreadPool(0, Environment.ProcessorCount, 100, "name"))
            {
                int  wasExecuted = 0;
                bool wasRunned   = testInst.TryRun(() =>
                {
                    Interlocked.Exchange(ref wasExecuted, 1);
                });

                Assert.IsTrue(wasRunned);
                TimingAssert.AreEqual(5000, 1, () => Volatile.Read(ref wasExecuted));
            }
        }
예제 #28
0
        public void TestExceptionFromPredicatePassed()
        {
            using (var testInst = new MonitorObject())
            {
                int result = 0;
                int state  = 0;
                var task   = Task.Run(() =>
                {
                    using (var waiter = testInst.Enter(60000))
                    {
                        if (waiter.Wait((s) => { if (Volatile.Read(ref state) > 0)
                                                 {
                                                     throw new ApplicationException();
                                                 }
                                                 return(false); }, new object()))
                        {
                            Interlocked.Exchange(ref result, 1);
                        }
                        else
                        {
                            Interlocked.Exchange(ref result, 2);
                        }
                    }
                });

                TimingAssert.AreEqual(10000, 1, () => testInst.WaiterCount);
                Assert.AreEqual(0, Volatile.Read(ref result));

                testInst.Pulse();
                Thread.Sleep(1);
                Assert.AreEqual(0, Volatile.Read(ref result));

                Interlocked.Increment(ref state);
                testInst.Pulse();
                TimingAssert.AreEqual(10000, 0, () => testInst.WaiterCount);
                Assert.AreEqual(0, result);

                try
                {
                    task.Wait();
                }
                catch (AggregateException aE)
                {
                    if (aE.InnerExceptions.Count != 1 || !(aE.InnerExceptions[0] is ApplicationException))
                    {
                        throw;
                    }
                }
            }
        }
예제 #29
0
        // =========================

        private void AddWakesUpTest(LevelingQueue <int> queue)
        {
            while (queue.TryAdd(100))
            {
                ;                       // Fill queue
            }
            if (queue.IsBackgroundTransferingEnabled)
            {
                SpinWait sw = new SpinWait();
                while (queue.IsBackgroundInWork && sw.Count < 100)
                {
                    sw.SpinOnce();
                }

                for (int i = 0; i < 100; i++)
                {
                    queue.TryAdd(100);
                    SpinWaitHelper.SpinWait(12);
                }
            }

            Barrier bar       = new Barrier(2);
            int     addResult = 0;
            Task    task      = Task.Run(() =>
            {
                bar.SignalAndWait();
                AtomicSet(ref addResult, queue.TryAdd(-100, 60000));
            });

            bar.SignalAndWait();
            Thread.Sleep(10);
            Assert.AreEqual(0, Volatile.Read(ref addResult));

            queue.Take();
            if (queue.AddingMode == LevelingQueueAddingMode.PreserveOrder && !queue.IsBackgroundTransferingEnabled)
            {
                int item;
                while (queue.TryTake(out item))
                {
                    ;
                }
            }

            TimingAssert.AreEqual(10000, 1, () => Volatile.Read(ref addResult));

            task.Wait();
        }
        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);
        }