Пример #1
0
        public void API_TryWrappedInvoke()
        {
            var atomicInt = new LockFreeInt32();

            var target = new AtomicDelegate <Func <int, int> >();

            Assert.AreEqual((false, default(int)), target.TryWrappedInvoke(f => f(10)));

            target.Set(i => atomicInt.Add(i).CurrentValue);
            Assert.AreEqual((true, 10), target.TryWrappedInvoke(f => f(10)));
            Assert.AreEqual(10, atomicInt.Value);

            Assert.AreEqual(true, target.TryWrappedInvoke((Action <Func <int, int> >)(f => f(10))));
            Assert.AreEqual(20, atomicInt.Value);
            target.Set(null);
            Assert.AreEqual(false, target.TryWrappedInvoke((Action <Func <int, int> >)(f => f(10))));
            Assert.AreEqual(20, atomicInt.Value);


            // Context-consuming variants
            atomicInt.Set(0);
            target.Set(null);
            Assert.AreEqual((false, default(int)), target.TryWrappedInvoke((f, ctx) => f(ctx), 10));

            target.Set(i => atomicInt.Add(i).CurrentValue);
            Assert.AreEqual((true, 10), target.TryWrappedInvoke((f, ctx) => f(ctx), 10));
            Assert.AreEqual(10, atomicInt.Value);

            Assert.AreEqual(true, target.TryWrappedInvoke((Action <Func <int, int>, int>)((f, ctx) => f(ctx)), 10));
            Assert.AreEqual(20, atomicInt.Value);
            target.Set(null);
            Assert.AreEqual(false, target.TryWrappedInvoke((Action <Func <int, int>, int>)((f, ctx) => f(ctx)), 10));
            Assert.AreEqual(20, atomicInt.Value);
        }
Пример #2
0
        public void API_TryDynamicInvoke()
        {
            var atomicInt = new LockFreeInt32();

            var targetA = new AtomicDelegate <Action <int> >();

            Assert.AreEqual((false, (object)null), targetA.TryDynamicInvoke(10));

            targetA.Set(i => atomicInt.Add(i));
            Assert.AreEqual((true, (object)null), targetA.TryDynamicInvoke(300));
            Assert.Throws <TargetParameterCountException>(() => targetA.TryDynamicInvoke());
            Assert.Throws <ArgumentException>(() => targetA.TryDynamicInvoke(""));
            Assert.Throws <TargetParameterCountException>(() => targetA.TryDynamicInvoke(3, 3));

            var targetB = new AtomicDelegate <Func <int, int> >();

            Assert.AreEqual((false, (object)null), targetB.TryDynamicInvoke(10));

            targetB.Set(i => atomicInt.Add(i).CurrentValue);
            var invokeRes = targetB.TryDynamicInvoke(300);

            Assert.AreEqual(true, invokeRes.DelegateWasInvoked);
            Assert.AreEqual(600, (int)invokeRes.Result);

            Assert.Throws <TargetParameterCountException>(() => targetB.TryDynamicInvoke());
            Assert.Throws <ArgumentException>(() => targetB.TryDynamicInvoke(""));
            Assert.Throws <TargetParameterCountException>(() => targetB.TryDynamicInvoke(3, 3));
        }
Пример #3
0
        void WithInlined_Entry()
        {
            for (var i = 0; i < NumIterations; ++i)
            {
                var incResult = _inlined.Increment();
                Assert(incResult.CurrentValue == incResult.PreviousValue + 1);

                SimulateContention(ContentionLevel.B_Moderate);

                var addResult = _inlined.Add(10);
                Assert(addResult.CurrentValue == addResult.PreviousValue + 10);

                SimulateContention(ContentionLevel.B_Moderate);

                var subResult = _inlined.Subtract(9);
                Assert(subResult.CurrentValue == subResult.PreviousValue - 9);

                SimulateContention(ContentionLevel.B_Moderate);

                var multResult = _inlined.MultiplyBy(3);
                Assert(multResult.CurrentValue == multResult.PreviousValue * 3);

                SimulateContention(ContentionLevel.B_Moderate);

                var divResult = _inlined.DivideBy(4);
                Assert(divResult.CurrentValue == divResult.PreviousValue / 4);

                SimulateContention(ContentionLevel.B_Moderate);

                var decResult = _inlined.Decrement();
                Assert(decResult.CurrentValue == decResult.PreviousValue - 1);

                SimulateContention(ContentionLevel.B_Moderate);

                var value   = _inlined.Value;
                var exchVal = _inlined.Exchange(value + 3);
                _inlined.Value = exchVal.PreviousValue - 3;
            }
        }
