Exemple #1
0
        public void FastExchange()
        {
            const int NumIterations = 3_000_000;

            var atomicIntA = new AtomicInt(0);
            var atomicIntB = new AtomicInt(0);
            var runner     = NewRunner(new DummyImmutableVal(0, 0));

            // (T)
            runner.GlobalSetUp        = (_, __) => { atomicIntA.Set(0); atomicIntB.Set(0); };
            runner.AllThreadsTearDown = target => {
                AssertAreEqual(NumIterations, target.Value.Alpha);
                AssertAreEqual(NumIterations, target.Value.Bravo);
            };
            runner.ExecuteContinuousSingleWriterCoherencyTests(
                target => {
                var newA     = atomicIntA.Increment().CurrentValue;
                var newB     = atomicIntB.Increment().CurrentValue;
                var newValue = new DummyImmutableVal(newA, newB);
                var prev     = target.FastExchange(newValue);
                AssertAreEqual(prev.Alpha, newA - 1);
                AssertAreEqual(prev.Bravo, newB - 1);
            },
                NumIterations,
                target => target.Value,
                (prev, cur) => {
                AssertTrue(prev.Alpha <= cur.Alpha);
                AssertTrue(prev.Bravo <= cur.Bravo);
            }
                );
            runner.GlobalSetUp        = null;
            runner.AllThreadsTearDown = null;
        }
        public void Assert_Coherency_Swap()
        {
            const int NumIterations = 3_000_000;

            var atomicIntA = new LockFreeInt32(0);
            var atomicIntB = new LockFreeInt32(0);
            var runner     = NewRunner(new DummyImmutableVal(0, 0));

            runner.GlobalSetUp        = (_, __) => { atomicIntA.Set(0); atomicIntB.Set(0); };
            runner.AllThreadsTearDown = target => {
                FastAssertEqual(NumIterations, target.Value.Alpha);
                FastAssertEqual(NumIterations, target.Value.Bravo);
            };
            runner.ExecuteContinuousSingleWriterCoherencyTests(
                target => {
                var newA     = atomicIntA.IncrementAndGet();
                var newB     = atomicIntB.IncrementAndGet();
                var newValue = new DummyImmutableVal(newA, newB);
                var prev     = target.Swap(newValue);
                FastAssertEqual(prev.Alpha, newA - 1);
                FastAssertEqual(prev.Bravo, newB - 1);
            },
                NumIterations,
                target => target.Value,
                (prev, cur) => {
                FastAssertTrue(prev.Alpha <= cur.Alpha);
                FastAssertTrue(prev.Bravo <= cur.Bravo);
            }
                );
            runner.GlobalSetUp        = null;
            runner.AllThreadsTearDown = null;
        }
        public void Assert_Coherency_TrySwap()
        {
            const int NumIterations = 2_000_000;

            var runner = NewRunner(new DummyImmutableVal(0, 0));

            runner.ExecuteContinuousCoherencyTests(
                target => {
                var curValue = target.Value;
                var newValue = new DummyImmutableVal(0, curValue.Bravo + 1);
                target.TrySwap(newValue, curValue);
            },
                NumIterations,
                target => target.Value,
                (prev, cur) => FastAssertTrue(cur.Bravo >= prev.Bravo)
                );
        }
