Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

core.stdc.stdatomic

A D implementation of the C stdatomic.h header.
Note: If it compiles it should produce similar assembly to the system C toolchain and should not introduce when optimizing unnecessary behaviors, if you do not care about this guarantee use the impl suffix.
Note: The D shared type qualifier is the closest to the Atomic type qualifier from C. It may be changed from shared in the future.
Note: Fail memory order is currently ignored due to limitations with internal implementation of atomics.
Authors:
Richard (Rikki) Andrew cattermole
enum memory_order: MemoryOrder;
memory_order_relaxed
No ordering provided
memory_order_consume
As per cppreference.com circa 2015 no compiler supports consume memory order and in practice it devolves to acquire.
memory_order_acquire
Prevent reordering before operation
memory_order_release
Prevent reordering after operation
memory_order_acq_rel
Prevent reordering before and after operation
memory_order_seq_cst
Prevent reordering before for read operations and after for writes.
__STDC_VERSION_STDATOMIC_H__
ATOMIC_BOOL_LOCK_FREE
ATOMIC_CHAR_LOCK_FREE
ATOMIC_CHAR16_T_LOCK_FREE
ATOMIC_CHAR32_T_LOCK_FREE
ATOMIC_WCHAR_T_LOCK_FREE
ATOMIC_SHORT_LOCK_FREE
ATOMIC_INT_LOCK_FREE
ATOMIC_LONG_LOCK_FREE
ATOMIC_LLONG_LOCK_FREE
ATOMIC_POINTER_LOCK_FREE
ATOMIC_CHAR8_T_LOCK_FREE
alias atomic_signal_fence = atomic_signal_fence_impl()(memory_order order);
bool atomic_is_lock_free(A)(const shared(A)* obj);
struct atomic_flag;
Guaranteed to be a atomic boolean type
enum atomic_flag ATOMIC_FLAG_INIT;
void atomic_flag_clear_impl()(atomic_flag* obj);
void atomic_flag_clear_explicit_impl()(atomic_flag* obj, memory_order order);
bool atomic_flag_test_and_set_impl()(atomic_flag* obj);
Examples:
atomic_flag flag;
assert(!atomic_flag_test_and_set_impl(&flag));
atomic_flag_clear_impl(&flag);
bool atomic_flag_test_and_set_explicit_impl()(atomic_flag* obj, memory_order order);
Examples:
atomic_flag flag;
assert(!atomic_flag_test_and_set_explicit_impl(&flag, memory_order.memory_order_seq_cst));
atomic_flag_clear_explicit_impl(&flag, memory_order.memory_order_seq_cst);
@trusted void atomic_init(A, C)(out shared(A) obj, C desired);
Initializes an atomic variable, the destination should not have any expression associated with it prior to this call.
We use an out parameter instead of a pointer for destination in an attempt to communicate to the compiler that it initializers.
Examples:
shared int val;
atomic_init(val, 2);

shared float valF;
atomic_init(valF, 3.2);
@trusted A kill_dependency(A)(A y);
No-op function, doesn't apply to D
void atomic_signal_fence_impl()(memory_order order);
Don't allow reordering, does not emit any instructions.
Examples:
atomic_signal_fence_impl(memory_order.memory_order_seq_cst);
void atomic_thread_fence_impl()(memory_order order);
Don't allow reordering, and emit a fence instruction.
Examples:
atomic_thread_fence_impl(memory_order.memory_order_seq_cst);
alias atomic_bool = shared(bool);
alias atomic_char = shared(char);
alias atomic_schar = shared(byte);
alias atomic_uchar = shared(ubyte);
alias atomic_short = shared(short);
alias atomic_ushort = shared(ushort);
alias atomic_int = shared(int);
alias atomic_uint = shared(uint);
alias atomic_long = shared(long);
alias atomic_ulong = shared(ulong);
alias atomic_llong = shared(long);
alias atomic_ullong = shared(ulong);
alias atomic_char8_t = shared(char);
alias atomic_char16_t = shared(wchar);
alias atomic_char32_t = shared(dchar);
alias atomic_wchar_t = shared(dchar);
alias atomic_int_least8_t = shared(byte);
alias atomic_uint_least8_t = shared(ubyte);
alias atomic_int_least16_t = shared(short);
alias atomic_uint_least16_t = shared(ushort);
alias atomic_int_least32_t = shared(int);
alias atomic_uint_least32_t = shared(uint);
alias atomic_int_least64_t = shared(long);
alias atomic_uint_least64_t = shared(ulong);
alias atomic_int_fast8_t = shared(byte);
alias atomic_uint_fast8_t = shared(ubyte);
alias atomic_int_fast16_t = shared(long);
alias atomic_uint_fast16_t = shared(ulong);
alias atomic_int_fast32_t = shared(long);
alias atomic_uint_fast32_t = shared(ulong);
alias atomic_int_fast64_t = shared(long);
alias atomic_uint_fast64_t = shared(ulong);
alias atomic_intptr_t = shared(long);
alias atomic_uintptr_t = shared(ulong);
alias atomic_size_t = shared(ulong);
alias atomic_ptrdiff_t = shared(long);
alias atomic_intmax_t = shared(long);
alias atomic_uintmax_t = shared(ulong);
@trusted void atomic_store_impl(A, C)(shared(A)* obj, C desired);
Examples:
shared(int) obj;
atomic_store_impl(&obj, 3);

shared(float) objF;
atomic_store_impl(&objF, 3.21);
@trusted void atomic_store_explicit_impl(A, C)(shared(A)* obj, C desired, memory_order order);
Examples:
shared(int) obj;
atomic_store_explicit_impl(&obj, 3, memory_order.memory_order_seq_cst);

shared(float) objF;
atomic_store_explicit_impl(&objF, 3.21, memory_order.memory_order_seq_cst);
@trusted A atomic_load_impl(A)(const shared(A)* obj);
Examples:
shared(int) obj = 3;
assert(atomic_load_impl(&obj) == 3);

shared(float) objF = 3.5;
assert(atomic_load_impl(&objF) > 3);

static struct S2
{
    size_t[2] values;
}
align(S2.sizeof) shared(S2) objS2 = {[1, 2]};
assert(atomic_load_impl(&objS2).values == [1, 2]);
@trusted A atomic_load_explicit_impl(A)(const shared(A)* obj, memory_order order);
Examples:
shared(int) obj = 3;
assert(atomic_load_explicit_impl(&obj, memory_order.memory_order_seq_cst) == 3);

shared(float) objF = 3.5;
assert(atomic_load_explicit_impl(&objF, memory_order.memory_order_seq_cst) > 3);
@trusted A atomic_exchange_impl(A, C)(shared(A)* obj, C desired);
Examples:
shared(int) obj = 3;
assert(atomic_exchange_impl(&obj, 2) == 3);

shared(float) objF = 3;
assert(atomic_exchange_impl(&objF, 2.1) > 2.5);
@trusted A atomic_exchange_explicit_impl(A, C)(shared(A)* obj, C desired, memory_order order);
Examples:
shared(int) obj = 3;
assert(atomic_exchange_explicit_impl(&obj, 2, memory_order.memory_order_seq_cst) == 3);

