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
This commit is contained in:
Corey Farwell 2017-05-02 21:21:17 -04:00 committed by GitHub
commit 1a5284c32b

View File

@ -1573,12 +1573,30 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
/// An atomic fence. /// An atomic fence.
/// ///
/// A fence 'A' which has [`Release`] ordering semantics, synchronizes with a /// Depending on the specified order, a fence prevents the compiler and CPU from
/// fence 'B' with (at least) [`Acquire`] semantics, if and only if there exists /// reordering certain types of memory operations around it.
/// atomic operations X and Y, both operating on some atomic object 'M' such /// 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 /// 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. /// 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 /// Atomic operations with [`Release`] or [`Acquire`] semantics can also synchronize
/// with a fence. /// 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`]. /// 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 /// [`Ordering`]: enum.Ordering.html
/// [`Acquire`]: enum.Ordering.html#variant.Acquire /// [`Acquire`]: enum.Ordering.html#variant.Acquire
/// [`SeqCst`]: enum.Ordering.html#variant.SeqCst /// [`SeqCst`]: enum.Ordering.html#variant.SeqCst