Exemple #4
0
        public void TryExchangeWithContext()
        {
            const int NumIterations = 300_000;

            var runner = NewRunner(new DummyImmutableVal(0, 0));

            // (T, Func<T, T, TContext, bool>)
            runner.AllThreadsTearDown = target => {
                AssertAreEqual(NumIterations, target.Value.Alpha);
                AssertAreEqual(-1 * NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    var newValue = new DummyImmutableVal(curValue.Alpha + 1, curValue.Bravo - 1);
                    var(wasSet, prevValue, setValue) = target.TryExchange(newValue, (c, n, ctx) => c.Alpha + ctx == n.Alpha && c.Bravo - ctx == n.Bravo, 1);
                    if (wasSet)
                    {
                        AssertAreEqual(curValue, prevValue);
                        AssertAreEqual(newValue, setValue);
                    }
                    else
                    {
                        AssertAreNotEqual(curValue, prevValue);
                        AssertAreEqual(setValue, prevValue);
                    }
                }
            }
                );
            runner.AllThreadsTearDown = null;

            // (Func<T, TContext, T>, T)
            runner.ExecuteFreeThreadedTests(
                target => {
                var curValue = target.Value;

                var(wasSet, prevValue, CurrentValue) = target.TryExchange(
                    (c, ctx) => c.Bravo < c.Alpha
                                                        ? new DummyImmutableVal(c.Alpha, c.Bravo + ctx)
                                                        : new DummyImmutableVal(c.Alpha + ctx, c.Bravo),
                    1, curValue);

                if (wasSet)
                {
                    AssertAreEqual(curValue, prevValue);
                    AssertAreEqual(prevValue.Bravo < prevValue.Alpha ? new DummyImmutableVal(prevValue.Alpha, prevValue.Bravo + 1) : new DummyImmutableVal(prevValue.Alpha + 1, prevValue.Bravo), CurrentValue);
                }
                else
                {
                    AssertAreNotEqual(curValue, prevValue);
                }
            },
                NumIterations
                );

            // (Func<T, TContext, T>, Func<T, T, bool>)
            runner.AllThreadsTearDown = target => {
                AssertAreEqual(NumIterations, target.Value.Alpha);
                AssertAreEqual(-1 * NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    var(wasSet, prevValue, CurrentValue) = target.TryExchange((c, ctx) => new DummyImmutableVal(c.Alpha + ctx, c.Bravo - ctx), 1, (c, n) => c.Alpha + 1 == n.Alpha && c.Bravo - 1 == n.Bravo && c.Alpha < NumIterations);
                    if (wasSet)
                    {
                        AssertAreEqual(new DummyImmutableVal(prevValue.Alpha + 1, prevValue.Bravo - 1), CurrentValue);
                        AssertTrue(CurrentValue.Alpha <= NumIterations);
                    }
                    else
                    {
                        AssertAreEqual(CurrentValue, prevValue);
                    }
                }
            }
                );
            runner.AllThreadsTearDown = null;

            // (Func<T, T>, Func<T, T, TContext, bool>)
            runner.AllThreadsTearDown = target => {
                AssertAreEqual(NumIterations, target.Value.Alpha);
                AssertAreEqual(-1 * NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    var(wasSet, prevValue, CurrentValue) = target.TryExchange(c => new DummyImmutableVal(c.Alpha + 1, c.Bravo - 1), (c, n, ctx) => c.Alpha + ctx == n.Alpha && c.Bravo - ctx == n.Bravo && c.Alpha < NumIterations, 1);
                    if (wasSet)
                    {
                        AssertAreEqual(new DummyImmutableVal(prevValue.Alpha + 1, prevValue.Bravo - 1), CurrentValue);
                        AssertTrue(CurrentValue.Alpha <= NumIterations);
                    }
                    else
                    {
                        AssertAreEqual(CurrentValue, prevValue);
                    }
                }
            }
                );
            runner.AllThreadsTearDown = null;

            // (Func<T, TMapContext, T>, Func<T, T, TPredicateContext, bool>)
            runner.AllThreadsTearDown = target => {
                AssertAreEqual(NumIterations, target.Value.Alpha);
                AssertAreEqual(-1 * NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    var(wasSet, prevValue, CurrentValue) = target.TryExchange((c, ctx) => new DummyImmutableVal(c.Alpha + ctx, c.Bravo - ctx), 1, (c, n, ctx) => c.Alpha + 1 == n.Alpha && c.Bravo - 1 == n.Bravo && c.Alpha < ctx, NumIterations);
                    if (wasSet)
                    {
                        AssertAreEqual(new DummyImmutableVal(prevValue.Alpha + 1, prevValue.Bravo - 1), CurrentValue);
                        AssertTrue(CurrentValue.Alpha <= NumIterations);
                    }
                    else
                    {
                        AssertAreEqual(CurrentValue, prevValue);
                    }
                }
            }
                );
            runner.AllThreadsTearDown = null;
        }
