/// <summary> /// Atomically sets the value of the mark to the given update value /// if the current reference is equal to the expected /// reference. 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="expectedReference"> /// The expected value of the reference /// </param> /// <param name="newMark"> /// The new value for the mark /// </param> /// <returns> /// <see lang="true"/> if successful, <see lang="false"/> otherwise /// </returns> public bool AttemptMark(T expectedReference, bool newMark) { ReferenceBooleanPair <T> current = Pair; return(expectedReference.Equals(current.Reference) && (newMark == current.MarkBit || _atomicReference.CompareAndSet(current, new ReferenceBooleanPair <T>(expectedReference, newMark)))); }
/// <summary> /// Atomically sets the value of both the reference and mark /// to the given update values if the /// current reference is equal to <paramref name="expectedReference"/> /// and the current mark is equal to the <paramref name="expectedMark"/>. /// </summary> /// <param name="expectedReference"> /// The expected value of the reference /// </param> /// <param name="newReference"> /// The new value for the reference /// </param> /// <param name="expectedMark"> /// The expected value of the mark /// </param> /// <param name="newMark"> /// The new value for the mark /// </param> /// <returns> /// <see lang="true"/> if successful, <see lang="false"/> otherwise /// </returns> public bool CompareAndSet(T expectedReference, T newReference, bool expectedMark, bool newMark) { ReferenceBooleanPair <T> current = Pair; return(expectedReference.Equals(current.Reference) && expectedMark == current.MarkBit && ((newReference.Equals(current.Reference) && newMark == current.MarkBit) || _atomicReference.CompareAndSet(current, new ReferenceBooleanPair <T>(newReference, newMark)))); }
/// <summary> /// Returns the current values of both the reference and the mark. /// Typical usage is: /// <code> /// bool[1] holder; /// object reference = v.GetobjectReference(holder); /// </code> /// </summary> /// <param name="markHolder"> /// An array of size of at least one. On return, /// markholder[0] will hold the value of the mark. /// </param> /// <returns> /// The current value of the reference /// </returns> public T GetReference(ref bool[] markHolder) { ReferenceBooleanPair <T> p = Pair; markHolder[0] = p.MarkBit; return(p.Reference); }
/// <summary> /// Unconditionally sets the value of both the reference and mark. /// </summary> /// <param name="newReference">the new value for the reference /// </param> /// <param name="newMark">the new value for the mark /// </param> public void SetNewAtomicValue(T newReference, bool newMark) { ReferenceBooleanPair <T> current = Pair; if (!newReference.Equals(current.Reference) || newMark != current.MarkBit) { _atomicReference.SetNewAtomicValue(new ReferenceBooleanPair <T>(newReference, newMark)); } }