Skip to content

Commit ea5848d

Browse files
authored
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: #48655 (comment). 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.
2 parents a08a03c + 31c8205 commit ea5848d

File tree

1 file changed

+11
-15
lines changed

1 file changed

+11
-15
lines changed

src/libcore/sync/atomic.rs

+11-15
Original file line numberDiff line numberDiff line change
@@ -1807,13 +1807,12 @@ new value. Returns a `Result` of `Ok(previous_value)` if the function returned `
18071807
18081808
Note: This may call the function multiple times if the value has been changed from other threads in
18091809
the meantime, as long as the function returns `Some(_)`, but the function will have been applied
1810-
but once to the stored value.
1810+
only once to the stored value.
18111811
1812-
`fetch_update` takes two [`Ordering`] arguments to describe the memory
1813-
ordering of this operation. The first describes the required ordering for loads
1814-
and failed updates while the second describes the required ordering when the
1815-
operation finally succeeds. Beware that this is different from the two
1816-
modes in [`compare_exchange`]!
1812+
`fetch_update` takes two [`Ordering`] arguments to describe the memory ordering of this operation.
1813+
The first describes the required ordering for when the operation finally succeeds while the second
1814+
describes the required ordering for loads. These correspond to the success and failure orderings of
1815+
[`compare_exchange`] respectively.
18171816
18181817
Using [`Acquire`] as success ordering makes the store part
18191818
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.
18311830
# Examples
18321831
18331832
```rust
1834-
#![feature(no_more_cas)]
18351833
", $extra_feature, "use std::sync::atomic::{", stringify!($atomic_type), ", Ordering};
18361834
18371835
let x = ", stringify!($atomic_type), "::new(7);
1838-
assert_eq!(x.fetch_update(|_| None, Ordering::SeqCst, Ordering::SeqCst), Err(7));
1839-
assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(7));
1840-
assert_eq!(x.fetch_update(|x| Some(x + 1), Ordering::SeqCst, Ordering::SeqCst), Ok(8));
1836+
assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |_| None), Err(7));
1837+
assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(7));
1838+
assert_eq!(x.fetch_update(Ordering::SeqCst, Ordering::SeqCst, |x| Some(x + 1)), Ok(8));
18411839
assert_eq!(x.load(Ordering::SeqCst), 9);
18421840
```"),
18431841
#[inline]
1844-
#[unstable(feature = "no_more_cas",
1845-
reason = "no more CAS loops in user code",
1846-
issue = "48655")]
1842+
#[stable(feature = "no_more_cas", since = "1.45.0")]
18471843
#[$cfg_cas]
18481844
pub fn fetch_update<F>(&self,
1849-
mut f: F,
1845+
set_order: Ordering,
18501846
fetch_order: Ordering,
1851-
set_order: Ordering) -> Result<$int_type, $int_type>
1847+
mut f: F) -> Result<$int_type, $int_type>
18521848
where F: FnMut($int_type) -> Option<$int_type> {
18531849
let mut prev = self.load(fetch_order);
18541850
while let Some(next) = f(prev) {

0 commit comments

Comments
 (0)