1import core.thread, core.memory, core.atomic; 2 3// test init 4shared uint gctor, gdtor, tctor, tdtor; 5shared static this() { if (atomicOp!"+="(gctor, 1) != 1) assert(0); } 6shared static ~this() { if (atomicOp!"+="(gdtor, 1) != 1) assert(0); } 7static this() { atomicOp!"+="(tctor, 1); } 8static ~this() { atomicOp!"+="(tdtor, 1); } 9 10// test GC 11__gshared Object root; 12void alloc() { root = new Object(); } 13void access() { assert(root.toString() !is null); } // vtbl call will fail if finalized 14void free() { root = null; } 15 16Object tls_root; 17void tls_alloc() { tls_root = new Object(); } 18void tls_access() { assert(tls_root.toString() !is null); } // vtbl call will fail if finalized 19void tls_free() { tls_root = null; } 20 21void 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 28void 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 43extern(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. 63import core.runtime : rt_init, rt_term; 64 65extern(C) int plugin_init() 66{ 67 return rt_init(); 68} 69 70extern(C) int plugin_term() 71{ 72 return rt_term(); 73} 74