1 module atomic;
2 import core.atomic;
3 
4 /**
5     Gets the status of atomics support in the current
6     numem configuration.
7 
8     Notes:
9         If atomics are not supported, these functions will
10         act as non-atomic alternatives.
11 
12     Returns:
13         Whether atomics are supported by the loaded
14         hookset.
15 */
16 export
17 extern(C)
18 bool nu_atomic_supported() @nogc nothrow {
19     return true;
20 }
21 
22 /**
23     Inserts a memory acquire barrier.
24 */
25 export
26 extern(C)
27 void nu_atomic_barrier_acquire() @nogc nothrow {
28     atomicFence!(MemoryOrder.acq)();
29 }
30 
31 /**
32     Inserts a memory release barrier.
33 */
34 export
35 extern(C)
36 void nu_atomic_barrier_release() @nogc nothrow {
37     atomicFence!(MemoryOrder.rel)();
38 }
39 
40 /**
41     Loads a 32 bit value atomically.
42 */
43 export
44 extern(C)
45 inout(uint) nu_atomic_load_32(ref inout(uint) src) @nogc nothrow {
46     return atomicLoad(src);
47 }
48 
49 /**
50     Stores a 32 bit value atomically.
51 */
52 export
53 extern(C)
54 void nu_atomic_store_32(ref uint dst, uint value) @nogc nothrow {
55     atomicStore(dst, value);
56 }
57 
58 /**
59     Adds a 32 bit value atomically.
60 */
61 export
62 extern(C)
63 extern uint nu_atomic_add_32(ref uint dst, uint value) @nogc nothrow {
64     return atomicFetchAdd(dst, value);
65 }
66 
67 /**
68     Subtracts a 32 bit value atomically.
69 */
70 export
71 extern(C)
72 extern uint nu_atomic_sub_32(ref uint dst, uint value) @nogc nothrow {
73     return atomicFetchSub(dst, value);
74 }
75 
76 /**
77     Loads a pointer value atomically.
78 */
79 export
80 extern(C)
81 extern inout(void)* nu_atomic_load_ptr(inout(void)** src) @nogc nothrow {
82     return cast(inout(void)*)atomicLoad(*cast(size_t*)src);
83 }
84 
85 /**
86     Stores a pointer value atomically.
87 */
88 export
89 extern(C)
90 extern void nu_atomic_store_ptr(void** dst, void* value) @nogc nothrow {
91     atomicStore(*dst, value);
92 }
93 
94 /**
95     Compares variable at $(D dst) and swaps it if it contains $(D oldvalue).
96 */
97 export
98 extern(C)
99 extern bool nu_atomic_cmpxhg_ptr(void** dst, void* oldvalue, void* value) @nogc nothrow {
100     if (atomicLoad(*dst) is oldvalue) {
101         atomicExchange(dst, value);
102         return true;
103     }
104     return false;
105 }