Skip to content

std.atomics

atomic ops; rmw returns the previous value; helpers are seq-cst

pub Relaxed :: 0

orderings for core::atomic_*; must be comptime-known

pub Acquire :: 1
pub Release :: 2
pub AcqRel :: 3
pub SeqCst :: 4
pub Native :: constraint($T)

int, float, bool or pointer, at most word-sized

pub Numeric :: constraint($T)

int or float, for add/sub/mul/div

pub Integer :: constraint($T)

int only: bitwise, shifts, min/max

pub Boolean :: constraint($T)

for flag helpers

pub load :: fn($T: Native, p: *T) -> T
pub store :: fn($T: Native, p: *T, v: T)
pub load_acquire :: fn($T: Native, p: *T) -> T

acquire load; pairs with store_release

pub store_release :: fn($T: Native, p: *T, v: T)

release store; pairs with load_acquire

pub swap :: fn($T: Native, p: *T, v: T) -> T

returns the previous value

pub compare_exchange :: fn($T: Native, p: *T, expected: T, desired: T) -> bool

true if *p was expected and is now desired

pub compare_exchange_value :: fn($T: Native, p: *T, expected: T, desired: T) -> T

returns the observed value (== expected on success)

pub fetch_add :: fn($T: Numeric, p: *T, v: T) -> T

native for ints and floats

pub fetch_sub :: fn($T: Numeric, p: *T, v: T) -> T
pub fetch_mul :: fn($T: Numeric, p: *T, v: T) -> T

no hardware atomic; cas retry loop

pub fetch_div :: fn($T: Numeric, p: *T, v: T) -> T
pub fetch_max :: fn($T: Integer, p: *T, v: T) -> T

min / max (ints; signedness from T)

pub fetch_min :: fn($T: Integer, p: *T, v: T) -> T
pub fetch_and :: fn($T: Integer, p: *T, v: T) -> T

bitwise (ints; returns the previous value)

pub fetch_or :: fn($T: Integer, p: *T, v: T) -> T
pub fetch_xor :: fn($T: Integer, p: *T, v: T) -> T
pub fetch_nand :: fn($T: Integer, p: *T, v: T) -> T
pub fetch_shl :: fn($T: Integer, p: *T, bits: T) -> T

no hardware atomic; cas retry loops

pub fetch_shr :: fn($T: Integer, p: *T, bits: T) -> T
pub fence :: fn()

seq-cst fence

pub fence_acquire :: fn()

nothing after it moves before it

pub fence_release :: fn()

nothing before it moves after it

pub is_set :: fn(flag: *u32) -> bool
pub test_and_set :: fn(flag: *u32) -> bool

sets to 1; returns whether it was already set

pub clear :: fn(flag: *u32)
pub wait_until_set :: fn(flag: *u32)

busy-waits

pub wait_until_eq :: fn(flag: *u32, value: u32)

busy-waits until *flag == value

pub spin_lock :: fn(lock: *u32)

spins on test_and_set until it wins 0 -> 1

pub spin_unlock :: fn(lock: *u32)
pub Atomic :: struct($T: Native) {
value: T,
}

typed atomic cell; methods skip the Integer/Numeric checks the free fns do

pub make :: fn(v: T) -> Self
pub get :: fn(self: *Self) -> T
pub set :: fn(self: *Self, v: T)
pub get_acquire :: fn(self: *Self) -> T
pub set_release :: fn(self: *Self, v: T)
pub exchange :: fn(self: *Self, v: T) -> T
pub cas :: fn(self: *Self, expected: T, desired: T) -> bool

cas: bool and observed-value variants

pub cas_value :: fn(self: *Self, expected: T, desired: T) -> T
pub add :: fn(self: *Self, v: T) -> T

arithmetic; returns the previous value

pub sub :: fn(self: *Self, v: T) -> T
pub mul :: fn(self: *Self, v: T) -> T
pub div :: fn(self: *Self, v: T) -> T
pub max :: fn(self: *Self, v: T) -> T

min / max + bitwise; returns the previous value

pub min :: fn(self: *Self, v: T) -> T
pub and :: fn(self: *Self, v: T) -> T
pub or :: fn(self: *Self, v: T) -> T
pub xor :: fn(self: *Self, v: T) -> T
pub nand :: fn(self: *Self, v: T) -> T