Exemple #5
0
        public void Exchange()
        {
            const int NumIterations = 300_000;

            var atomicIntA = new AtomicInt(0);
            var atomicIntB = new AtomicInt(0);
            var runner     = NewRunner(new DummyImmutableVal(0, 0));

            // (T)
            runner.GlobalSetUp        = (_, __) => { atomicIntA.Set(0); atomicIntB.Set(0); };
            runner.AllThreadsTearDown = target => {
                AssertAreEqual(NumIterations, target.Value.Alpha);
                AssertAreEqual(NumIterations, target.Value.Bravo);
            };
            runner.ExecuteContinuousSingleWriterCoherencyTests(
                target => {
                var newA     = atomicIntA.Increment().CurrentValue;
                var newB     = atomicIntB.Increment().CurrentValue;
                var newValue = new DummyImmutableVal(newA, newB);
                var prev     = target.Exchange(newValue).PreviousValue;
                AssertAreEqual(prev.Alpha, newA - 1);
                AssertAreEqual(prev.Bravo, newB - 1);
            },
                NumIterations,
                target => target.Value,
                (prev, cur) => {
                AssertTrue(prev.Alpha <= cur.Alpha);
                AssertTrue(prev.Bravo <= cur.Bravo);
            }
                );
            runner.GlobalSetUp        = null;
            runner.AllThreadsTearDown = null;

            // (Func<T, T>)
            runner.AllThreadsTearDown = target => {
                AssertAreEqual(NumIterations, target.Value.Alpha);
                AssertAreEqual(NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                var exchRes = target.Exchange(t => new DummyImmutableVal(t.Alpha + 1, t.Bravo + 1));
                AssertAreEqual(exchRes.PreviousValue.Alpha + 1, exchRes.CurrentValue.Alpha);
                AssertAreEqual(exchRes.PreviousValue.Bravo + 1, exchRes.CurrentValue.Bravo);
            },
                NumIterations
                );
            runner.AllThreadsTearDown = null;

            // (Func<T, TContext, T>)
            runner.AllThreadsTearDown = target => {
                AssertAreEqual(NumIterations, target.Value.Alpha);
                AssertAreEqual(NumIterations * 2, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                var exchRes = target.Exchange((t, ctx) => new DummyImmutableVal(t.Alpha + 1, t.Bravo + ctx), 2);
                AssertAreEqual(exchRes.PreviousValue.Alpha + 1, exchRes.CurrentValue.Alpha);
                AssertAreEqual(exchRes.PreviousValue.Bravo + 2, exchRes.CurrentValue.Bravo);
            },
                NumIterations
                );
            runner.AllThreadsTearDown = null;
        }
        public void TryExchangeWithoutContext()
        {
            const int NumIterations = 200_000;

            var runner = NewRunner(new DummyImmutableVal(0, 0));

            // (T, T)
            runner.ExecuteContinuousCoherencyTests(
                target => {
                var curValue = target.Value;
                var newValue = new DummyImmutableVal(0, curValue.Bravo + 1);
                target.TryExchange(newValue, curValue);
            },
                NumIterations,
                target => target.Value,
                (prev, cur) => FastAssertTrue(cur.Bravo >= prev.Bravo)
                );

            // (T, Func<T, T, bool>)
            runner.AllThreadsTearDown = target => {
                FastAssertEqual(NumIterations, target.Value.Alpha);
                FastAssertEqual(-1 * NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    var newValue = new DummyImmutableVal(curValue.Alpha + 1, curValue.Bravo - 1);
                    var(wasSet, prevValue, setValue) = target.TryExchange(newValue, (c, n) => c.Alpha + 1 == n.Alpha && c.Bravo - 1 == n.Bravo);
                    if (wasSet)
                    {
                        FastAssertEqual <DummyImmutableVal>(curValue, prevValue);
                        FastAssertEqual <DummyImmutableVal>(newValue, setValue);
                    }
                    else
                    {
                        FastAssertNotEqual <DummyImmutableVal>(curValue, prevValue);
                        AssertAreEqual(setValue, prevValue);
                    }
                }
            }
                );
            runner.AllThreadsTearDown = null;

            // (Func<T, T>, T)
            runner.ExecuteFreeThreadedTests(
                target => {
                var curValue = target.Value;

                var(wasSet, prevValue, CurrentValue) = target.TryExchange(
                    c => c.Bravo < c.Alpha
                                                        ? new DummyImmutableVal(c.Alpha, c.Bravo + 1)
                                                        : new DummyImmutableVal(c.Alpha + 1, c.Bravo),
                    curValue
                    );

                if (wasSet)
                {
                    FastAssertEqual <DummyImmutableVal>(curValue, prevValue);
                    FastAssertEqual <DummyImmutableVal>(prevValue.Bravo < prevValue.Alpha ? new DummyImmutableVal(prevValue.Alpha, prevValue.Bravo + 1) : new DummyImmutableVal(prevValue.Alpha + 1, prevValue.Bravo), CurrentValue);
                }

                else
                {
                    FastAssertNotEqual <DummyImmutableVal>(curValue, prevValue);
                }
            },
                NumIterations
                );

            // (Func<T, T>, Func<T, T, bool>)
            runner.AllThreadsTearDown = target => {
                FastAssertEqual(NumIterations, target.Value.Alpha);
                FastAssertEqual(-1 * NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    var(wasSet, prevValue, CurrentValue) = target.TryExchange(c => new DummyImmutableVal(c.Alpha + 1, c.Bravo - 1), (c, n) => c.Alpha + 1 == n.Alpha && c.Bravo - 1 == n.Bravo && c.Alpha < NumIterations);
                    if (wasSet)
                    {
                        FastAssertEqual <DummyImmutableVal>(new DummyImmutableVal(prevValue.Alpha + 1, prevValue.Bravo - 1), CurrentValue);
                        FastAssertTrue(CurrentValue.Alpha <= NumIterations);
                    }
                    else
                    {
                        AssertAreEqual(prevValue, CurrentValue);
                    }
                }
            }
                );
            runner.AllThreadsTearDown = null;
        }
        public void Assert_Coherency_TrySet()
        {
            const int NumIterations = 1_000_000;

            var runner = NewRunner(new DummyImmutableVal(0, 0));

            runner.GlobalSetUp = (target, _) => target.Set(new DummyImmutableVal(0, 0));

            // bool TrySet(T newValue, Func<T, bool> setPredicate);
            runner.AllThreadsTearDown = target => {
                FastAssertEqual(NumIterations, target.Value.Alpha);
                FastAssertEqual(-NumIterations, target.Value.Bravo);
            };
            runner.ExecuteContinuousCoherencyTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    var newValue = new DummyImmutableVal(curValue.Alpha + 1, curValue.Bravo - 1);
                    target.TrySet(newValue, v => v.Alpha + 1 == newValue.Alpha && v.Bravo - 1 == newValue.Bravo);
                    FastAssertTrue(target.Value.Alpha > curValue.Alpha);
                    FastAssertTrue(target.Value.Bravo < curValue.Alpha);
                }
            },
                target => target.Value,
                (prev, cur) => {
                FastAssertTrue(cur.Alpha >= prev.Alpha);
                FastAssertTrue(cur.Bravo <= prev.Bravo);
            },
                v => v.Alpha == NumIterations
                );
            runner.AllThreadsTearDown = null;

            // bool TrySet(T newValue, Func<T, bool> setPredicate, out T previousValue);
            runner.AllThreadsTearDown = target => {
                FastAssertEqual(NumIterations, target.Value.Alpha);
                FastAssertEqual(-NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    var newValue = new DummyImmutableVal(curValue.Alpha + 1, curValue.Bravo - 1);
                    var wasSet   = target.TrySet(newValue, v => v.Alpha + 1 == newValue.Alpha && v.Bravo - 1 == newValue.Bravo, out var prevValue);
                    if (wasSet)
                    {
                        FastAssertEqual(curValue, prevValue);
                    }
                    else
                    {
                        FastAssertNotEqual(curValue, prevValue);
                    }
                }
            }
                );
            runner.AllThreadsTearDown = null;

            // bool TrySet(Func<T, T> valueMapFunc, Func<T, bool> setPredicate);
            runner.AllThreadsTearDown = target => {
                FastAssertEqual(NumIterations, target.Value.Alpha);
                FastAssertEqual(-NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    target.TrySet(v => new DummyImmutableVal(v.Alpha + 1, v.Bravo - 1), v => v == curValue);
                    FastAssertTrue(target.Value.Alpha > curValue.Alpha);
                    FastAssertTrue(target.Value.Bravo < curValue.Alpha);
                }
            }
                );
            runner.AllThreadsTearDown = null;

            // bool TrySet(Func<T, T> valueMapFunc, Func<T, bool> setPredicate, out T previousValue);
            runner.AllThreadsTearDown = target => {
                FastAssertEqual(NumIterations, target.Value.Alpha);
                FastAssertEqual(-NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    var wasSet = target.TrySet(v => new DummyImmutableVal(v.Alpha + 1, v.Bravo - 1), v => v == curValue, out var prevValue);
                    if (wasSet)
                    {
                        FastAssertEqual(curValue, prevValue);
                    }
                    else
                    {
                        FastAssertNotEqual(curValue, prevValue);
                    }
                }
            }
                );
            runner.AllThreadsTearDown = null;

            // bool TrySet(Func<T, T> valueMapFunc, Func<T, bool> setPredicate, out T previousValue, out T newValue);
            runner.AllThreadsTearDown = target => {
                FastAssertEqual(NumIterations, target.Value.Alpha);
                FastAssertEqual(-NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    var wasSet = target.TrySet(v => new DummyImmutableVal(v.Alpha + 1, v.Bravo - 1), v => v == curValue, out var prevValue, out var newValue);
                    if (wasSet)
                    {
                        FastAssertEqual(curValue, prevValue);
                        FastAssertEqual(prevValue.Alpha + 1, newValue.Alpha);
                        FastAssertEqual(prevValue.Bravo - 1, newValue.Bravo);
                    }
                    else
                    {
                        FastAssertNotEqual(curValue, prevValue);
                        FastAssertEqual(prevValue, newValue);
                    }
                }
            }
                );
            runner.AllThreadsTearDown = null;

            // bool TrySet(Func<T, T> valueMapFunc, Func<T, T, bool> setPredicate);
            runner.AllThreadsTearDown = target => {
                FastAssertEqual(NumIterations, target.Value.Alpha);
                FastAssertEqual(-NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    target.TrySet(v => new DummyImmutableVal(v.Alpha + 1, v.Bravo - 1), (c, n) => c.Alpha == curValue.Alpha && n.Bravo == c.Bravo + 1);
                    FastAssertTrue(target.Value.Alpha > curValue.Alpha);
                    FastAssertTrue(target.Value.Bravo < curValue.Alpha);
                }
            }
                );
            runner.AllThreadsTearDown = null;

            // bool TrySet(Func<T, T> valueMapFunc, Func<T, T, bool> setPredicate, out T previousValue);
            runner.AllThreadsTearDown = target => {
                FastAssertEqual(NumIterations, target.Value.Alpha);
                FastAssertEqual(-NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    var wasSet = target.TrySet(v => new DummyImmutableVal(v.Alpha + 1, v.Bravo - 1), (c, n) => c.Alpha == curValue.Alpha && n.Bravo == c.Bravo + 1, out var prevValue);
                    if (wasSet)
                    {
                        FastAssertEqual(curValue, prevValue);
                    }
                    else
                    {
                        FastAssertNotEqual(curValue, prevValue);
                    }
                }
            }
                );
            runner.AllThreadsTearDown = null;

            // bool TrySet(Func<T, T> valueMapFunc, Func<T, T, bool> setPredicate, out T previousValue, out T newValue);
            runner.AllThreadsTearDown = target => {
                FastAssertEqual(NumIterations, target.Value.Alpha);
                FastAssertEqual(-NumIterations, target.Value.Bravo);
            };
            runner.ExecuteFreeThreadedTests(
                target => {
                while (true)
                {
                    var curValue = target.Value;
                    if (curValue.Alpha == NumIterations)
                    {
                        return;
                    }
                    var wasSet = target.TrySet(v => new DummyImmutableVal(v.Alpha + 1, v.Bravo - 1), (c, n) => c.Alpha == curValue.Alpha && n.Bravo == c.Bravo + 1, out var prevValue, out var newValue);
                    if (wasSet)
                    {
                        FastAssertEqual(curValue, prevValue);
                        FastAssertEqual(prevValue.Alpha + 1, newValue.Alpha);
                        FastAssertEqual(prevValue.Bravo - 1, newValue.Bravo);
                    }
                    else
                    {
                        FastAssertNotEqual(curValue, prevValue);
                        FastAssertEqual(prevValue, newValue);
                    }
                }
            }
                );
            runner.AllThreadsTearDown = null;
        }
Exemple #8
0
 protected override bool AreEqual(DummyImmutableVal lhs, DummyImmutableVal rhs) => lhs == rhs;