/// <summary> /// Atomically sets the value of the stamp 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="newStamp"> /// The new value for the stamp /// </param> /// <returns> /// True if successful /// </returns> public virtual bool AttemptStamp(T expectedReference, int newStamp) { ReferenceIntegerPair <T> current = Pair; return(expectedReference.Equals(current.Reference) && (newStamp == current.Integer || _atomicReference.CompareAndSet(current, new ReferenceIntegerPair <T>(expectedReference, newStamp)))); }
/// <summary> /// Atomically sets the value of both the reference and stamp /// to the given update values if the /// current reference is equal to the expected reference /// and the current stamp is equal to the expected stamp. /// </summary> /// <param name="expectedReference"> /// The expected value of the reference /// </param> /// <param name="newReference"> /// The new value for the reference /// </param> /// <param name="expectedStamp"> /// The expected value of the stamp /// </param> /// <param name="newStamp"> /// The new value for the stamp /// </param> /// <returns> /// True if successful, false otherwise. /// </returns> public virtual bool CompareAndSet(T expectedReference, T newReference, int expectedStamp, int newStamp) { ReferenceIntegerPair <T> current = Pair; return(expectedReference.Equals(current.Reference) && expectedStamp == current.Integer && ((newReference.Equals(current.Reference) && newStamp == current.Integer) || _atomicReference.WeakCompareAndSet(current, new ReferenceIntegerPair <T>(newReference, newStamp)))); }
/// <summary> /// Returns the current values of both the reference and the stamp. /// Typical usage is: /// <code> /// int[1] holder; /// object reference = v.GetobjectReference(holder); /// </code> /// </summary> /// <param name="stampHolder"> /// An array of size of at least one. On return, /// <tt>stampholder[0]</tt> will hold the value of the stamp. /// </param> /// <returns> /// The current value of the reference /// </returns> public T GetObjectReference(int[] stampHolder) { ReferenceIntegerPair <T> p = Pair; stampHolder[0] = p.Integer; return(p.Reference); }
/// <summary> /// Unconditionally sets the value of both the reference and stamp. /// </summary> /// <param name="newReference"> /// The new value for the reference /// </param> /// <param name="newStamp"> /// The new value for the stamp /// </param> public void SetNewAtomicValue(T newReference, int newStamp) { ReferenceIntegerPair <T> current = Pair; if (!newReference.Equals(current.Reference) || newStamp != current.Integer) { _atomicReference.Reference = new ReferenceIntegerPair <T>(newReference, newStamp); } }