Synchronization Primitives

Ordering

std::sync::atomic::Ordering is a #[non_exhaustive] enum passed to every atomic method (load, store, swap, fetch_add, compare_exchange) that specifies how the compiler and CPU hardware may reorder surrounding memory accesses relative to that atomic operation.

The Five Variants of std::sync::atomic::Ordering

#[non_exhaustive]
pub enum Ordering {
    Relaxed,
    Release,
    Acquire,
    AcqRel,
    SeqCst,
}
Ordering Variant Valid On Synchronization & Memory-Ordering Guarantee
Ordering::Relaxed All operations (load, store, RMW) Guarantees atomicity of this single variable only; imposes zero ordering constraints on other memory reads/writes
Ordering::Release Writes (store, RMW) Prevents any preceding read or write on the current thread from being reordered after this store
Ordering::Acquire Reads (load, RMW) Prevents any subsequent read or write on the current thread from being reordered before this load; observes all writes performed before a matching Release store
Ordering::AcqRel Read-Modify-Write (swap, fetch_*, compare_exchange) Performs an Acquire on the read half and a Release on the write half of a read-modify-write operation
Ordering::SeqCst All operations (load, store, RMW) Acquire/Release/AcqRel plus establishes a single global total order of all SeqCst operations across all threads
Strength Hierarchy of `std::sync::atomic::Ordering`:

                 [ Ordering::SeqCst ]   (Strongest: Total global order + Acq/Rel)
                          ^
                          |
                 [ Ordering::AcqRel ]   (Both Acquire and Release on RMW ops)
                    ^            ^
                   /              \
    [ Ordering::Acquire ]    [ Ordering::Release ]
    (On loads / RMW)         (On stores / RMW)
                   \              /
                    v            v
                 [ Ordering::Relaxed ]  (Weakest: Single-variable atomicity only)

Valid Ordering Variants per Atomic Method

Passing Ordering::Release or Ordering::AcqRel to .load()—or passing Ordering::Acquire or Ordering::AcqRel to .store()—panics at runtime!

Atomic Operation Allowed Ordering Arguments Forbidden (Panics at Runtime!)
.load(order) Relaxed, Acquire, SeqCst Release, AcqRel
.store(val, order) Relaxed, Release, SeqCst Acquire, AcqRel
.swap(val, order) / .fetch_*(val, order) Relaxed, Acquire, Release, AcqRel, SeqCst (All 5 allowed)
.compare_exchange(cur, new, success, failure) success: any of the 5; failure: Relaxed, Acquire, SeqCst failure cannot be Release or AcqRel

Practical Example: Relaxed Metrics vs. Release/Acquire Flag Signaling

  • Use Ordering::Relaxed when incrementing standalone metrics or generating unique IDs where no other memory depends on the counter value.
  • Pair Ordering::Release (on the writer) with Ordering::Acquire (on the reader) when an atomic variable signals that other memory has been initialized or updated:
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::thread;

static DATA_SLOT: AtomicU64 = AtomicU64::new(0);
static IS_PUBLISHED: AtomicBool = AtomicBool::new(false);

fn main() {
    thread::scope(|s| {
        // Producer thread:
        s.spawn(|| {
            // 1. Write the payload (can be Relaxed or non-atomic inside UnsafeCell):
            DATA_SLOT.store(0xDEAD_BEEF, Ordering::Relaxed);
            // 2. Publish with `Ordering::Release` so step 1 is guaranteed to
            //    happen-before any reader that observes `IS_PUBLISHED == true`!
            IS_PUBLISHED.store(true, Ordering::Release);
        });

        // Consumer thread:
        s.spawn(|| {
            // 3. Spin with `Ordering::Acquire` until `IS_PUBLISHED` becomes true:
            while !IS_PUBLISHED.load(Ordering::Acquire) {
                std::hint::spin_loop();
            }
            // 4. Guaranteed by Release/Acquire synchronization to observe `0xDEAD_BEEF`!
            let payload = DATA_SLOT.load(Ordering::Relaxed);
            println!("consumer observed payload: {:#x}", payload);
        });
    });
}
consumer observed payload: 0xdeadbeef