///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
testType!(bool)(); testType!(byte)(); testType!(ubyte)(); testType!(short)(); testType!(ushort)(); testType!(int)(); testType!(uint)();
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
1 testType!(shared int*)(); 2 3 static interface Inter {} 4 static class KlassImpl : Inter {} 5 testXCHG!(shared Inter)(new shared(KlassImpl)); 6 testCAS!(shared Inter)(new shared(KlassImpl)); 7 8 static class Klass {} 9 testXCHG!(shared Klass)(new shared(Klass)); 10 testCAS!(shared Klass)(new shared(Klass)); 11 12 testXCHG!(shared int)(42); 13 14 testType!(float)(0.1f); 15 16 static if (has64BitCAS) 17 { 18 testType!(double)(0.1); 19 testType!(long)(); 20 testType!(ulong)(); 21 } 22 static if (has128BitCAS) 23 { 24 () @trusted 25 { 26 align(16) struct Big { long a, b; } 27 28 shared(Big) atom; 29 shared(Big) base; 30 shared(Big) arg; 31 shared(Big) val = Big(1, 2); 32 33 assert(cas(&atom, arg, val), Big.stringof); 34 assert(atom is val, Big.stringof); 35 assert(!cas(&atom, arg, val), Big.stringof); 36 assert(atom is val, Big.stringof); 37 38 atom = Big(); 39 assert(cas(&atom, &arg, val), Big.stringof); 40 assert(arg is base, Big.stringof); 41 assert(atom is val, Big.stringof); 42 43 arg = Big(); 44 assert(!cas(&atom, &arg, base), Big.stringof); 45 assert(arg is val, Big.stringof); 46 assert(atom is val, Big.stringof); 47 }(); 48 } 49 50 shared(size_t) i; 51 52 atomicOp!"+="(i, cast(size_t) 1); 53 assert(i == 1); 54 55 atomicOp!"-="(i, cast(size_t) 1); 56 assert(i == 0); 57 58 shared float f = 0.1f; 59 atomicOp!"+="(f, 0.1f); 60 assert(f > 0.1999f && f < 0.2001f); 61 62 static if (has64BitCAS) 63 { 64 shared double d = 0.1; 65 atomicOp!"+="(d, 0.1); 66 assert(d > 0.1999 && d < 0.2001); 67 }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
static if (has128BitCAS) { struct DoubleValue { long value1; long value2; } align(16) shared DoubleValue a; atomicStore(a, DoubleValue(1,2)); assert(a.value1 == 1 && a.value2 ==2); while (!cas(&a, DoubleValue(1,2), DoubleValue(3,4))){} assert(a.value1 == 3 && a.value2 ==4); align(16) DoubleValue b = atomicLoad(a); assert(b.value1 == 3 && b.value2 ==4); } static if (hasDWCAS) { static struct List { size_t gen; List* next; } shared(List) head; assert(cas(&head, shared(List)(0, null), shared(List)(1, cast(List*)1))); assert(head.gen == 1); assert(cast(size_t)head.next == 1); } // https://issues.dlang.org/show_bug.cgi?id=20629 static struct Struct { uint a, b; } shared Struct s1 = Struct(1, 2); atomicStore(s1, Struct(3, 4)); assert(cast(uint) s1.a == 3); assert(cast(uint) s1.b == 4);
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
int a; if (casWeak!(MemoryOrder.acq_rel, MemoryOrder.raw)(&a, 0, 4)) assert(a == 4);
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// https://issues.dlang.org/show_bug.cgi?id=17821 { shared ulong x = 0x1234_5678_8765_4321; atomicStore(x, 0); assert(x == 0); } { struct S { ulong x; alias x this; } shared S s; s = 0x1234_5678_8765_4321; atomicStore(s, 0); assert(s.x == 0); } { abstract class Logger {} shared Logger s1; Logger s2; atomicStore(s1, cast(shared) s2); }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
static struct S { int val; } auto s = shared(S)(1); shared(S*) ptr; // head unshared shared(S)* ifThis = null; shared(S)* writeThis = &s; assert(ptr is null); assert(cas(&ptr, ifThis, writeThis)); assert(ptr is writeThis); // head shared shared(S*) ifThis2 = writeThis; shared(S*) writeThis2 = null; assert(cas(&ptr, ifThis2, writeThis2)); assert(ptr is null);
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
shared ubyte u8 = 1; shared ushort u16 = 2; shared uint u32 = 3; shared byte i8 = 5; shared short i16 = 6; shared int i32 = 7; assert(atomicOp!"+="(u8, 8) == 9); assert(atomicOp!"+="(u16, 8) == 10); assert(atomicOp!"+="(u32, 8) == 11); assert(atomicOp!"+="(i8, 8) == 13); assert(atomicOp!"+="(i16, 8) == 14); assert(atomicOp!"+="(i32, 8) == 15); version (D_LP64) { shared ulong u64 = 4; shared long i64 = 8; assert(atomicOp!"+="(u64, 8) == 12); assert(atomicOp!"+="(i64, 8) == 16); }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
byte[10] byteArray = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]; ulong[10] ulongArray = [2, 4, 6, 8, 10, 12, 14, 16, 19, 20]; { auto array = byteArray; byte* ptr = &array[0]; byte* prevPtr = atomicFetchAdd(ptr, 3); assert(prevPtr == &array[0]); assert(*prevPtr == 1); assert(*ptr == 7); } { auto array = ulongArray; ulong* ptr = &array[0]; ulong* prevPtr = atomicFetchAdd(ptr, 3); assert(prevPtr == &array[0]); assert(*prevPtr == 2); assert(*ptr == 8); }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
shared ubyte u8 = 1; shared ushort u16 = 2; shared uint u32 = 3; shared byte i8 = 5; shared short i16 = 6; shared int i32 = 7; assert(atomicOp!"-="(u8, 1) == 0); assert(atomicOp!"-="(u16, 1) == 1); assert(atomicOp!"-="(u32, 1) == 2); assert(atomicOp!"-="(i8, 1) == 4); assert(atomicOp!"-="(i16, 1) == 5); assert(atomicOp!"-="(i32, 1) == 6); version (D_LP64) { shared ulong u64 = 4; shared long i64 = 8; assert(atomicOp!"-="(u64, 1) == 3); assert(atomicOp!"-="(i64, 1) == 7); }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
byte[10] byteArray = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]; ulong[10] ulongArray = [2, 4, 6, 8, 10, 12, 14, 16, 19, 20]; { auto array = byteArray; byte* ptr = &array[5]; byte* prevPtr = atomicFetchSub(ptr, 4); assert(prevPtr == &array[5]); assert(*prevPtr == 11); assert(*ptr == 3); // https://issues.dlang.org/show_bug.cgi?id=21578 } { auto array = ulongArray; ulong* ptr = &array[5]; ulong* prevPtr = atomicFetchSub(ptr, 4); assert(prevPtr == &array[5]); assert(*prevPtr == 12); assert(*ptr == 4); // https://issues.dlang.org/show_bug.cgi?id=21578 }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
shared ulong a = 2; uint b = 1; atomicOp!"-="(a, b); assert(a == 1); shared uint c = 2; ubyte d = 1; atomicOp!"-="(c, d); assert(c == 1);
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
shared int i; static assert(is(typeof(atomicLoad(i)) == int)); shared int* p; static assert(is(typeof(atomicLoad(p)) == shared(int)*)); shared int[] a; static if (__traits(compiles, atomicLoad(a))) { static assert(is(typeof(atomicLoad(a)) == shared(int)[])); } static struct S { int* _impl; } shared S s; static assert(is(typeof(atomicLoad(s)) : shared S)); static assert(is(typeof(atomicLoad(s)._impl) == shared(int)*)); auto u = atomicLoad(s); assert(u._impl is null); u._impl = new shared int(42); assert(atomicLoad(*u._impl) == 42); static struct S2 { S s; } shared S2 s2; static assert(is(typeof(atomicLoad(s2).s) == TailShared!S)); static struct S3 { size_t head; int* tail; } shared S3 s3; static if (__traits(compiles, atomicLoad(s3))) { static assert(is(typeof(atomicLoad(s3).head) == size_t)); static assert(is(typeof(atomicLoad(s3).tail) == shared(int)*)); } static class C { int i; } shared C c; static assert(is(typeof(atomicLoad(c)) == shared C)); static struct NoIndirections { int i; } shared NoIndirections n; static assert(is(typeof(atomicLoad(n)) == NoIndirections));
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
shared uint si1 = 45; shared uint si2 = 38; shared uint* psi = &si1; assert((&psi).cas(cast(const) psi, &si2));
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////