From 621d06481d508facae89d6404792db57e9a837f5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 6 Aug 2018 12:05:59 +0200 Subject: [PATCH 1/5] atomic ordering docs --- src/libcore/sync/atomic.rs | 59 +++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index e98194c17c885..41e6376ff8c05 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -193,32 +193,67 @@ pub enum Ordering { /// [`Monotonic`]: http://llvm.org/docs/Atomics.html#monotonic #[stable(feature = "rust1", since = "1.0.0")] Relaxed, - /// When coupled with a store, all previous writes become visible - /// to the other threads that perform a load with [`Acquire`] ordering - /// on the same value. + /// When coupled with a store, all previous operations become ordered + /// before any load of this value with [`Acquire`] (or stronger) ordering. + /// In particular, all previous writes become visible to all threads + /// that perform an [`Acquire`] (or stronger) load of this value. /// + /// Notice that using this ordering for an operation that combines loads + /// and stores leads to a [`Relaxed`] load operation! + /// + /// This ordering is only applicable for operations that can perform a store. + /// + /// Corresponds to LLVM's [`Release`] ordering. + /// + /// [`Release`]: http://llvm.org/docs/Atomics.html#release /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire + /// [`Relaxed`]: https://llvm.org/docs/Atomics.html#monotonic #[stable(feature = "rust1", since = "1.0.0")] Release, - /// When coupled with a load, all subsequent loads will see data - /// written before a store with [`Release`] ordering on the same value - /// in other threads. + /// When coupled with a load, if the loaded value was written by a store operation with + /// [`Release`] (or stronger) ordering, then all subsequent operations + /// become ordered after that store. In particular, all subsequent loads will see data + /// written before the store. /// + /// Notice that using this ordering for an operation that combines loads + /// and stores leads to a [`Relaxed`] store operation! + /// + /// This ordering is only applicable for operations that can perform a load. + /// + /// Corresponds to LLVM's [`Acquire`] ordering. + /// + /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire /// [`Release`]: http://llvm.org/docs/Atomics.html#release + /// [`Relaxed`]: https://llvm.org/docs/Atomics.html#monotonic #[stable(feature = "rust1", since = "1.0.0")] Acquire, - /// Has the effects of both [`Acquire`] and [`Release`] together. + /// Has the effects of both [`Acquire`] and [`Release`] together: + /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering. + /// + /// Notice that in the case of `compare_and_swap`, it is possible that the operation ends up + /// not performing any store and hence it has just `Acquire` ordering. However, + /// `AcqRel` will never perform [`Relaxed`] accesses. /// /// This ordering is only applicable for operations that combine both loads and stores. /// - /// For loads it uses [`Acquire`] ordering. For stores it uses the [`Release`] ordering. + /// Corresponds to LLVM's [`AcquireRelease`] ordering. /// + /// [`AcquireRelease`]: http://llvm.org/docs/Atomics.html#acquirerelease /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire /// [`Release`]: http://llvm.org/docs/Atomics.html#release + /// [`Relaxed`]: https://llvm.org/docs/Atomics.html#monotonic #[stable(feature = "rust1", since = "1.0.0")] AcqRel, - /// Like `AcqRel` with the additional guarantee that all threads see all + /// Like [`Acquire`]/[`Release`]/[`AcqRel`] (for load, store, and load-with-store + /// operations, respectively) with the additional guarantee that all threads see all /// sequentially consistent operations in the same order. + /// + /// Corresponds to LLVM's [`SequentiallyConsistent`] ordering. + /// + /// [`SequentiallyConsistent`]: http://llvm.org/docs/Atomics.html#sequentiallyconsistent + /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire + /// [`Release`]: http://llvm.org/docs/Atomics.html#release + /// [`AcqRel`]: https://llvm.org/docs/Atomics.html#acquirerelease #[stable(feature = "rust1", since = "1.0.0")] SeqCst, // Prevent exhaustive matching to allow for future extension @@ -384,9 +419,11 @@ impl AtomicBool { /// was updated. /// /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory - /// ordering of this operation. + /// ordering of this operation. Notice that even when using [`AcqRel`], the operation + /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics. /// /// [`Ordering`]: enum.Ordering.html + /// [`Ordering`]: enum.Ordering.html#variant.AcqRel /// [`bool`]: ../../../std/primitive.bool.html /// /// # Examples @@ -421,7 +458,7 @@ impl AtomicBool { /// ordering of this operation. The first describes the required ordering if the /// operation succeeds while the second describes the required ordering when the /// operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and must - /// be equivalent or weaker than the success ordering. + /// be equivalent to or weaker than the success ordering. /// /// [`bool`]: ../../../std/primitive.bool.html /// [`Ordering`]: enum.Ordering.html From e9a86a2e1ae69ea733c5e8fdd976b9b41668fec2 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 7 Aug 2018 11:22:45 +0200 Subject: [PATCH 2/5] fix link label; use more https --- src/libcore/sync/atomic.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 41e6376ff8c05..3f35067f4f55b 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -29,7 +29,7 @@ //! //! [`Ordering`]: enum.Ordering.html //! -//! [1]: http://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations +//! [1]: https://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations //! [2]: ../../../nomicon/atomics.html //! //! Atomic variables are safe to share between threads (they implement [`Sync`]) @@ -178,7 +178,7 @@ unsafe impl Sync for AtomicPtr {} /// "relaxed" atomics allow all reorderings. /// /// Rust's memory orderings are [the same as -/// LLVM's](http://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations). +/// LLVM's](https://llvm.org/docs/LangRef.html#memory-model-for-concurrent-operations). /// /// For more information see the [nomicon]. /// @@ -190,7 +190,7 @@ pub enum Ordering { /// /// Corresponds to LLVM's [`Monotonic`] ordering. /// - /// [`Monotonic`]: http://llvm.org/docs/Atomics.html#monotonic + /// [`Monotonic`]: https://llvm.org/docs/Atomics.html#monotonic #[stable(feature = "rust1", since = "1.0.0")] Relaxed, /// When coupled with a store, all previous operations become ordered @@ -205,8 +205,8 @@ pub enum Ordering { /// /// Corresponds to LLVM's [`Release`] ordering. /// - /// [`Release`]: http://llvm.org/docs/Atomics.html#release - /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire + /// [`Release`]: https://llvm.org/docs/Atomics.html#release + /// [`Acquire`]: https://llvm.org/docs/Atomics.html#acquire /// [`Relaxed`]: https://llvm.org/docs/Atomics.html#monotonic #[stable(feature = "rust1", since = "1.0.0")] Release, @@ -222,8 +222,8 @@ pub enum Ordering { /// /// Corresponds to LLVM's [`Acquire`] ordering. /// - /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire - /// [`Release`]: http://llvm.org/docs/Atomics.html#release + /// [`Acquire`]: https://llvm.org/docs/Atomics.html#acquire + /// [`Release`]: https://llvm.org/docs/Atomics.html#release /// [`Relaxed`]: https://llvm.org/docs/Atomics.html#monotonic #[stable(feature = "rust1", since = "1.0.0")] Acquire, @@ -238,9 +238,9 @@ pub enum Ordering { /// /// Corresponds to LLVM's [`AcquireRelease`] ordering. /// - /// [`AcquireRelease`]: http://llvm.org/docs/Atomics.html#acquirerelease - /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire - /// [`Release`]: http://llvm.org/docs/Atomics.html#release + /// [`AcquireRelease`]: https://llvm.org/docs/Atomics.html#acquirerelease + /// [`Acquire`]: https://llvm.org/docs/Atomics.html#acquire + /// [`Release`]: https://llvm.org/docs/Atomics.html#release /// [`Relaxed`]: https://llvm.org/docs/Atomics.html#monotonic #[stable(feature = "rust1", since = "1.0.0")] AcqRel, @@ -250,9 +250,9 @@ pub enum Ordering { /// /// Corresponds to LLVM's [`SequentiallyConsistent`] ordering. /// - /// [`SequentiallyConsistent`]: http://llvm.org/docs/Atomics.html#sequentiallyconsistent - /// [`Acquire`]: http://llvm.org/docs/Atomics.html#acquire - /// [`Release`]: http://llvm.org/docs/Atomics.html#release + /// [`SequentiallyConsistent`]: https://llvm.org/docs/Atomics.html#sequentiallyconsistent + /// [`Acquire`]: https://llvm.org/docs/Atomics.html#acquire + /// [`Release`]: https://llvm.org/docs/Atomics.html#release /// [`AcqRel`]: https://llvm.org/docs/Atomics.html#acquirerelease #[stable(feature = "rust1", since = "1.0.0")] SeqCst, @@ -423,7 +423,7 @@ impl AtomicBool { /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics. /// /// [`Ordering`]: enum.Ordering.html - /// [`Ordering`]: enum.Ordering.html#variant.AcqRel + /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel /// [`bool`]: ../../../std/primitive.bool.html /// /// # Examples From 110bcc97984fec55cb6c0bd5313bcd8ee02da12c Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 7 Aug 2018 11:26:05 +0200 Subject: [PATCH 3/5] forgot to add comment for some atomic types --- src/libcore/sync/atomic.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 3f35067f4f55b..7867998d05852 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -843,7 +843,8 @@ impl AtomicPtr { /// was updated. /// /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory - /// ordering of this operation. + /// ordering of this operation. Notice that even when using [`AcqRel`], the operation + /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics. /// /// [`Ordering`]: enum.Ordering.html /// @@ -1202,7 +1203,8 @@ The return value is always the previous value. If it is equal to `current`, then value was updated. `compare_and_swap` also takes an [`Ordering`] argument which describes the memory -ordering of this operation. +ordering of this operation. Notice that even when using [`AcqRel`], the operation +might fail and hence just perform an `Acquire` load, but not have `Release` semantics. [`Ordering`]: enum.Ordering.html From 1733bd3cbd7e04ad1745a3372b969e23575f9ebc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 7 Aug 2018 11:33:20 +0200 Subject: [PATCH 4/5] list possible orderings for load and store --- src/libcore/sync/atomic.rs | 69 ++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 7867998d05852..17702494eccee 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -332,15 +332,18 @@ impl AtomicBool { /// Loads a value from the bool. /// /// `load` takes an [`Ordering`] argument which describes the memory ordering - /// of this operation. + /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`]. /// /// # Panics /// /// Panics if `order` is [`Release`] or [`AcqRel`]. /// /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed /// [`Release`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel + /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst /// /// # Examples /// @@ -360,9 +363,18 @@ impl AtomicBool { /// Stores a value into the bool. /// /// `store` takes an [`Ordering`] argument which describes the memory ordering - /// of this operation. + /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `order` is [`Acquire`] or [`AcqRel`]. /// /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed + /// [`Release`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel + /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst /// /// # Examples /// @@ -374,13 +386,6 @@ impl AtomicBool { /// some_bool.store(false, Ordering::Relaxed); /// assert_eq!(some_bool.load(Ordering::Relaxed), false); /// ``` - /// - /// # Panics - /// - /// Panics if `order` is [`Acquire`] or [`AcqRel`]. - /// - /// [`Acquire`]: enum.Ordering.html#variant.Acquire - /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn store(&self, val: bool, order: Ordering) { @@ -751,15 +756,18 @@ impl AtomicPtr { /// Loads a value from the pointer. /// /// `load` takes an [`Ordering`] argument which describes the memory ordering - /// of this operation. + /// of this operation. Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`]. /// /// # Panics /// /// Panics if `order` is [`Release`] or [`AcqRel`]. /// /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed /// [`Release`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel + /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst /// /// # Examples /// @@ -780,9 +788,18 @@ impl AtomicPtr { /// Stores a value into the pointer. /// /// `store` takes an [`Ordering`] argument which describes the memory ordering - /// of this operation. + /// of this operation. Possible values are [`SeqCst`], [`Release`] and [`Relaxed`]. + /// + /// # Panics + /// + /// Panics if `order` is [`Acquire`] or [`AcqRel`]. /// /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed + /// [`Release`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel + /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst /// /// # Examples /// @@ -796,13 +813,6 @@ impl AtomicPtr { /// /// some_ptr.store(other_ptr, Ordering::Relaxed); /// ``` - /// - /// # Panics - /// - /// Panics if `order` is [`Acquire`] or [`AcqRel`]. - /// - /// [`Acquire`]: enum.Ordering.html#variant.Acquire - /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn store(&self, ptr: *mut T, order: Ordering) { @@ -1115,14 +1125,18 @@ assert_eq!(some_var.into_inner(), 5); concat!("Loads a value from the atomic integer. `load` takes an [`Ordering`] argument which describes the memory ordering of this operation. +Possible values are [`SeqCst`], [`Acquire`] and [`Relaxed`]. # Panics Panics if `order` is [`Release`] or [`AcqRel`]. [`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed [`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire [`AcqRel`]: enum.Ordering.html#variant.AcqRel +[`SeqCst`]: enum.Ordering.html#variant.SeqCst # Examples @@ -1144,8 +1158,18 @@ assert_eq!(some_var.load(Ordering::Relaxed), 5); concat!("Stores a value into the atomic integer. `store` takes an [`Ordering`] argument which describes the memory ordering of this operation. + Possible values are [`SeqCst`], [`Release`] and [`Relaxed`]. + +# Panics + +Panics if `order` is [`Acquire`] or [`AcqRel`]. [`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed +[`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire +[`AcqRel`]: enum.Ordering.html#variant.AcqRel +[`SeqCst`]: enum.Ordering.html#variant.SeqCst # Examples @@ -1156,14 +1180,7 @@ let some_var = ", stringify!($atomic_type), "::new(5); some_var.store(10, Ordering::Relaxed); assert_eq!(some_var.load(Ordering::Relaxed), 10); -``` - -# Panics - -Panics if `order` is [`Acquire`] or [`AcqRel`]. - -[`Acquire`]: enum.Ordering.html#variant.Acquire -[`AcqRel`]: enum.Ordering.html#variant.AcqRel"), +```"), #[inline] #[$stable] pub fn store(&self, val: $int_type, order: Ordering) { From 6a018a03dfcffef05feec0bf2e5fdba6b965ca1b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 7 Aug 2018 11:57:43 +0200 Subject: [PATCH 5/5] document mode possibilities for all RMW operations --- src/libcore/sync/atomic.rs | 255 ++++++++++++++++++++++++++++++++----- 1 file changed, 226 insertions(+), 29 deletions(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 17702494eccee..5bb713f576741 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -397,9 +397,14 @@ impl AtomicBool { /// Stores a value into the bool, returning the previous value. /// /// `swap` takes an [`Ordering`] argument which describes the memory ordering - /// of this operation. + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. /// /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed + /// [`Release`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire /// /// # Examples /// @@ -426,8 +431,13 @@ impl AtomicBool { /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory /// ordering of this operation. Notice that even when using [`AcqRel`], the operation /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics. + /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it + /// happens, and using [`Release`] makes the load part [`Relaxed`]. /// /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed + /// [`Release`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel /// [`bool`]: ../../../std/primitive.bool.html /// @@ -462,13 +472,18 @@ impl AtomicBool { /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory /// ordering of this operation. The first describes the required ordering if the /// operation succeeds while the second describes the required ordering when the - /// operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and must - /// be equivalent to or weaker than the success ordering. + /// operation fails. Using [`Acquire`] as success ordering makes the store part + /// of this operation [`Relaxed`], and using [`Release`] makes the successful load + /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`] + /// and must be equivalent to or weaker than the success ordering. + /// /// /// [`bool`]: ../../../std/primitive.bool.html /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed /// [`Release`]: enum.Ordering.html#variant.Release - /// [`AcqRel`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst /// /// # Examples /// @@ -515,16 +530,20 @@ impl AtomicBool { /// previous value. /// /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory - /// ordering of this operation. The first describes the required ordering if the operation - /// succeeds while the second describes the required ordering when the operation fails. The - /// failure ordering can't be [`Release`] or [`AcqRel`] and must be equivalent or - /// weaker than the success ordering. + /// ordering of this operation. The first describes the required ordering if the + /// operation succeeds while the second describes the required ordering when the + /// operation fails. Using [`Acquire`] as success ordering makes the store part + /// of this operation [`Relaxed`], and using [`Release`] makes the successful load + /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`] + /// and must be equivalent to or weaker than the success ordering. /// /// [`bool`]: ../../../std/primitive.bool.html /// [`compare_exchange`]: #method.compare_exchange /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed /// [`Release`]: enum.Ordering.html#variant.Release - /// [`AcqRel`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst /// /// # Examples /// @@ -565,6 +584,16 @@ impl AtomicBool { /// /// Returns the previous value. /// + /// `fetch_and` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed + /// [`Release`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// /// # Examples /// /// ``` @@ -596,6 +625,16 @@ impl AtomicBool { /// /// Returns the previous value. /// + /// `fetch_nand` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed + /// [`Release`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// /// # Examples /// /// ``` @@ -640,6 +679,16 @@ impl AtomicBool { /// /// Returns the previous value. /// + /// `fetch_or` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed + /// [`Release`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// /// # Examples /// /// ``` @@ -671,6 +720,16 @@ impl AtomicBool { /// /// Returns the previous value. /// + /// `fetch_xor` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed + /// [`Release`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// /// # Examples /// /// ``` @@ -824,9 +883,14 @@ impl AtomicPtr { /// Stores a value into the pointer, returning the previous value. /// /// `swap` takes an [`Ordering`] argument which describes the memory ordering - /// of this operation. + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. /// /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed + /// [`Release`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire /// /// # Examples /// @@ -855,8 +919,14 @@ impl AtomicPtr { /// `compare_and_swap` also takes an [`Ordering`] argument which describes the memory /// ordering of this operation. Notice that even when using [`AcqRel`], the operation /// might fail and hence just perform an `Acquire` load, but not have `Release` semantics. + /// Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it + /// happens, and using [`Release`] makes the load part [`Relaxed`]. /// /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed + /// [`Release`]: enum.Ordering.html#variant.Release + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel /// /// # Examples /// @@ -887,14 +957,18 @@ impl AtomicPtr { /// the previous value. On success this value is guaranteed to be equal to `current`. /// /// `compare_exchange` takes two [`Ordering`] arguments to describe the memory - /// ordering of this operation. The first describes the required ordering if - /// the operation succeeds while the second describes the required ordering when - /// the operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] - /// and must be equivalent or weaker than the success ordering. + /// ordering of this operation. The first describes the required ordering if the + /// operation succeeds while the second describes the required ordering when the + /// operation fails. Using [`Acquire`] as success ordering makes the store part + /// of this operation [`Relaxed`], and using [`Release`] makes the successful load + /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`] + /// and must be equivalent to or weaker than the success ordering. /// /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed /// [`Release`]: enum.Ordering.html#variant.Release - /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst /// /// # Examples /// @@ -940,15 +1014,19 @@ impl AtomicPtr { /// previous value. /// /// `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory - /// ordering of this operation. The first describes the required ordering if the operation - /// succeeds while the second describes the required ordering when the operation fails. The - /// failure ordering can't be [`Release`] or [`AcqRel`] and must be equivalent or - /// weaker than the success ordering. + /// ordering of this operation. The first describes the required ordering if the + /// operation succeeds while the second describes the required ordering when the + /// operation fails. Using [`Acquire`] as success ordering makes the store part + /// of this operation [`Relaxed`], and using [`Release`] makes the successful load + /// [`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`] + /// and must be equivalent to or weaker than the success ordering. /// /// [`compare_exchange`]: #method.compare_exchange /// [`Ordering`]: enum.Ordering.html + /// [`Relaxed`]: enum.Ordering.html#variant.Relaxed /// [`Release`]: enum.Ordering.html#variant.Release - /// [`AcqRel`]: enum.Ordering.html#variant.AcqRel + /// [`Acquire`]: enum.Ordering.html#variant.Acquire + /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst /// /// # Examples /// @@ -1191,9 +1269,15 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); doc_comment! { concat!("Stores a value into the atomic integer, returning the previous value. -`swap` takes an [`Ordering`] argument which describes the memory ordering of this operation. +`swap` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. [`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed +[`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire # Examples @@ -1222,8 +1306,14 @@ value was updated. `compare_and_swap` also takes an [`Ordering`] argument which describes the memory ordering of this operation. Notice that even when using [`AcqRel`], the operation might fail and hence just perform an `Acquire` load, but not have `Release` semantics. +Using [`Acquire`] makes the store part of this operation [`Relaxed`] if it +happens, and using [`Release`] makes the load part [`Relaxed`]. [`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed +[`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire +[`AcqRel`]: enum.Ordering.html#variant.AcqRel # Examples @@ -1264,14 +1354,18 @@ containing the previous value. On success this value is guaranteed to be equal t `current`. `compare_exchange` takes two [`Ordering`] arguments to describe the memory -ordering of this operation. The first describes the required ordering if -the operation succeeds while the second describes the required ordering when -the operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and -must be equivalent or weaker than the success ordering. +ordering of this operation. The first describes the required ordering if the +operation succeeds while the second describes the required ordering when the +operation fails. Using [`Acquire`] as success ordering makes the store part +of this operation [`Relaxed`], and using [`Release`] makes the successful load +[`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`] +and must be equivalent to or weaker than the success ordering. [`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed [`Release`]: enum.Ordering.html#variant.Release -[`AcqRel`]: enum.Ordering.html#variant.AcqRel +[`Acquire`]: enum.Ordering.html#variant.Acquire +[`SeqCst`]: enum.Ordering.html#variant.SeqCst # Examples @@ -1316,13 +1410,17 @@ written and containing the previous value. `compare_exchange_weak` takes two [`Ordering`] arguments to describe the memory ordering of this operation. The first describes the required ordering if the operation succeeds while the second describes the required ordering when the -operation fails. The failure ordering can't be [`Release`] or [`AcqRel`] and -must be equivalent or weaker than the success ordering. +operation fails. Using [`Acquire`] as success ordering makes the store part +of this operation [`Relaxed`], and using [`Release`] makes the successful load +[`Relaxed`]. The failure ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`] +and must be equivalent to or weaker than the success ordering. [`compare_exchange`]: #method.compare_exchange [`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed [`Release`]: enum.Ordering.html#variant.Release -[`AcqRel`]: enum.Ordering.html#variant.AcqRel +[`Acquire`]: enum.Ordering.html#variant.Acquire +[`SeqCst`]: enum.Ordering.html#variant.SeqCst # Examples @@ -1358,6 +1456,16 @@ loop { This operation wraps around on overflow. +`fetch_add` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +[`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed +[`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire + # Examples ``` @@ -1379,6 +1487,16 @@ assert_eq!(foo.load(Ordering::SeqCst), 10); This operation wraps around on overflow. +`fetch_sub` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +[`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed +[`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire + # Examples ``` @@ -1403,6 +1521,16 @@ sets the new value to the result. Returns the previous value. +`fetch_and` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +[`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed +[`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire + # Examples ``` @@ -1427,6 +1555,16 @@ sets the new value to the result. Returns the previous value. +`fetch_nand` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +[`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed +[`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire + # Examples ``` @@ -1452,6 +1590,16 @@ sets the new value to the result. Returns the previous value. +`fetch_or` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +[`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed +[`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire + # Examples ``` @@ -1476,6 +1624,16 @@ sets the new value to the result. Returns the previous value. +`fetch_xor` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +[`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed +[`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire + # Examples ``` @@ -1501,6 +1659,25 @@ 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`]! + +Using [`Acquire`] as success ordering makes the store part +of this operation [`Relaxed`], and using [`Release`] makes the final successful load +[`Relaxed`]. The (failed) load ordering can only be [`SeqCst`], [`Acquire`] or [`Relaxed`] +and must be equivalent to or weaker than the success ordering. + +[`bool`]: ../../../std/primitive.bool.html +[`compare_exchange`]: #method.compare_exchange +[`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed +[`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire +[`SeqCst`]: enum.Ordering.html#variant.SeqCst + # Examples ```rust @@ -1541,6 +1718,16 @@ sets the new value to the result. Returns the previous value. +`fetch_max` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +[`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed +[`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire + # Examples ``` @@ -1580,6 +1767,16 @@ sets the new value to the result. Returns the previous value. +`fetch_min` takes an [`Ordering`] argument which describes the memory ordering +of this operation. All ordering modes are possible. Note that using +[`Acquire`] makes the store part of this operation [`Relaxed`], and +using [`Release`] makes the load part [`Relaxed`]. + +[`Ordering`]: enum.Ordering.html +[`Relaxed`]: enum.Ordering.html#variant.Relaxed +[`Release`]: enum.Ordering.html#variant.Release +[`Acquire`]: enum.Ordering.html#variant.Acquire + # Examples ```