@@ -2852,37 +2852,25 @@ macro_rules! atomic_int {
2852
2852
unsafe { atomic_xor( self . v. get( ) , val, order) }
2853
2853
}
2854
2854
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`]" ) ]
2859
+ /// to try to store the new value.
2860
+ /// If storing a new value fails, because another thread changed the current value,
2861
+ /// then the given closure will be called again on the new current value
2862
+ /// (that was just returned by compare_exchange_weak),
2863
+ /// until either the closure returns None,
2864
+ /// or compare_exchange_weak succeeds in storing a new value.
2865
+ /// Returns `Ok(previous value)` if it ever succeeds in storing a new value.
2866
+ /// Takes a success and a failure [`Ordering`] to pass on to compare_exchange_weak,
2867
+ /// and also uses the failure ordering for the initial load.
2868
+ ///
2869
+ /// Note: susceptible to the [ABA Problem](https://en.wikipedia.org/wiki/ABA_problem).
2872
2870
///
2873
2871
/// **Note**: This method is only available on platforms that support atomic operations on
2874
2872
#[ doc = concat!( "[`" , $s_int_type, "`]." ) ]
2875
2873
///
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
- ///
2886
2874
/// # Examples
2887
2875
///
2888
2876
/// ```rust
@@ -2899,13 +2887,13 @@ macro_rules! atomic_int {
2899
2887
#[ $cfg_cas]
2900
2888
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
2901
2889
pub fn fetch_update<F >( & self ,
2902
- set_order : Ordering ,
2903
- fetch_order : Ordering ,
2890
+ success : Ordering ,
2891
+ failure : Ordering ,
2904
2892
mut f: F ) -> Result <$int_type, $int_type>
2905
2893
where F : FnMut ( $int_type) -> Option <$int_type> {
2906
- let mut prev = self . load( fetch_order ) ;
2894
+ let mut prev = self . load( failure ) ;
2907
2895
while let Some ( next) = f( prev) {
2908
- match self . compare_exchange_weak( prev, next, set_order , fetch_order ) {
2896
+ match self . compare_exchange_weak( prev, next, success , failure ) {
2909
2897
x @ Ok ( _) => return x,
2910
2898
Err ( next_prev) => prev = next_prev
2911
2899
}
0 commit comments