+
+/* ============================ C Public Interface ======================== */
+
+
+private int _termCleanupLevel=1;
+
+/// sets the cleanup level done by gc
+/// (0: none, 1: fullCollect, 2: fullCollectNoStack (might crash daemonThreads))
+/// result !=0 if the value was invalid
+extern (C) int gc_setTermCleanupLevel(int cLevel){
+ if (cLevel<0 || cLevel>2) return cLevel;
+ _termCleanupLevel=cLevel;
+ return 0;
+}
+
+/// returns the cleanup level done by gc
+extern (C) int gc_getTermCleanupLevel(){
+ return _termCleanupLevel;
+}
+
+version (DigitalMars) version(OSX) {
+ extern(C) void _d_osx_image_init();
+}
+
+extern (C) void thread_init();
+
+extern (C) void gc_init()
+{
+ scope (exit) assert (Invariant());
+ gc = cast(GC*) cstdlib.calloc(1, GC.sizeof);
+ *gc = GC.init;
+ initialize();
+ version (DigitalMars) version(OSX) {
+ _d_osx_image_init();
+ }
+ // NOTE: The GC must initialize the thread library
+ // before its first collection.
+ thread_init();
+}
+
+extern (C) void gc_term()
+{
+ assert (Invariant());
+ if (_termCleanupLevel<1) {
+ // no cleanup
+ } else if (_termCleanupLevel==2){
+ // a more complete cleanup
+ // NOTE: There may be daemons threads still running when this routine is
+ // called. If so, cleaning memory out from under then is a good
+ // way to make them crash horribly.
+ // Often this probably doesn't matter much since the app is
+ // supposed to be shutting down anyway, but for example tests might
+ // crash (and be considerd failed even if the test was ok).
+ // thus this is not the default and should be enabled by
+ // I'm disabling cleanup for now until I can think about it some
+ // more.
+ //
+ fullCollectNoStack(); // not really a 'collect all' -- still scans
+ // static data area, roots, and ranges.
+ } else {
+ // default (safe) clenup
+ fullCollect();
+ }
+}
+
+extern (C) void gc_enable()
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ enable();
+}
+
+extern (C) void gc_disable()
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ disable();
+}
+
+extern (C) void gc_collect()
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ fullCollect();
+}
+
+
+extern (C) void gc_minimize()
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ minimize();
+}
+
+extern (C) uint gc_getAttr( void* p )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return getAttr(p);
+}
+
+extern (C) uint gc_setAttr( void* p, uint a )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return setAttr(p, a);
+}
+
+extern (C) uint gc_clrAttr( void* p, uint a )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return clrAttr(p, a);
+}
+
+extern (C) void* gc_malloc(size_t sz, uint attrs = 0,
+ PointerMap ptrmap = PointerMap.init)
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return malloc(sz, attrs, ptrmap);
+}
+
+extern (C) void* gc_calloc(size_t sz, uint attrs = 0,
+ PointerMap ptrmap = PointerMap.init)
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return calloc(sz, attrs, ptrmap);
+}
+
+extern (C) void* gc_realloc(void* p, size_t sz, uint attrs = 0,
+ PointerMap ptrmap = PointerMap.init)
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return realloc(p, sz, attrs, ptrmap);
+}
+
+extern (C) size_t gc_extend( void* p, size_t mx, size_t sz )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return extend(p, mx, sz);
+}
+
+extern (C) size_t gc_reserve( size_t sz )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return reserve(sz);
+}
+
+extern (C) void gc_free( void* p )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ free(p);
+}
+
+extern (C) void* gc_addrOf( void* p )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return addrOf(p);
+}
+
+extern (C) size_t gc_sizeOf( void* p )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return sizeOf(p);
+}
+
+extern (C) BlkInfo gc_query( void* p )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return query(p);
+}
+
+// NOTE: This routine is experimental. The stats or function name may change
+// before it is made officially available.
+extern (C) GCStats gc_stats()
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ GCStats stats = void;
+ getStats(stats);
+ return stats;
+}
+
+extern (C) void gc_addRoot( void* p )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ addRoot(p);
+}
+
+extern (C) void gc_addRange( void* p, size_t sz )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ addRange(p, sz);
+}
+
+extern (C) void gc_removeRoot( void *p )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ removeRoot(p);
+}
+
+extern (C) void gc_removeRange( void *p )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ removeRange(p);
+}
+
+extern (C) void* gc_weakpointerCreate( Object r )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return weakpointerCreate(r);
+}
+
+extern (C) void gc_weakpointerDestroy( void* wp )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ weakpointerDestroy(wp);
+}
+
+extern (C) Object gc_weakpointerGet( void* wp )
+{
+ assert (Invariant()); scope (exit) assert (Invariant());
+ return weakpointerGet(wp);
+}
+
+