about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorCorey Farwell <coreyf@rwell.org>2017-05-02 21:21:17 -0400
committerGitHub <noreply@github.com>2017-05-02 21:21:17 -0400
commit1a5284c32b1bd47da23c00fe5ab87ae009fd2eda (patch)
tree28dc3d53f017f91da463fde9b19ac4b97537782a /src/libcore
parent4d81b14b80a076fa249a4b7022688c600f2e9590 (diff)
parent91a9866bb33c39c2dabcc2e61ca2986a79b9a076 (diff)
downloadrust-1a5284c32b1bd47da23c00fe5ab87ae009fd2eda.tar.gz
rust-1a5284c32b1bd47da23c00fe5ab87ae009fd2eda.zip
Rollup merge of #41217 - topecongiro:docs/atomic-fence, r=steveklabnik
Update docs of 'fence'

This PR updates the docs for `std::sync::atomic::fence` with an example and a diagram.
Part of #29377.
r? @steveklabnik
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/sync/atomic.rs55
1 files changed, 52 insertions, 3 deletions
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 3c51dbc2550..c13fd558354 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -1573,12 +1573,30 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
 
 /// An atomic fence.
 ///
-/// A fence 'A' which has [`Release`] ordering semantics, synchronizes with a
-/// fence 'B' with (at least) [`Acquire`] semantics, if and only if there exists
-/// atomic operations X and Y, both operating on some atomic object 'M' such
+/// Depending on the specified order, a fence prevents the compiler and CPU from
+/// reordering certain types of memory operations around it.
+/// That creates synchronizes-with relationships between it and atomic operations
+/// or fences in other threads.
+///
+/// A fence 'A' which has (at least) [`Release`] ordering semantics, synchronizes
+/// with a fence 'B' with (at least) [`Acquire`] semantics, if and only if there
+/// exist operations X and Y, both operating on some atomic object 'M' such
 /// that A is sequenced before X, Y is synchronized before B and Y observes
 /// the change to M. This provides a happens-before dependence between A and B.
 ///
+/// ```text
+///     Thread 1                                          Thread 2
+///
+/// fence(Release);      A --------------
+/// x.store(3, Relaxed); X ---------    |
+///                                |    |
+///                                |    |
+///                                -------------> Y  if x.load(Relaxed) == 3 {
+///                                     |-------> B      fence(Acquire);
+///                                                      ...
+///                                                  }
+/// ```
+///
 /// Atomic operations with [`Release`] or [`Acquire`] semantics can also synchronize
 /// with a fence.
 ///
@@ -1592,6 +1610,37 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
 ///
 /// Panics if `order` is [`Relaxed`].
 ///
+/// # Examples
+///
+/// ```
+/// use std::sync::atomic::AtomicBool;
+/// use std::sync::atomic::fence;
+/// use std::sync::atomic::Ordering;
+///
+/// // A mutual exclusion primitive based on spinlock.
+/// pub struct Mutex {
+///     flag: AtomicBool,
+/// }
+///
+/// impl Mutex {
+///     pub fn new() -> Mutex {
+///         Mutex {
+///             flag: AtomicBool::new(false),
+///         }
+///     }
+///
+///     pub fn lock(&self) {
+///         while !self.flag.compare_and_swap(false, true, Ordering::Relaxed) {}
+///         // This fence syncronizes-with store in `unlock`.
+///         fence(Ordering::Acquire);
+///     }
+///
+///     pub fn unlock(&self) {
+///         self.flag.store(false, Ordering::Release);
+///     }
+/// }
+/// ```
+///
 /// [`Ordering`]: enum.Ordering.html
 /// [`Acquire`]: enum.Ordering.html#variant.Acquire
 /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst