The atomic module is intended to provide some basic support for lock-free
concurrent programming. Some common operations are defined, each of which
may be performed using the specified memory barrier or a less granular
barrier if the hardware does not support the version requested. This
model is based on a design by Alexander Terekhov as outlined in
this thread. Another useful reference for memory ordering on modern
architectures is
this
article by Paul McKenney.
BSD style: see
license.txt
Sean Kelly
- enum msync ¶#
-
Memory synchronization flag. If the supplied option is not available on the
current platform then a stronger method will be used instead.
- raw ¶#
-
not sequenced
- hlb ¶#
-
hoist-load barrier
- hsb ¶#
-
hoist-store barrier
- slb ¶#
-
sink-load barrier
- ssb ¶#
-
sink-store barrier
- acq ¶#
-
hoist-load + hoist-store barrier
- rel ¶#
-
sink-load + sink-store barrier
- seq ¶#
-
fully sequenced (acq + rel)
- template atomicLoad(msync ms, T) ¶#
-
Supported msync values:
msync.raw
msync.hlb
msync.acq
msync.seq
- T atomicLoad(ref T val) ¶#
-
Refreshes the contents of 'val' from main memory. This operation is
both lock-free and atomic.
val | The value to load. This value must be properly aligned. |
The loaded value.
- template atomicStore(msync ms, T) ¶#
-
Supported msync values:
msync.raw
msync.ssb
msync.acq
msync.rel
msync.seq
- void atomicStore(ref T val, T newval) ¶#
-
Stores 'newval' to the memory referenced by 'val'. This operation
is both lock-free and atomic.
val | The destination variable. |
newval | The value to store. |
- template atomicStoreIf(msync ms, T) ¶#
-
Supported msync values:
msync.raw
msync.ssb
msync.acq
msync.rel
msync.seq
- bool atomicStoreIf(ref T val, T newval, T equalTo) ¶#
-
Stores 'newval' to the memory referenced by 'val' if val is equal to
'equalTo'. This operation is both lock-free and atomic.
val | The destination variable. |
newval | The value to store. |
equalTo | The comparison value. |
true if the store occurred, false if not.
- template atomicIncrement(msync ms, T) ¶#
-
Supported msync values:
msync.raw
msync.ssb
msync.acq
msync.rel
msync.seq
- T atomicIncrement(ref T val) ¶#
-
This operation is only legal for built-in value and pointer types,
and is equivalent to an atomic "val = val + 1" operation. This
function exists to facilitate use of the optimized increment
instructions provided by some architecures. If no such instruction
exists on the target platform then the behavior will perform the
operation using more traditional means. This operation is both
lock-free and atomic.
val | The value to increment. |
The result of an atomicLoad of val immediately following the
increment operation. This value is not required to be equal to the
newly stored value. Thus, competing writes are allowed to occur
between the increment and successive load operation.
- template atomicDecrement(msync ms, T) ¶#
-
Supported msync values:
msync.raw
msync.ssb
msync.acq
msync.rel
msync.seq
- T atomicDecrement(ref T val) ¶#
-
This operation is only legal for built-in value and pointer types,
and is equivalent to an atomic "val = val - 1" operation. This
function exists to facilitate use of the optimized decrement
instructions provided by some architecures. If no such instruction
exists on the target platform then the behavior will perform the
operation using more traditional means. This operation is both
lock-free and atomic.
val | The value to decrement. |
The result of an atomicLoad of val immediately following the
increment operation. This value is not required to be equal to the
newly stored value. Thus, competing writes are allowed to occur
between the increment and successive load operation.
- struct Atomic(T) ¶#
-
This struct represents a value which will be subject to competing access.
All accesses to this value will be synchronized with main memory, and
various memory barriers may be employed for instruction ordering. Any
primitive type of size equal to or smaller than the memory bus size is
allowed, so 32-bit machines may use values with size <= int.sizeof and
64-bit machines may use values with size <= long.sizeof. The one exception
to this rule is that architectures that support DCAS will allow double-wide
storeIf operations. The 32-bit x86 architecture, for example, supports
64-bit storeIf operations.
- template load(msync ms = msync.seq) ¶#
-
- T load() ¶#
-
Refreshes the contents of this value from main memory. This
operation is both lock-free and atomic.
The loaded value.
- template store(msync ms = msync.seq) ¶#
-
- void store(T newval) ¶#
-
Stores 'newval' to the memory referenced by this value. This
operation is both lock-free and atomic.
newval | The value to store. |
- template storeIf(msync ms = msync.seq) ¶#
-
- bool storeIf(T newval, T equalTo) ¶#
-
Stores 'newval' to the memory referenced by this value if val is
equal to 'equalTo'. This operation is both lock-free and atomic.
newval | The value to store. |
equalTo | The comparison value. |
true if the store occurred, false if not.