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(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(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