about summary refs log tree commit diff
path: root/src/libcore/sync
diff options
context:
space:
mode:
authortopecongiro <seuchida@gmail.com>2017-04-11 21:45:12 +0900
committerSeiichi Uchida <topecongiro@localhost.localdomain>2017-05-01 17:25:07 +0900
commit91a9866bb33c39c2dabcc2e61ca2986a79b9a076 (patch)
tree35c49eafba4a5894df275b2431956a09199191ec /src/libcore/sync
parentf8107c0d7ce4f39364fc96d0eeb6a23673491f81 (diff)
downloadrust-91a9866bb33c39c2dabcc2e61ca2986a79b9a076.tar.gz
rust-91a9866bb33c39c2dabcc2e61ca2986a79b9a076.zip
Add an example for 'fence'
Diffstat (limited to 'src/libcore/sync')
-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 0c70524ead2..53362de0d11 100644
--- a/src/libcore/sync/atomic.rs
+++ b/src/libcore/sync/atomic.rs
@@ -1550,12 +1550,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.
 ///
@@ -1569,6 +1587,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