atomic_* functions.
Memory ordering
All atomic operations accept amemory_order argument:
| Order | Description |
|---|---|
"relaxed" | No ordering guarantees beyond atomicity |
"acquire" | All subsequent loads observe stores released before this acquire |
"release" | All prior stores become visible to threads that acquire this |
"acq_rel" | Combines acquire and release semantics |
"relaxed" unless otherwise specified.
Atomic load and store
Atomic exchange
Returns the old value and storesvalue atomically:
Atomic fetch-and-modify (RMW)
Each operation atomically reads the current value, applies the operation, stores the result, and returns the old value.| Function | Operation |
|---|---|
enigma.atomic_fetch_add(ptr, idx, val, order) | *ptr += val |
enigma.atomic_fetch_sub(ptr, idx, val, order) | *ptr -= val |
enigma.atomic_fetch_min(ptr, idx, val, order) | *ptr = min(*ptr, val) |
enigma.atomic_fetch_max(ptr, idx, val, order) | *ptr = max(*ptr, val) |
enigma.atomic_fetch_and(ptr, idx, val, order) | *ptr &= val |
enigma.atomic_fetch_or(ptr, idx, val, order) | *ptr |= val |
enigma.atomic_fetch_xor(ptr, idx, val, order) | *ptr ^= val |
Example: global counter
Example: parallel histogram
Compare-and-swap (CAS)
atomic_compare_exchange_weak attempts to replace expected with desired. Returns True if the swap succeeded:
Example: lock-free maximum
Ordering guidelines
| Use case | Recommended order |
|---|---|
| Independent counter increments | "relaxed" |
| Producer side of a flag | "release" |
| Consumer side of a flag | "acquire" |
| RMW used as a mutex | "acq_rel" |
"relaxed" where ordering matters is a common source of subtle bugs. When in doubt, use "acq_rel".