1 module libd.threading.atomic;
2 
3 nothrow @nogc pure:
4 
5 private extern(C) bool atomicCas8(ubyte* ifThis, ubyte equalsThis, ubyte setThis);
6 private extern(C) bool atomicCas16(ushort* ifThis, ushort equalsThis, ushort setThis);
7 private extern(C) bool atomicCas32(uint* ifThis, uint equalsThis, uint setThis);
8 private extern(C) bool atomicCas64(ulong* ifThis, ulong equalsThis, ulong setThis);
9 
10 private extern(C) void atomicStore8(ubyte* dest, ubyte source);
11 private extern(C) void atomicStore16(ushort* dest, ushort source);
12 private extern(C) void atomicStore32(uint* dest, uint source);
13 private extern(C) void atomicStore64(ulong* dest, ulong source);
14 
15 private extern(C) ubyte atomicLoad8(ubyte* value);
16 private extern(C) ushort atomicLoad16(ushort* value);
17 private extern(C) uint atomicLoad32(uint* value);
18 private extern(C) ulong atomicLoad64(ulong* value);
19 
20 @trusted
21 bool atomicCas(T)(shared ref T ifThis, T equalsThis, T setItToThis)
22 {
23     static if(T.sizeof == 1)
24         return atomicCas8(cast(ubyte*)&ifThis, cast(ubyte)equalsThis, cast(ubyte)setItToThis);
25     else static if(T.sizeof == 2)
26         return atomicCas16(cast(ushort*)&ifThis, cast(ushort)equalsThis, cast(ushort)setItToThis);
27     else static if(T.sizeof == 4)
28         return atomicCas32(cast(uint*)&ifThis, cast(uint)equalsThis, cast(uint)setItToThis);
29     else static if(T.sizeof == 8)
30         return atomicCas16(cast(ulong*)&ifThis, cast(ulong)equalsThis, cast(ulong)setItToThis);
31     else
32         static assert(false, "Cannot use "~T.stringof~" with CAS.");
33 }
34 
35 @trusted
36 void atomicStore(T)(shared ref T intoThis, T storeThis)
37 {
38     static if(T.sizeof == 1)
39         return atomicStore8(cast(ubyte*)&intoThis, cast(ubyte)storeThis);
40     else static if(T.sizeof == 2)
41         return atomicStore16(cast(ushort*)&intoThis, cast(ushort)storeThis);
42     else static if(T.sizeof == 4)
43         return atomicStore32(cast(uint*)&intoThis, cast(uint)storeThis);
44     else static if(T.sizeof == 8)
45         return atomicStore16(cast(ulong*)&intoThis, cast(ulong)storeThis);
46     else
47         static assert(false, "Cannot use "~T.stringof~" with XCHG.");
48 }
49 
50 @trusted
51 T atomicLoad(T)(shared ref T value)
52 {
53     static if(T.sizeof == 1)
54         return cast(T)atomicLoad8(cast(ubyte*)&value);
55     else static if(T.sizeof == 2)
56         return cast(T)atomicLoad16(cast(ushort*)&value);
57     else static if(T.sizeof == 4)
58         return cast(T)atomicLoad32(cast(uint*)&value);
59     else static if(T.sizeof == 8)
60         return cast(T)atomicLoad16(cast(ulong*)&value);
61     else
62         static assert(false, "Cannot use "~T.stringof~" with XCHG.");
63 }