Skip to content

Commit 1a5284c

Browse files
authored
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
2 parents 4d81b14 + 91a9866 commit 1a5284c

File tree

1 file changed

+52
-3
lines changed

1 file changed

+52
-3
lines changed

src/libcore/sync/atomic.rs

+52-3
Original file line numberDiff line numberDiff line change
@@ -1573,12 +1573,30 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
15731573

15741574
/// An atomic fence.
15751575
///
1576-
/// A fence 'A' which has [`Release`] ordering semantics, synchronizes with a
1577-
/// fence 'B' with (at least) [`Acquire`] semantics, if and only if there exists
1578-
/// atomic operations X and Y, both operating on some atomic object 'M' such
1576+
/// Depending on the specified order, a fence prevents the compiler and CPU from
1577+
/// reordering certain types of memory operations around it.
1578+
/// That creates synchronizes-with relationships between it and atomic operations
1579+
/// or fences in other threads.
1580+
///
1581+
/// A fence 'A' which has (at least) [`Release`] ordering semantics, synchronizes
1582+
/// with a fence 'B' with (at least) [`Acquire`] semantics, if and only if there
1583+
/// exist operations X and Y, both operating on some atomic object 'M' such
15791584
/// that A is sequenced before X, Y is synchronized before B and Y observes
15801585
/// the change to M. This provides a happens-before dependence between A and B.
15811586
///
1587+
/// ```text
1588+
/// Thread 1 Thread 2
1589+
///
1590+
/// fence(Release); A --------------
1591+
/// x.store(3, Relaxed); X --------- |
1592+
/// | |
1593+
/// | |
1594+
/// -------------> Y if x.load(Relaxed) == 3 {
1595+
/// |-------> B fence(Acquire);
1596+
/// ...
1597+
/// }
1598+
/// ```
1599+
///
15821600
/// Atomic operations with [`Release`] or [`Acquire`] semantics can also synchronize
15831601
/// with a fence.
15841602
///
@@ -1592,6 +1610,37 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
15921610
///
15931611
/// Panics if `order` is [`Relaxed`].
15941612
///
1613+
/// # Examples
1614+
///
1615+
/// ```
1616+
/// use std::sync::atomic::AtomicBool;
1617+
/// use std::sync::atomic::fence;
1618+
/// use std::sync::atomic::Ordering;
1619+
///
1620+
/// // A mutual exclusion primitive based on spinlock.
1621+
/// pub struct Mutex {
1622+
/// flag: AtomicBool,
1623+
/// }
1624+
///
1625+
/// impl Mutex {
1626+
/// pub fn new() -> Mutex {
1627+
/// Mutex {
1628+
/// flag: AtomicBool::new(false),
1629+
/// }
1630+
/// }
1631+
///
1632+
/// pub fn lock(&self) {
1633+
/// while !self.flag.compare_and_swap(false, true, Ordering::Relaxed) {}
1634+
/// // This fence syncronizes-with store in `unlock`.
1635+
/// fence(Ordering::Acquire);
1636+
/// }
1637+
///
1638+
/// pub fn unlock(&self) {
1639+
/// self.flag.store(false, Ordering::Release);
1640+
/// }
1641+
/// }
1642+
/// ```
1643+
///
15951644
/// [`Ordering`]: enum.Ordering.html
15961645
/// [`Acquire`]: enum.Ordering.html#variant.Acquire
15971646
/// [`SeqCst`]: enum.Ordering.html#variant.SeqCst

0 commit comments

Comments
 (0)