Types and operations for atomic operations and lockless algorithms.
Unstable API.
By default, C++ uses C11 atomic primitives. To use C++ std::atomic, -d:nimUseCppAtomics can be defined.
Example:
import std/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
Atomic[T] {.importcpp: "std::atomic", completeStruct.} = objectT. Source Edit MemoryOrder {.importcpp: "std::memory_order".} = enum
moRelaxed, ## No ordering constraints. Only the atomicity and ordering against
## other atomic operations is guaranteed.
moConsume, ## This ordering is currently discouraged as it's semantics are
## being revised. Acquire operations should be preferred.
moAcquire, ## When applied to a load operation, no reads or writes in the
## current thread can be reordered before this operation.
moRelease, ## When applied to a store operation, no reads or writes in the
## current thread can be reorderd after this operation.
moAcquireRelease, ## When applied to a read-modify-write operation, this behaves like
## both an acquire and a release operation.
moSequentiallyConsistent ## Behaves like Acquire when applied to load, like Release when
## applied to a store and like AcquireRelease when applied to a
## read-modify-write operation.
## Also guarantees that all threads observe the same total ordering
## with other moSequentiallyConsistent operations.proc compareExchange[T](location: var Atomic[T]; expected: var T; desired: T;
order: MemoryOrder = moSequentiallyConsistent): bool {.
importcpp: "#.compare_exchange_strong(@)", header: "<atomic>", ...raises: [],
tags: [], forbids: [].}expected value and performs exchange with the desired one if equal or load if not. Returns true if the exchange was successful. Source Edit proc compareExchange[T](location: var Atomic[T]; expected: var T; desired: T;
success, failure: MemoryOrder): bool {.
importcpp: "#.compare_exchange_strong(@)", header: "<atomic>", ...raises: [],
tags: [], forbids: [].}proc compareExchangeWeak[T](location: var Atomic[T]; expected: var T;
desired: T;
order: MemoryOrder = moSequentiallyConsistent): bool {.
importcpp: "#.compare_exchange_weak(@)", header: "<atomic>", ...raises: [],
tags: [], forbids: [].}proc compareExchangeWeak[T](location: var Atomic[T]; expected: var T;
desired: T; success, failure: MemoryOrder): bool {.
importcpp: "#.compare_exchange_weak(@)", header: "<atomic>", ...raises: [],
tags: [], forbids: [].}proc exchange[T](location: var Atomic[T]; desired: T;
order: MemoryOrder = moSequentiallyConsistent): T {.
importcpp: "#.exchange(@)", header: "<atomic>", ...raises: [], tags: [],
forbids: [].}desired value and returns the old value. Source Edit proc fetchAnd[T: SomeInteger](location: var Atomic[T]; value: T;
order: MemoryOrder = moSequentiallyConsistent): T {.
importcpp: "#.fetch_and(@)", header: "<atomic>", ...raises: [], tags: [],
forbids: [].}value and returns the original value. Source Edit proc fetchOr[T: SomeInteger](location: var Atomic[T]; value: T;
order: MemoryOrder = moSequentiallyConsistent): T {.
importcpp: "#.fetch_or(@)", header: "<atomic>", ...raises: [], tags: [],
forbids: [].}value and returns the original value. Source Edit proc fetchSub[T: SomeInteger](location: var Atomic[T]; value: T;
order: MemoryOrder = moSequentiallyConsistent): T {.
importcpp: "#.fetch_sub(@)", header: "<atomic>", ...raises: [], tags: [],
forbids: [].}value to the atomic integer and returns the original value. Source Edit proc fetchXor[T: SomeInteger](location: var Atomic[T]; value: T;
order: MemoryOrder = moSequentiallyConsistent): T {.
importcpp: "#.fetch_xor(@)", header: "<atomic>", ...raises: [], tags: [],
forbids: [].}value and returns the original value. Source Edit
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/atomics.html