From 2ce3f85d46edbf5105f2e93d2cbe56ad777b41e6 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 3 May 2020 06:23:15 -0700 Subject: [PATCH 1/2] Tweak and stabilize AtomicN::fetch_update --- src/libcore/sync/atomic.rs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 220f221cdd36..f9d31f0a7d79 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -1809,11 +1809,10 @@ Note: This may call the function multiple times if the value has been changed fr the meantime, as long as the function returns `Some(_)`, but the function will have been applied but 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(&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) { From 31c820552350e3f686a6f353982f0f31ecbaf4a7 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Sun, 3 May 2020 19:36:12 -0400 Subject: [PATCH 2/2] Update src/libcore/sync/atomic.rs Co-authored-by: Ralf Jung --- src/libcore/sync/atomic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index f9d31f0a7d79..0e0ebfa1a452 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -1807,7 +1807,7 @@ 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 when the operation finally succeeds while the second