@@ -2852,37 +2852,22 @@ macro_rules! atomic_int {
28522852 unsafe { atomic_xor( self . v. get( ) , val, order) }
28532853 }
28542854
2855- /// Fetches the value, and applies a function to it that returns an optional
2856- /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
2857- /// `Err(previous_value)`.
2858- ///
2859- /// Note: This may call the function multiple times if the value has been changed from other threads in
2860- /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
2861- /// only once to the stored value.
2862- ///
2863- /// `fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
2864- /// The first describes the required ordering for when the operation finally succeeds while the second
2865- /// describes the required ordering for loads. These correspond to the success and failure orderings of
2866- #[ doc = concat!( "[`" , stringify!( $atomic_type) , "::compare_exchange`]" ) ]
2867- /// respectively.
2868- ///
2869- /// Using [`Acquire`] as success ordering makes the store part
2870- /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
2871- /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
2855+ /// Loads the current value, applies a closure to it, and optionally tries to store a new value.
2856+ /// If the closure ever returns None, this method will immediately return `Err(current value)`.
2857+ /// If the closure returns Some(new value), then this method calls
2858+ /// #[doc = concat!("[`", stringify!($atomic_type), "::compare_exchange_weak`]")] to try to store the new value.
2859+ /// If storing a new value fails, because another thread changed the current value,
2860+ /// then the given closure will be called again on the new current value (that was just returned by compare_exchange_weak),
2861+ /// until either the closure returns None or compare_exchange_weak succeeds in storing a new value.
2862+ /// Returns `Ok(previous value)` if it ever succeeds in storing a new value.
2863+ /// Takes a success and a failure [`Ordering`] to pass on to compare_exchange_weak,
2864+ /// and also uses the failure ordering for the initial load.
2865+ ///
2866+ /// Note: susceptible to the [ABA Problem](https://en.wikipedia.org/wiki/ABA_problem).
28722867 ///
28732868 /// **Note**: This method is only available on platforms that support atomic operations on
28742869 #[ doc = concat!( "[`" , $s_int_type, "`]." ) ]
28752870 ///
2876- /// # Considerations
2877- ///
2878- /// This method is not magic; it is not provided by the hardware.
2879- /// It is implemented in terms of
2880- #[ doc = concat!( "[`" , stringify!( $atomic_type) , "::compare_exchange_weak`]," ) ]
2881- /// and suffers from the same drawbacks.
2882- /// In particular, this method will not circumvent the [ABA Problem].
2883- ///
2884- /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
2885- ///
28862871 /// # Examples
28872872 ///
28882873 /// ```rust
@@ -2899,13 +2884,13 @@ macro_rules! atomic_int {
28992884 #[ $cfg_cas]
29002885 #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
29012886 pub fn fetch_update<F >( & self ,
2902- set_order : Ordering ,
2903- fetch_order : Ordering ,
2887+ success : Ordering ,
2888+ failure : Ordering ,
29042889 mut f: F ) -> Result <$int_type, $int_type>
29052890 where F : FnMut ( $int_type) -> Option <$int_type> {
2906- let mut prev = self . load( fetch_order ) ;
2891+ let mut prev = self . load( failure ) ;
29072892 while let Some ( next) = f( prev) {
2908- match self . compare_exchange_weak( prev, next, set_order , fetch_order ) {
2893+ match self . compare_exchange_weak( prev, next, success , failure ) {
29092894 x @ Ok ( _) => return x,
29102895 Err ( next_prev) => prev = next_prev
29112896 }
0 commit comments