about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2020-05-29 15:06:53 +0900
committerGitHub <noreply@github.com>2020-05-29 15:06:53 +0900
commitea5848df4b6150a5d308af643968d54bb510ac03 (patch)
tree5c90f9d573530abfa6e6b8fd511009026ef1baf0 /src/libcore
parenta08a03ced7909d2a8d6e6df1005b6acda7f10bf4 (diff)
parent31c820552350e3f686a6f353982f0f31ecbaf4a7 (diff)
Rollup merge of #71843 - sfackler:cas-loop-cleanup, r=dtolnay
Tweak and stabilize AtomicN::fetch_update

The fetch_update method implements a compare-and-swap loop to update the value in an atomic to an arbitrary value computed by a closure.

I've applied a few tweaks suggested by @mystor in this comment on the tracking issue: https://github.com/rust-lang/rust/issues/48655#issuecomment-496036553. Specifically, the load and store ordering arguments have been swapped to match with the orderings of `compare_exchange`, and the closure has been moved from the first to last argument.

Moving the closure to the last argument is a change away from other methods on the atomic types which place the ordering(s) last, but matches with the broad convention that closure arguments come last in functions. In particular, rustfmt style lays calls with multi-line closures out more cleanly when the closure comes last.
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/sync/atomic.rs26
1 files changed, 11 insertions, 15 deletions
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 220f221cdd3..0e0ebfa1a45 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -1807,13 +1807,12 @@ new value. Returns a `Result` of `Ok(previous_value)` if the function returned `
 
 Note: This may call the function multiple times if the value has been changed from other threads in
 the meantime, as long as the function returns `Some(_)`, but the function will have been applied
-but once to the stored value.
+only once to the stored value.
 
-`fetch_update` takes two [`Ordering`] arguments to describe the memory
-ordering of this operation. The first describes the required ordering for loads
-and failed updates while the second describes the required ordering when the
-operation finally succeeds. Beware that this is different from the two
-modes in [`compare_exchange`]!
+`fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
+The first describes the required ordering for when the operation finally succeeds while the second
+describes the required ordering for loads. These correspond to the success and failure orderings of
+[`compare_exchange`] respectively.
 
 Using [`Acquire`] as success ordering makes the store part
 of this operation [`Relaxed`], and using [`Release`] makes the final successful load
@@ -1831,24 +1830,21 @@ and must be equivalent to or weaker than the success ordering.
 # Examples
 
 ```rust
-#![feature(no_more_cas)]
 ", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
 
 let x = ", stringify!($atomic_type), "::new(7);
-assert_eq!(x.fetch_update(|_| None, Ordering::SeqCst, Ordering::SeqCst), Err(7));
-assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(7));
-assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(8));
+assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
+assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
+assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
 assert_eq!(x.load(Ordering::SeqCst), 9);
 ```"),
                 #[inline]
-                #[unstable(feature = "no_more_cas",
-                       reason = "no more CAS loops in user code",
-                       issue = "48655")]
+                #[stable(feature = "no_more_cas", since = "1.45.0")]
                 #[$cfg_cas]
                 pub fn fetch_update<F>(&self,
-                                       mut f: F,
+                                       set_order: Ordering,
                                        fetch_order: Ordering,
-                                       set_order: Ordering) -> Result<$int_type, $int_type>
+                                       mut f: F) -> Result<$int_type, $int_type>
                 where F: FnMut($int_type) -> Option<$int_type> {
                     let mut prev = self.load(fetch_order);
                     while let Some(next) = f(prev) {