1 import core.thread, core.memory, core.atomic; 2 3 // test init 4 shared uint gctor, gdtor, tctor, tdtor; 5 shared static this() { if (atomicOp!"+="(gctor, 1) != 1) assert(0); } 6 shared static ~this() { if (atomicOp!"+="(gdtor, 1) != 1) assert(0); } 7 static this() { atomicOp!"+="(tctor, 1); } 8 static ~this() { atomicOp!"+="(tdtor, 1); } 9 10 // test GC 11 __gshared Object root; 12 void alloc() { root = new Object(); } 13 void access() { assert(root.toString() !is null); } // vtbl call will fail if finalized 14 void free() { root = null; } 15 16 Object tls_root; 17 void tls_alloc() { tls_root = new Object(); } 18 void tls_access() { assert(tls_root.toString() !is null); } // vtbl call will fail if finalized 19 void tls_free() { tls_root = null; } 20 21 void stack(alias func)() 22 { 23 // allocate some extra stack space to not keep references to GC memory on the scanned stack 24 ubyte[1024] buf = void; 25 func(); 26 } 27 28 void testGC() 29 { 30 import core.memory; 31 32 stack!alloc(); 33 stack!tls_alloc(); 34 stack!access(); 35 stack!tls_access(); 36 GC.collect(); 37 stack!tls_access(); 38 stack!access(); 39 stack!tls_free(); 40 stack!free(); 41 } 42 43 extern(C) int runTests() 44 { 45 try 46 { 47 assert(atomicLoad!(MemoryOrder.acq)(gctor) == 1); 48 assert(atomicLoad!(MemoryOrder.acq)(gdtor) == 0); 49 assert(atomicLoad!(MemoryOrder.acq)(tctor) >= 1); 50 assert(atomicLoad!(MemoryOrder.acq)(tdtor) >= 0); 51 // test some runtime functionality 52 testGC(); 53 new Thread(&testGC).start.join; 54 } 55 catch (Throwable) 56 { 57 return false; 58 } 59 return true; 60 } 61 62 // Provide a way to initialize D from C programs that are D agnostic. 63 import core.runtime : rt_init, rt_term; 64 65 extern(C) int plugin_init() 66 { 67 return rt_init(); 68 } 69 70 extern(C) int plugin_term() 71 { 72 return rt_term(); 73 } 74