/// <summary> /// Atomically sets the value of the mark to the given update value /// if the current value and the expected value <see cref="AreEqual"/>. /// Any given invocation of this operation may fail /// (return false) spuriously, but repeated invocation /// when the current value holds the expected value and no other /// thread is also attempting to set the value will eventually /// succeed. /// </summary> /// <param name="expectedValue"> /// The expected value /// </param> /// <param name="newMark"> /// The new value for the mark /// </param> /// <returns> /// <c>true</c> if successful, <c>false</c> otherwise /// </returns> public bool AttemptMark(T expectedValue, bool newMark) { ValueBooleanPair current = Pair; return(AreEqual(expectedValue, current._value) && (newMark == current._markBit || _atomicReference.CompareAndSet(current, new ValueBooleanPair(expectedValue, newMark)))); }
/// <summary> /// Atomically sets both the value and mark to the given update values if the /// current value and <paramref name="expectedValue"/> <see cref="AreEqual"/> /// and the current mark is equal to the <paramref name="expectedMark"/>. /// </summary> /// <param name="expectedValue"> /// The expected value /// </param> /// <param name="newValue"> /// The new value /// </param> /// <param name="expectedMark"> /// The expected value of the mark /// </param> /// <param name="newMark"> /// The new value for the mark /// </param> /// <returns> /// <c>true</c> if successful, <c>false</c> otherwise /// </returns> public bool CompareAndSet(T expectedValue, T newValue, bool expectedMark, bool newMark) { ValueBooleanPair current = Pair; return(AreEqual(expectedValue, current._value) && expectedMark == current._markBit && ((AreEqual(newValue, current._value) && newMark == current._markBit) || _atomicReference.CompareAndSet(current, new ValueBooleanPair(newValue, newMark)))); }
/// <summary> /// Returns both the current value and the current mark. /// Typical usage is: /// <code> /// bool isMarked; /// var reference = v.GetValue(out isMarked); /// </code> /// </summary> /// <param name="isMarked"> /// return the value of the mark. /// </param> /// <returns> /// The current value. /// </returns> public T GetValue(out bool isMarked) { ValueBooleanPair p = Pair; isMarked = p._markBit; return(p._value); }
/// <summary> /// Unconditionally sets both the value and mark if any of them are /// not equal. Method <see cref="AreEqual"/> is used to compare the /// value. /// </summary> /// <param name="newValue">the new value /// </param> /// <param name="newMark">the new value for the mark /// </param> public void SetNewAtomicValue(T newValue, bool newMark) { ValueBooleanPair current = Pair; if (!AreEqual(newValue, current._value) || newMark != current._markBit) { _atomicReference.Exchange(new ValueBooleanPair(newValue, newMark)); } }