@@ -3102,37 +3102,25 @@ macro_rules! atomic_int {
3102
3102
unsafe { atomic_xor( self . v. get( ) , val, order) }
3103
3103
}
3104
3104
3105
- /// Fetches the value, and applies a function to it that returns an optional
3106
- /// new value. Returns a `Result` of `Ok(previous_value)` if the function returned `Some(_)`, else
3107
- /// `Err(previous_value)`.
3108
- ///
3109
- /// Note: This may call the function multiple times if the value has been changed from other threads in
3110
- /// the meantime, as long as the function returns `Some(_)`, but the function will have been applied
3111
- /// only once to the stored value.
3112
- ///
3113
- /// `fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
3114
- /// The first describes the required ordering for when the operation finally succeeds while the second
3115
- /// describes the required ordering for loads. These correspond to the success and failure orderings of
3116
- #[ doc = concat!( "[`" , stringify!( $atomic_type) , "::compare_exchange`]" ) ]
3117
- /// respectively.
3118
- ///
3119
- /// Using [`Acquire`] as success ordering makes the store part
3120
- /// of this operation [`Relaxed`], and using [`Release`] makes the final successful load
3121
- /// [`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`].
3105
+ /// Loads the current value, applies a closure to it, and optionally tries to store a new value.
3106
+ /// If the closure ever returns None, this method will immediately return `Err(current value)`.
3107
+ /// If the closure returns Some(new value), then this method calls
3108
+ #[ doc = concat!( "[`" , stringify!( $atomic_type) , "::compare_exchange_weak`]" ) ]
3109
+ /// to try to store the new value.
3110
+ /// If storing a new value fails, because another thread changed the current value,
3111
+ /// then the given closure will be called again on the new current value
3112
+ /// (that was just returned by compare_exchange_weak),
3113
+ /// until either the closure returns None,
3114
+ /// or compare_exchange_weak succeeds in storing a new value.
3115
+ /// Returns `Ok(previous value)` if it ever succeeds in storing a new value.
3116
+ /// Takes a success and a failure [`Ordering`] to pass on to compare_exchange_weak,
3117
+ /// and also uses the failure ordering for the initial load.
3118
+ ///
3119
+ /// Note: susceptible to the [ABA Problem](https://en.wikipedia.org/wiki/ABA_problem).
3122
3120
///
3123
3121
/// **Note**: This method is only available on platforms that support atomic operations on
3124
3122
#[ doc = concat!( "[`" , $s_int_type, "`]." ) ]
3125
3123
///
3126
- /// # Considerations
3127
- ///
3128
- /// This method is not magic; it is not provided by the hardware.
3129
- /// It is implemented in terms of
3130
- #[ doc = concat!( "[`" , stringify!( $atomic_type) , "::compare_exchange_weak`]," ) ]
3131
- /// and suffers from the same drawbacks.
3132
- /// In particular, this method will not circumvent the [ABA Problem].
3133
- ///
3134
- /// [ABA Problem]: https://en.wikipedia.org/wiki/ABA_problem
3135
- ///
3136
3124
/// # Examples
3137
3125
///
3138
3126
/// ```rust
@@ -3149,13 +3137,13 @@ macro_rules! atomic_int {
3149
3137
#[ $cfg_cas]
3150
3138
#[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
3151
3139
pub fn fetch_update<F >( & self ,
3152
- set_order : Ordering ,
3153
- fetch_order : Ordering ,
3140
+ success : Ordering ,
3141
+ failure : Ordering ,
3154
3142
mut f: F ) -> Result <$int_type, $int_type>
3155
3143
where F : FnMut ( $int_type) -> Option <$int_type> {
3156
- let mut prev = self . load( fetch_order ) ;
3144
+ let mut prev = self . load( failure ) ;
3157
3145
while let Some ( next) = f( prev) {
3158
- match self . compare_exchange_weak( prev, next, set_order , fetch_order ) {
3146
+ match self . compare_exchange_weak( prev, next, success , failure ) {
3159
3147
x @ Ok ( _) => return x,
3160
3148
Err ( next_prev) => prev = next_prev
3161
3149
}
0 commit comments