shared(float) objF = 1.5;
assert(atomic_exchange_explicit_impl(&objF, 2.1, memory_order.memory_order_seq_cst) < 2);
@trusted bool atomic_compare_exchange_strong_impl(A, B, C)(shared(A)* obj, B* expected, C desired);
Examples:
shared(int) obj = 3;
int expected = 3;
assert(atomic_compare_exchange_strong_impl(&obj, &expected, 2));
Examples:
shared(float) obj = 3;
float expected = 3;
assert(atomic_compare_exchange_strong_impl(&obj, &expected, 2.1));
@trusted bool atomic_compare_exchange_weak_impl(A, B, C)(shared(A)* obj, B* expected, C desired);
Examples:
shared(int) obj = 3;
int expected = 3;
static assert(__traits(compiles, {atomic_compare_exchange_weak_impl(&obj, &expected, 2);}));
Examples:
shared(float) obj = 3;
float expected = 3;
static assert(__traits(compiles, {atomic_compare_exchange_weak_impl(&obj, &expected, 2.1);}));
@trusted bool atomic_compare_exchange_strong_explicit_impl(A, B, C)(shared(A)* obj, B* expected, C desired, memory_order succ, memory_order fail);
Examples:
shared(int) obj = 3;
int expected = 3;
assert(atomic_compare_exchange_strong_explicit_impl(&obj, &expected, 2, memory_order.memory_order_seq_cst, memory_order.memory_order_seq_cst));
Examples:
align(size_t[2].sizeof) shared(size_t[2]) obj = [3, 4];
size_t[2] expected = [3, 4];
size_t[2] toSwap = [1, 2];
assert(atomic_compare_exchange_strong_explicit_impl(&obj, &expected, toSwap, memory_order.memory_order_seq_cst, memory_order.memory_order_seq_cst));
Examples:
shared(float) obj = 3;
float expected = 3;
assert(atomic_compare_exchange_strong_explicit_impl(&obj, &expected, 2.1, memory_order.memory_order_seq_cst, memory_order.memory_order_seq_cst));
@trusted bool atomic_compare_exchange_weak_explicit_impl(A, B, C)(shared(A)* obj, B* expected, C desired, memory_order succ, memory_order fail);
Examples:
shared(int) obj = 3;
int expected = 3;
atomic_compare_exchange_weak_explicit_impl(&obj, &expected, 2, memory_order.memory_order_seq_cst, memory_order.memory_order_seq_cst);
Examples:
align(size_t[2].sizeof) shared(size_t[2]) obj = [3, 4];
size_t[2] expected = [3, 4];
size_t[2] toSwap = [1, 2];
assert(atomic_compare_exchange_weak_explicit_impl(&obj, &expected, toSwap, memory_order.memory_order_seq_cst, memory_order.memory_order_seq_cst));
Examples:
shared(float) obj = 3;
float expected = 3;
atomic_compare_exchange_weak_explicit_impl(&obj, &expected, 2, memory_order.memory_order_seq_cst, memory_order.memory_order_seq_cst);
@trusted A atomic_fetch_add_impl(A, M)(shared(A)* obj, M arg);
Examples:
shared(int) val;
atomic_fetch_add_impl(&val, 3);
assert(atomic_load_impl(&val) == 3);

shared(float) valF = 0.5;
atomic_fetch_add_impl(&valF, 3);
assert(atomic_load_impl(&valF) > 3);
@trusted A atomic_fetch_add_explicit_impl(A, M)(shared(A)* obj, M arg, memory_order order);
Examples:
shared(int) val;
atomic_fetch_add_explicit_impl(&val, 3, memory_order.memory_order_seq_cst);
assert(atomic_load_impl(&val) == 3);

shared(float) valF = 3;
atomic_fetch_add_explicit_impl(&valF, 3, memory_order.memory_order_seq_cst);
assert(atomic_load_impl(&valF) > 3);
@trusted A atomic_fetch_sub_explicit_impl(A, M)(shared(A)* obj, M arg, memory_order order);
Examples:
shared(int) val = 3;
atomic_fetch_sub_explicit_impl(&val, 3, memory_order.memory_order_seq_cst);
assert(atomic_load_impl(&val) == 0);

shared(float) valF = 4;
atomic_fetch_sub_explicit_impl(&valF, 3, memory_order.memory_order_seq_cst);
assert(atomic_load_impl(&valF) < 4);
@trusted A atomic_fetch_or_impl(A, M)(shared(A)* obj, M arg);
Examples:
shared(int) val = 5;
atomic_fetch_or_impl(&val, 3);
assert(atomic_load_impl(&val) == 7);
@trusted A atomic_fetch_or_explicit_impl(A, M)(shared(A)* obj, M arg, memory_order order);
Examples:
shared(int) val = 5;
atomic_fetch_or_explicit_impl(&val, 3, memory_order.memory_order_seq_cst);
assert(atomic_load_impl(&val) == 7);
@trusted A atomic_fetch_xor_impl(A, M)(shared(A)* obj, M arg);
Examples:
shared(int) val = 5;
atomic_fetch_xor_impl(&val, 3);
assert(atomic_load_impl(&val) == 6);
@trusted A atomic_fetch_xor_explicit_impl(A, M)(shared(A)* obj, M arg, memory_order order);
Examples:
shared(int) val = 5;
atomic_fetch_xor_explicit_impl(&val, 3, memory_order.memory_order_seq_cst);
assert(atomic_load_impl(&val) == 6);
@trusted A atomic_fetch_and_impl(A, M)(shared(A)* obj, M arg);
Examples:
shared(int) val = 5;
atomic_fetch_and_impl(&val, 3);
assert(atomic_load_impl(&val) == 1);
@trusted A atomic_fetch_and_explicit_impl(A, M)(shared(A)* obj, M arg, memory_order order);
Examples:
shared(int) val = 5;
atomic_fetch_and_explicit_impl(&val, 3, memory_order.memory_order_seq_cst);
assert(atomic_load_impl(&val) == 1);