public void CreateContextualFuncsContext() { _contextualFuncsBarrier = new ManualResetEvent(false); _contextualFuncsThreads = new List <Thread>(); _contextualFuncsUser = new AtomicRef <User>(new User(0, "")); _contextualFuncsLong = new AtomicLong(0L); BenchmarkUtils.PrepareThreads(NumThreads, _contextualFuncsBarrier, WithContextualFuncs_Entry, _contextualFuncsThreads); }
public void CreateManualLoopsContext() { _manualLoopsBarrier = new ManualResetEvent(false); _manualLoopsThreads = new List <Thread>(); _manualLoopsUser = new AtomicRef <User>(new User(0, "")); _manualLoopsLong = new AtomicLong(0L); BenchmarkUtils.PrepareThreads(NumThreads, _manualLoopsBarrier, WithManualLoops_Entry, _manualLoopsThreads); }
public void CreateAtomicRefContext() { _atomicUser = new AtomicRef <User>(new User(0, _usernames[0])); _atomicRefBarrier = new ManualResetEvent(false); _atomicRefThreads = new List <Thread>(); BenchmarkUtils.PrepareThreads(NumWriters, _atomicRefBarrier, WithAtomicRef_WriterEntry, _atomicRefThreads); BenchmarkUtils.PrepareThreads(NumReaders, _atomicRefBarrier, WithAtomicRef_ReaderEntry, _atomicRefThreads); }
public void CreateTupleReturnsContext() { _atomicLong = new AtomicLong(0L); _atomicInt = new AtomicInt(0); _atomicRef = new AtomicRef <User>(new User(0, "")); _atomicVal8 = new AtomicVal <Val8>(new Val8(0L)); _atomicVal16 = new AtomicVal <Val16>(new Val16(0L)); _atomicVal32 = new AtomicVal <Val32>(new Val32(0L)); _atomicVal64 = new AtomicVal <Val64>(new Val64(0L)); }
public void ShouldCreateNewContextObjectForEachTestCase() { _runner.ContextFactoryFunc = () => new DummyImmutableRef(); var lastSetContextObject = new AtomicRef <DummyImmutableRef>(null); var testCase = CreateNewTestCase(ctx => lastSetContextObject.Set(ctx)); _runner.ExecuteCustomTestCase(testCase); var firstContextObj = lastSetContextObject.Value; _runner.ExecuteCustomTestCase(testCase); Assert.AreNotEqual(firstContextObj, lastSetContextObject.Value); }
public void FastTryExchangeRefOnly() { const int NumIterations = 100_000; var runner = _equatableRefRunnerFactory.NewRunner(new DummyEquatableRef(0L)); // Test: Return value of method is always consistent runner.ExecuteFreeThreadedTests( atomicRef => { var curValue = atomicRef.Value; var newValue = new DummyEquatableRef(curValue.LongProp + 1L); var prevValue = atomicRef.FastTryExchangeRefOnly(newValue, curValue); var wasSet = ReferenceEquals(prevValue, curValue); var setValue = wasSet ? newValue : prevValue; if (wasSet) { Assert.True(ReferenceEquals(curValue, prevValue)); Assert.True(ReferenceEquals(newValue, setValue)); } else { Assert.False(ReferenceEquals(curValue, prevValue)); Assert.True(ReferenceEquals(setValue, prevValue)); } }, NumIterations ); // Test: Method does what is expected and is safe from race conditions runner.AllThreadsTearDown = atomicRef => Assert.AreEqual(NumIterations, atomicRef.Value.LongProp); runner.ExecuteFreeThreadedTests( atomicRef => { while (true) { var curValue = atomicRef.Value; if (curValue.LongProp == NumIterations) { return; } var newValue = new DummyEquatableRef(curValue.LongProp + 1L); var prevValue = atomicRef.FastTryExchangeRefOnly(newValue, curValue); var wasSet = ReferenceEquals(prevValue, curValue); var setValue = wasSet ? newValue : prevValue; if (wasSet) { Assert.True(ReferenceEquals(curValue, prevValue)); Assert.True(ReferenceEquals(newValue, setValue)); } else { Assert.False(ReferenceEquals(curValue, prevValue)); Assert.True(ReferenceEquals(setValue, prevValue)); } } } ); runner.AllThreadsTearDown = null; // Test: Method always exhibits coherency for consecutive reads from external threads runner.ExecuteContinuousCoherencyTests( atomicRef => { var curValue = atomicRef.Value; var newValue = new DummyEquatableRef(curValue.LongProp + 1L); atomicRef.FastTryExchangeRefOnly(newValue, curValue); }, NumIterations, atomicRef => atomicRef.Value, (prev, cur) => Assert.True(cur.LongProp >= prev.LongProp) ); // Test: Custom equality is used for types that provide it var dummyImmutableA = new DummyImmutableRef("Xenoprimate Rules"); var dummyImmutableB = new DummyImmutableRef("Xenoprimate Rules"); var dummyEquatableA = new DummyEquatableRef("Xenoprimate Rules"); var dummyEquatableB = new DummyEquatableRef("Xenoprimate Rules"); var atomicImmutable = new AtomicRef <DummyImmutableRef>(); var atomicEquatable = new AtomicRef <DummyEquatableRef>(); atomicImmutable.Set(dummyImmutableA); atomicImmutable.FastTryExchangeRefOnly(new DummyImmutableRef(), dummyImmutableB); Assert.AreEqual(dummyImmutableA, atomicImmutable.Value); atomicEquatable.Set(dummyEquatableA); var newVal = new DummyEquatableRef(); atomicEquatable.FastTryExchangeRefOnly(newVal, dummyEquatableB); Assert.AreEqual(dummyEquatableA, atomicEquatable.Value); }
public void EquatableMappedTryExchange() { const int NumIterations = 100_000; var equatableRunner = _equatableRefRunnerFactory.NewRunner(new DummyEquatableRef(0L)); // Test: Return value of method is always consistent equatableRunner.ExecuteFreeThreadedTests( atomicRef => { var curValue = atomicRef.Value; var(wasSet, prevValue, CurrentValue) = atomicRef.TryExchange(c => new DummyEquatableRef(c.LongProp + 1L), curValue); if (wasSet) { Assert.AreEqual(curValue, prevValue); Assert.AreEqual(new DummyEquatableRef(prevValue.LongProp + 1L), CurrentValue); } else { Assert.AreNotEqual(curValue, prevValue); } }, NumIterations ); // Test: Method does what is expected and is safe from race conditions equatableRunner.AllThreadsTearDown = atomicRef => Assert.AreEqual(NumIterations, atomicRef.Value.LongProp); equatableRunner.ExecuteFreeThreadedTests( atomicRef => { while (true) { var curValue = atomicRef.Value; if (curValue.LongProp == NumIterations) { return; } var(wasSet, prevValue, CurrentValue) = atomicRef.TryExchange(c => new DummyEquatableRef(c.LongProp + 1L), curValue); if (wasSet) { Assert.AreEqual(curValue, prevValue); Assert.AreEqual(new DummyEquatableRef(prevValue.LongProp + 1L), CurrentValue); } else { Assert.AreNotEqual(curValue, prevValue); } } } ); equatableRunner.AllThreadsTearDown = null; // Test: Method always exhibits coherency for consecutive reads from external threads equatableRunner.ExecuteContinuousCoherencyTests( atomicRef => { var curValue = atomicRef.Value; atomicRef.TryExchange(c => new DummyEquatableRef(c.LongProp + 1L), curValue); }, NumIterations, atomicRef => atomicRef.Value, (prev, cur) => Assert.True(cur.LongProp >= prev.LongProp) ); // Test: Custom equality is used for types that provide it var dummyImmutableA = new DummyImmutableRef("Xenoprimate Rules"); var dummyImmutableB = new DummyImmutableRef("Xenoprimate Rules"); var dummyEquatableA = new DummyEquatableRef("Xenoprimate Rules"); var dummyEquatableB = new DummyEquatableRef("Xenoprimate Rules"); var atomicImmutable = new AtomicRef <DummyImmutableRef>(); var atomicEquatable = new AtomicRef <DummyEquatableRef>(); atomicImmutable.Set(dummyImmutableA); Assert.AreEqual(false, atomicImmutable.TryExchange(c => new DummyImmutableRef(), dummyImmutableB).ValueWasSet); atomicEquatable.Set(dummyEquatableA); Assert.AreEqual(true, atomicEquatable.TryExchange(c => new DummyEquatableRef(), dummyEquatableB).ValueWasSet); }
public void API_CombineRemoveRemoveAll() { var lastRecordedInput = new AtomicRef <string>(); Func <string, string> initialValue = s => { lastRecordedInput.Set(s); return(s.ToUpper()); }; var target = new AtomicDelegate <Func <string, string> >(initialValue); var combineRes = target.Combine(s => s.ToLower()); Assert.AreEqual(initialValue, combineRes.PreviousValue); Assert.AreEqual("TEST", combineRes.PreviousValue("Test")); Assert.AreEqual("test", combineRes.CurrentValue("Test")); Assert.AreEqual("Test", lastRecordedInput.Value); target.TryInvoke("Input"); Assert.AreEqual("Input", lastRecordedInput.Value); combineRes = target.Combine(s => s + s); Assert.AreEqual("abcabc", target.Value("abc")); Assert.AreEqual("abc", lastRecordedInput.Value); Assert.AreEqual(combineRes.CurrentValue, target.Value); var removeRes = target.Remove(initialValue); Assert.AreEqual("qwertyqwerty", removeRes.PreviousValue("qwerty")); Assert.AreEqual("qwerty", lastRecordedInput.Value); Assert.AreEqual("ijklijkl", removeRes.CurrentValue("ijkl")); Assert.AreEqual("qwerty", lastRecordedInput.Value); Assert.AreEqual(removeRes.CurrentValue, target.Value); removeRes = target.Remove(c => "this delegate was never added"); Assert.AreEqual(removeRes.CurrentValue, removeRes.PreviousValue); Assert.AreEqual(target.Value, removeRes.PreviousValue); var invocationCounter = new AtomicInt(); Func <string, string> CurrentValue = s => { invocationCounter.Increment(); return(s[0].ToString()); }; target.Combine(CurrentValue); target.Combine(CurrentValue); target.Combine(CurrentValue); Assert.AreEqual((true, "r"), target.TryInvoke("rrrrr")); Assert.AreEqual(3, invocationCounter.Value); target.Remove(CurrentValue); Assert.AreEqual((true, "r"), target.TryInvoke("rrrrr")); Assert.AreEqual(5, invocationCounter.Value); removeRes = target.RemoveAll(CurrentValue); Assert.AreEqual((true, "rrrrrrrrrr"), target.TryInvoke("rrrrr")); Assert.AreEqual(5, invocationCounter.Value); Assert.AreEqual("rrrrrrrrrr", removeRes.CurrentValue("rrrrr")); Assert.AreEqual("r", removeRes.PreviousValue("rrrrr")); removeRes = target.RemoveAll(CurrentValue); Assert.AreEqual((true, "rrrrrrrrrr"), target.TryInvoke("rrrrr")); Assert.AreEqual(7, invocationCounter.Value); Assert.AreEqual("rrrrrrrrrr", removeRes.CurrentValue("rrrrr")); Assert.AreEqual(removeRes.CurrentValue, removeRes.PreviousValue); }