Пример #4
0
        void WithCustomInt_Entry()
        {
            const int Bitmask = 0b101010101;

            for (var i = 0; i < NumIterations; ++i)
            {
                var incResult = _customInt32.Increment();
                Assert(incResult.CurrentValue == incResult.PreviousValue + 1);
                var addResult = _customInt32.Add(10);
                Assert(addResult.CurrentValue == addResult.PreviousValue + 10);
                var subResult = _customInt32.Subtract(9);
                Assert(subResult.CurrentValue == subResult.PreviousValue - 9);
                var multResult = _customInt32.MultiplyBy(3);
                Assert(multResult.CurrentValue == multResult.PreviousValue * 3);
                var divResult = _customInt32.DivideBy(4);
                Assert(divResult.CurrentValue == divResult.PreviousValue / 4);
                var decResult = _customInt32.Decrement();
                Assert(decResult.CurrentValue == decResult.PreviousValue - 1);
                var exchangeResult = _customInt32.Exchange(curVal => curVal & Bitmask);
                Assert(exchangeResult.CurrentValue == (exchangeResult.PreviousValue & Bitmask));
            }
        }
Пример #5
0
        public void TryInvokeTryWrappedInvokeTryDynamicInvoke()
        {
            const int NumIterations           = 40_000;
            const int NumCombinesPerIteration = 3;
            const int ActionInputValue        = 3;

            var runner      = new ConcurrentTestCaseRunner <AtomicDelegate <Func <int, int> > >(() => new AtomicDelegate <Func <int, int> >());
            var counter     = new LockFreeInt32();
            var writerCount = new LockFreeInt32();

            var action = new Func <int, int>(n => counter.Add(n).CurrentValue);
            CancellationTokenSource cts = null;

            runner.GlobalSetUp = (_, threadConfig) => {
                writerCount.Value = threadConfig.WriterThreadCount;
                cts = new CancellationTokenSource();
            };
            runner.ExecuteSingleReaderTests(
                writerFunction: target => {
                for (var j = 0; j < NumIterations; j++)
                {
                    for (var i = 0; i < NumCombinesPerIteration; i++)
                    {
                        target.Combine(action);
                    }
                    for (var i = 0; i < NumCombinesPerIteration; i++)
                    {
                        target.Remove(action);
                    }
                }
                cts.Cancel();
            },
                readerFunction: target => {
                var numWriters = writerCount.Value;
                while (!cts.IsCancellationRequested)
                {
                    TestTryInvoke();
                    TestWrappedInvoke();
                    TestDynamicInvoke();

                    void TestTryInvoke()
                    {
                        var curCounterValue = counter.Value;
                        var result          = target.TryInvoke(ActionInputValue);
                        if (result.DelegateWasInvoked)
                        {
                            TestResult(curCounterValue, result.Result);
                        }
                        else
                        {
                            FastAssertEqual(curCounterValue, counter.Value);
                        }
                    }

                    void TestWrappedInvoke()
                    {
                        var curCounterValue = counter.Value;
                        var result          = target.TryWrappedInvoke(t => t(ActionInputValue));
                        if (result.DelegateWasInvoked)
                        {
                            TestResult(curCounterValue, result.Result);
                        }
                        else
                        {
                            FastAssertEqual(curCounterValue, counter.Value);
                        }

                        curCounterValue = counter.Value;
                        result          = target.TryWrappedInvoke((t, ctx) => t(ctx), ActionInputValue);
                        if (result.DelegateWasInvoked)
                        {
                            TestResult(curCounterValue, result.Result);
                        }
                        else
                        {
                            FastAssertEqual(curCounterValue, counter.Value);
                        }

                        curCounterValue = counter.Value;
                        var wasInvoked  = target.TryWrappedInvoke(t => { t(ActionInputValue); });
                        if (wasInvoked)
                        {
                            TestResult(curCounterValue, counter.Value);
                        }
                        else
                        {
                            FastAssertEqual(curCounterValue, counter.Value);
                        }

                        curCounterValue = counter.Value;
                        wasInvoked      = target.TryWrappedInvoke((t, ctx) => { t(ctx); }, ActionInputValue);
                        if (wasInvoked)
                        {
                            TestResult(curCounterValue, counter.Value);
                        }
                        else
                        {
                            FastAssertEqual(curCounterValue, counter.Value);
                        }
                    }

                    void TestDynamicInvoke()
                    {
                        var curCounterValue = counter.Value;
                        var result          = target.TryDynamicInvoke(ActionInputValue);
                        if (result.DelegateWasInvoked)
                        {
                            TestResult(curCounterValue, (int)result.Result);
                        }
                        else
                        {
                            FastAssertEqual(curCounterValue, counter.Value);
                        }
                    }

                    void TestResult(int previousCounterValue, int invocationResult)
                    {
                        var diff = invocationResult - previousCounterValue;
                        FastAssertTrue(diff >= 0 && diff <= NumCombinesPerIteration * numWriters * ActionInputValue);
                        FastAssertTrue(invocationResult % ActionInputValue == 0);
                    }
                }
            }
                );
        }