Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 63 additions & 11 deletions library/core/src/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4277,11 +4277,61 @@ unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
/// threads. To achieve this, a fence prevents the compiler and CPU from reordering certain types of
/// memory operations around it.
///
/// 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 sequenced before B and Y observes
/// the change to m. This provides a happens-before dependence between A and B.
/// There are 3 different ways to use an atomic fence:
///
/// - atomic - fence synchronization: an atomic operation with (at least) [`Release`] ordering
/// semantics synchronizes with a fence with (at least) [`Acquire`] ordering semantics.
/// - fence - atomic synchronization: a fence with (at least) [`Release`] ordering semantics
/// synchronizes with an atomic operation with (at least) [`Acquire`] ordering semantics.
/// - fence - fence synchronization: a fence with (at least) [`Release`] ordering semantics
/// synchronizes with a fence with (at least) [`Acquire`] ordering semantics.
///
/// These 3 ways complement the regular atomic - atomic synchronization.
///
/// ## Atomic - Fence
///
/// An atomic operation 'X' with (at least) [`Release`] ordering semantics on some atomic object
/// 'm' on thread 1 is paired on thread 2 with an atomic read 'Y' with any order on 'm' followed by
/// a fence 'B' with (at least) [`Acquire`] ordering semantics. This provides a happens-before
/// dependence between X and B.
///
/// ```text
/// Thread 1 Thread 2
///
/// m.store(3, Release); X ---------
/// |
/// |
/// -------------> Y if m.load(Relaxed) == 3 {
/// B fence(Acquire);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case, and the fence - atomic case below, it's unclear whether the arrow should come from/point to the fence instead.

The happens-before relationship established is between X and B, but it may be worth emphasizing the X - Y link which is crucial for the fence to work.

/// ...
/// }
/// ```
///
/// ## Fence - Atomic
///
/// A fence 'A' with (at least) [`Release`] ordering semantics followed by an atomic store 'X' with
/// any ordering on some atomic object 'm' on thread 1 is paired on thread 2 with an atomic
/// operation 'Y' with (at least) [`Acquire`] ordering semantics. This provides a happens-before
/// dependence between A and Y.
///
/// ```text
/// Thread 1 Thread 2
///
/// fence(Release); A
/// m.store(3, Relaxed); X ---------
/// |
/// |
/// -------------> Y if m.load(Acquire) == 3 {
/// ...
/// }
/// ```
///
/// ## Fence - Fence
///
/// A fence 'A' which has (at least) [`Release`] ordering semantics followed by an atomic store 'X'
/// with any ordering on some atomic object 'm' on thread 1 is paired on thread 2 with an atomic
/// operation 'Y' with any ordering on 'm' followed by a fence 'B' with (at least) [`Acquire`]
/// ordering semantics. This provides a happens-before dependence between A and B.
///
/// ```text
/// Thread 1 Thread 2
Expand All @@ -4296,14 +4346,16 @@ unsafe fn atomic_umin<T: Copy>(dst: *mut T, val: T, order: Ordering) -> T {
/// }
/// ```
///
/// Note that in the example above, it is crucial that the accesses to `m` are atomic. Fences cannot
/// ## Mandatory Atomic
///
/// Note that in the examples above, it is crucial that the access to `m` are atomic. Fences cannot
/// be used to establish synchronization among non-atomic accesses in different threads. However,
/// thanks to the happens-before relationship between A and B, any non-atomic accesses that
/// happen-before A are now also properly synchronized with any non-atomic accesses that
/// happen-after B.
/// thanks to the happens-before relationship, any non-atomic access that happen-before the atomic
/// operation or fence with (at least) [`Release`] ordering semantics are now also properly
/// synchronized with any non-atomic accesses that happen-after the atomic operation or fence with
/// (at least) [`Acquire`] ordering semantics.
///
/// Atomic operations with [`Release`] or [`Acquire`] semantics can also synchronize
/// with a fence.
/// ## Memory Ordering
///
/// A fence which has [`SeqCst`] ordering, in addition to having both [`Acquire`]
/// and [`Release`] semantics, participates in the global program order of the
Expand Down
Loading