Types and operations for atomic operations and lockless algorithms.
Unstable API.
Example:
import pure/concurrency/atomics # Atomic var loc: Atomic[int] loc.store(4) assert loc.load == 4 loc.store(2) assert loc.load(moRelaxed) == 2 loc.store(9) assert loc.load(moAcquire) == 9 loc.store(0, moRelease) assert loc.load == 0 assert loc.exchange(7) == 0 assert loc.load == 7 var expected = 7 assert loc.compareExchange(expected, 5, moRelaxed, moRelaxed) assert expected == 7 assert loc.load == 5 assert not loc.compareExchange(expected, 12, moRelaxed, moRelaxed) assert expected == 5 assert loc.load == 5 assert loc.fetchAdd(1) == 5 assert loc.fetchAdd(2) == 6 assert loc.fetchSub(3) == 8 loc.atomicInc(1) assert loc.load == 6 # AtomicFlag var flag: AtomicFlag assert not flag.testAndSet assert flag.testAndSet flag.clear(moRelaxed) assert not flag.testAndSet
Types
Atomic[T] = object when T is Trivial: when sizeof(T) == 1: value elif sizeof(T) == 2: value elif sizeof(T) == 4: value elif sizeof(T) == 8: value else: nonAtomicValue guard
- Source Edit
AtomicFlag {.importc: "atomic_flag", size: 1, header: "<stdatomic.h>".} = object
- Source Edit
MemoryOrder {.importc: "memory_order", header: "<stdatomic.h>".} = enum moRelaxed, moConsume, moAcquire, moRelease, moAcquireRelease, moSequentiallyConsistent
- Source Edit
Procs
proc `+=`[T: SomeInteger](location: var Atomic[T]; value: T) {.inline.}
- Atomically increments the atomic integer by some value. Source Edit
proc `-=`[T: SomeInteger](location: var Atomic[T]; value: T) {.inline.}
- Atomically decrements the atomic integer by some value. Source Edit
proc atomicDec[T: SomeInteger](location: var Atomic[T]; value: T = 1) {.inline.}
- Atomically decrements the atomic integer by some value. Source Edit
proc atomicInc[T: SomeInteger](location: var Atomic[T]; value: T = 1) {.inline.}
- Atomically increments the atomic integer by some value. Source Edit
proc clear(location: var AtomicFlag; order: MemoryOrder = moSequentiallyConsistent) {. importc: "atomic_flag_clear_explicit", header: "<stdatomic.h>", ...raises: [], tags: [].}
- Source Edit
proc compareExchange[T: not Trivial](location: var Atomic[T]; expected: var T; desired: T; order: MemoryOrder = moSequentiallyConsistent): bool {. inline.}
- Source Edit
proc compareExchange[T: not Trivial](location: var Atomic[T]; expected: var T; desired: T; success, failure: MemoryOrder): bool {. inline.}
- Source Edit
proc compareExchange[T: Trivial](location: var Atomic[T]; expected: var T; desired: T; order: MemoryOrder = moSequentiallyConsistent): bool {. inline.}
- Source Edit
proc compareExchange[T: Trivial](location: var Atomic[T]; expected: var T; desired: T; success, failure: MemoryOrder): bool {. inline.}
- Source Edit
proc compareExchangeWeak[T: not Trivial](location: var Atomic[T]; expected: var T; desired: T; order: MemoryOrder = moSequentiallyConsistent): bool {. inline.}
- Source Edit
proc compareExchangeWeak[T: not Trivial](location: var Atomic[T]; expected: var T; desired: T; success, failure: MemoryOrder): bool {.inline.}
- Source Edit
proc compareExchangeWeak[T: Trivial](location: var Atomic[T]; expected: var T; desired: T; order: MemoryOrder = moSequentiallyConsistent): bool {. inline.}
- Source Edit
proc compareExchangeWeak[T: Trivial](location: var Atomic[T]; expected: var T; desired: T; success, failure: MemoryOrder): bool {. inline.}
- Source Edit
proc exchange[T: not Trivial](location: var Atomic[T]; desired: T; order: MemoryOrder = moSequentiallyConsistent): T {. inline.}
- Source Edit
proc exchange[T: Trivial](location: var Atomic[T]; desired: T; order: MemoryOrder = moSequentiallyConsistent): T {. inline.}
- Source Edit
proc fence(order: MemoryOrder) {.importc: "atomic_thread_fence", header: "<stdatomic.h>", ...raises: [], tags: [].}
- Source Edit
proc fetchAdd[T: SomeInteger](location: var Atomic[T]; value: T; order: MemoryOrder = moSequentiallyConsistent): T {. inline.}
- Source Edit
proc fetchAnd[T: SomeInteger](location: var Atomic[T]; value: T; order: MemoryOrder = moSequentiallyConsistent): T {. inline.}
- Source Edit
proc fetchOr[T: SomeInteger](location: var Atomic[T]; value: T; order: MemoryOrder = moSequentiallyConsistent): T {. inline.}
- Source Edit
proc fetchSub[T: SomeInteger](location: var Atomic[T]; value: T; order: MemoryOrder = moSequentiallyConsistent): T {. inline.}
- Source Edit
proc fetchXor[T: SomeInteger](location: var Atomic[T]; value: T; order: MemoryOrder = moSequentiallyConsistent): T {. inline.}
- Source Edit
proc load[T: not Trivial](location: var Atomic[T]; order: MemoryOrder = moSequentiallyConsistent): T {. inline.}
- Source Edit
proc load[T: Trivial](location: var Atomic[T]; order: MemoryOrder = moSequentiallyConsistent): T {.inline.}
- Source Edit
proc signalFence(order: MemoryOrder) {.importc: "atomic_signal_fence", header: "<stdatomic.h>", ...raises: [], tags: [].}
- Source Edit
proc store[T: not Trivial](location: var Atomic[T]; desired: T; order: MemoryOrder = moSequentiallyConsistent) {. inline.}
- Source Edit
proc store[T: Trivial](location: var Atomic[T]; desired: T; order: MemoryOrder = moSequentiallyConsistent) {.inline.}
- Source Edit
proc testAndSet(location: var AtomicFlag; order: MemoryOrder = moSequentiallyConsistent): bool {. importc: "atomic_flag_test_and_set_explicit", header: "<stdatomic.h>", ...raises: [], tags: [].}
- Source Edit