@@ -1573,12 +1573,30 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
1573
1573
1574
1574
/// An atomic fence.
1575
1575
///
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
1579
1584
/// that A is sequenced before X, Y is synchronized before B and Y observes
1580
1585
/// the change to M. This provides a happens-before dependence between A and B.
1581
1586
///
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
+ ///
1582
1600
/// Atomic operations with [`Release`] or [`Acquire`] semantics can also synchronize
1583
1601
/// with a fence.
1584
1602
///
@@ -1592,6 +1610,37 @@ unsafe fn atomic_xor<T>(dst: *mut T, val: T, order: Ordering) -> T {
1592
1610
///
1593
1611
/// Panics if `order` is [`Relaxed`].
1594
1612
///
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
+ ///
1595
1644
/// [`Ordering`]: enum.Ordering.html
1596
1645
/// [`Acquire`]: enum.Ordering.html#variant.Acquire
1597
1646
/// [`SeqCst`]: enum.Ordering.html#variant.SeqCst
0 commit comments