/// <summary> /// Atomically sets the value of the stamp 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="newStamp"> /// The new value for the stamp /// </param> /// <returns> /// True if successful /// </returns> public virtual bool AttemptStamp(T expectedValue, int newStamp) { ValueIntegerPair current = Pair; return(AreEqual(expectedValue, current.Value) && (newStamp == current.Integer || _atomicReference.CompareAndSet(current, new ValueIntegerPair(expectedValue, newStamp)))); }
/// <summary> /// Atomically sets both the value and stamp to the given update values /// if the current value and the expected value <see cref="AreEqual"/> /// and the current stamp is equal to the expected stamp. /// </summary> /// <param name="expectedValue"> /// The expected value /// </param> /// <param name="newValue"> /// The new value /// </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 expectedValue, T newValue, int expectedStamp, int newStamp) { ValueIntegerPair current = Pair; return(AreEqual(expectedValue, current.Value) && expectedStamp == current.Integer && ((newValue.Equals(current.Value) && newStamp == current.Integer) || _atomicReference.WeakCompareAndSet(current, new ValueIntegerPair(newValue, newStamp)))); }
/// <summary> /// Returns both the current value and the stamp. /// Typical usage is: /// <code> /// int stamp; /// object value = v.GetValue(out stamp); /// </code> /// </summary> /// <param name="stamp"> /// 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 /// </returns> public T GetValue(out int stamp) { ValueIntegerPair p = Pair; stamp = p.Integer; return(p.Value); }
/// <summary> /// Unconditionally sets both the value and stamp 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="newStamp"> /// The new value for the stamp /// </param> public void SetNewAtomicValue(T newValue, int newStamp) { ValueIntegerPair current = Pair; if (!AreEqual(newValue, current.Value) || newStamp != current.Integer) { _atomicReference.Value = new ValueIntegerPair(newValue, newStamp); } }