extern (C) bool rt_term( ExceptionHandler dg = null );
extern (C) void* rt_loadLibrary( in char[] name );
- extern (C) void rt_unloadLibrary( void* ptr );
+ extern (C) bool rt_unloadLibrary( void* ptr );
}
* Params:
* p = A reference to the library to unload.
*/
- static void unloadLibrary( void* p )
+ static bool unloadLibrary( void* p )
{
- rt_unloadLibrary( p );
+ return rt_unloadLibrary( p );
}
private
{
+ import memory;
import util.console;
import core.stdc.stddef;
import core.stdc.stdlib;
*/
extern (C)
{
- void* gc_getHandle();
- void gc_setHandle(void* p);
- void gc_clrHandle();
+ void* gc_getProxy();
+ void gc_setProxy(void* p);
+ void gc_clrProxy();
alias void* function() gcGetFn;
alias void function(void*) gcSetFn;
alias void function() gcClrFn;
- alias bool function(ExceptionHandler dg = null) rtInitFn;
- alias bool function(ExceptionHandler dg = null) rtTermFn;
}
extern (C) void* rt_loadLibrary(in char[] name)
void* ptr = LoadLibraryA(temp.ptr);
if (ptr is null)
return ptr;
- gcSetFn gcSet = cast(gcSetFn) GetProcAddress(ptr, "_gc_setHandle");
- rtInitFn rtInit = cast(rtInitFn) GetProcAddress(ptr, "_rt_init");
- if (gcSet is null || rtInit is null)
- return ptr;
- gcSet(gc_getHandle());
- rtInit();
+ gcSetFn gcSet = cast(gcSetFn) GetProcAddress(ptr, "gc_setProxy");
+ if (gcSet !is null)
+ gcSet(gc_getProxy());
return ptr;
}
}
}
-extern (C) void rt_unloadLibrary(void* ptr)
+extern (C) bool rt_unloadLibrary(void* ptr)
{
version (Windows)
{
- gcClrFn gcClr = cast(gcClrFn) GetProcAddress(ptr, "_gc_clrHandle");
- rtTermFn rtTerm = cast(rtTermFn) GetProcAddress(ptr, "_rt_term");
-
- if (gcClr !is null && rtTerm !is null)
- {
- rtTerm();
+ gcClrFn gcClr = cast(gcClrFn) GetProcAddress(ptr, "gc_clrProxy");
+ if (gcClr !is null)
gcClr();
- }
return FreeLibrary(ptr) != 0;
}
else version (linux)
try
{
gc_init();
+ initStaticDataGC();
version (Windows)
_minit();
_moduleCtor();
void runAll()
{
gc_init();
+ initStaticDataGC();
version (Windows)
_minit();
_moduleCtor();
extern (C) extern void* __libc_stack_end;
}
}
+ extern (C) void gc_addRange( void* p, size_t sz );
+ extern (C) void gc_removeRange( void *p );
}
alias __data_start Data_Start;
alias _end Data_End;
}
-
- alias void delegate( void*, void* ) scanFn;
}
-/**
- *
- */
-extern (C) void rt_scanStaticData( scanFn scan )
-{
- scan(rt_staticDataBottom(), rt_staticDataTop());
-}
-
-/**
- *
- */
-extern (C) void* rt_staticDataBottom()
-{
- version( Windows )
- {
- return &_xi_a;
- }
- else version( linux )
- {
- return &__data_start;
- }
- else
- {
- static assert( false, "Operating system not supported." );
- }
-}
-
-/**
- *
- */
-extern (C) void* rt_staticDataTop()
+void initStaticDataGC()
{
version( Windows )
{
- return &_end;
+ gc_addRange( &_xi_a, &_end - &_xi_a );
}
else version( linux )
{
- return &_end;
+ gc_addRange( &__data_start, &_end - &__data_start );
}
else
{
extern (C) void gc_enable()
{
- _gc.enable();
+ if( proxy is null )
+ return _gc.enable();
+ return proxy.gc_enable();
}
extern (C) void gc_disable()
{
- _gc.disable();
+ if( proxy is null )
+ return _gc.disable();
+ return proxy.gc_disable();
}
extern (C) void gc_collect()
{
- _gc.fullCollect();
+ if( proxy is null )
+ return _gc.fullCollect();
+ return proxy.gc_collect();
}
extern (C) void gc_minimize()
{
- _gc.minimize();
+ if( proxy is null )
+ return _gc.minimize();
+ return proxy.gc_minimize();
}
extern (C) uint gc_getAttr( void* p )
{
- return _gc.getAttr( p );
+ if( proxy is null )
+ return _gc.getAttr( p );
+ return proxy.gc_getAttr( p );
}
extern (C) uint gc_setAttr( void* p, uint a )
{
- return _gc.setAttr( p, a );
+ if( proxy is null )
+ return _gc.setAttr( p, a );
+ return proxy.gc_setAttr( p, a );
}
extern (C) uint gc_clrAttr( void* p, uint a )
{
- return _gc.clrAttr( p, a );
+ if( proxy is null )
+ return _gc.clrAttr( p, a );
+ return proxy.gc_clrAttr( p, a );
}
extern (C) void* gc_malloc( size_t sz, uint ba = 0 )
{
- return _gc.malloc( sz, ba );
+ if( proxy is null )
+ return _gc.malloc( sz, ba );
+ return proxy.gc_malloc( sz, ba );
}
extern (C) void* gc_calloc( size_t sz, uint ba = 0 )
{
- return _gc.calloc( sz, ba );
+ if( proxy is null )
+ return _gc.calloc( sz, ba );
+ return proxy.gc_calloc( sz, ba );
}
extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0 )
{
- return _gc.realloc( p, sz, ba );
+ if( proxy is null )
+ return _gc.realloc( p, sz, ba );
+ return proxy.gc_realloc( p, sz, ba );
}
extern (C) size_t gc_extend( void* p, size_t mx, size_t sz )
{
- return _gc.extend( p, mx, sz );
+ if( proxy is null )
+ return _gc.extend( p, mx, sz );
+ return proxy.gc_extend( p, mx, sz );
}
extern (C) size_t gc_reserve( size_t sz )
{
- return _gc.reserve( sz );
+ if( proxy is null )
+ return _gc.reserve( sz );
+ return proxy.gc_reserve( sz );
}
extern (C) void gc_free( void* p )
{
- _gc.free( p );
+ if( proxy is null )
+ return _gc.free( p );
+ return proxy.gc_free( p );
}
extern (C) void* gc_addrOf( void* p )
{
- return _gc.addrOf( p );
+ if( proxy is null )
+ return _gc.addrOf( p );
+ return proxy.gc_addrOf( p );
}
extern (C) size_t gc_sizeOf( void* p )
{
- return _gc.sizeOf( p );
+ if( proxy is null )
+ return _gc.sizeOf( p );
+ return proxy.gc_sizeOf( p );
}
extern (C) BlkInfo gc_query( void* p )
{
- return _gc.query( p );
+ if( proxy is null )
+ return _gc.query( p );
+ return proxy.gc_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()
{
- GCStats stats = void;
- _gc.getStats( stats );
- return stats;
+ if( proxy is null )
+ {
+ GCStats stats = void;
+ _gc.getStats( stats );
+ return stats;
+ }
+ // TODO: Add proxy support for this once the layout of GCStats is
+ // finalized.
+ //return proxy.gc_stats();
+ return GCStats.init;
}
extern (C) void gc_addRoot( void* p )
{
- _gc.addRoot( p );
+ if( proxy is null )
+ return _gc.addRoot( p );
+ return proxy.gc_addRoot( p );
}
extern (C) void gc_addRange( void* p, size_t sz )
{
- _gc.addRange( p, sz );
+ if( proxy is null )
+ return _gc.addRange( p, sz );
+ return proxy.gc_addRange( p, sz );
}
-extern (C) void gc_removeRoot( void *p )
+extern (C) void gc_removeRoot( void* p )
{
- _gc.removeRoot( p );
+ if( proxy is null )
+ return _gc.removeRoot( p );
+ return proxy.gc_removeRoot( p );
}
-extern (C) void gc_removeRange( void *p )
+extern (C) void gc_removeRange( void* p )
{
- _gc.removeRange( p );
+ if( proxy is null )
+ return _gc.removeRange( p );
+ return proxy.gc_removeRange( p );
}
-extern (C) void* gc_getHandle()
+struct Proxy
{
- return cast(void*)_gc;
+ extern (C) void function() gc_enable;
+ extern (C) void function() gc_disable;
+ extern (C) void function() gc_collect;
+ extern (C) void function() gc_minimize;
+
+ extern (C) uint function(void*) gc_getAttr;
+ extern (C) uint function(void*, uint) gc_setAttr;
+ extern (C) uint function(void*, uint) gc_clrAttr;
+
+ extern (C) void* function(size_t, uint) gc_malloc;
+ extern (C) void* function(size_t, uint) gc_calloc;
+ extern (C) void* function(void*, size_t, uint ba) gc_realloc;
+ extern (C) size_t function(void*, size_t, size_t) gc_extend;
+ extern (C) size_t function(size_t) gc_reserve;
+ extern (C) void function(void*) gc_free;
+
+ extern (C) void* function(void*) gc_addrOf;
+ extern (C) size_t function(void*) gc_sizeOf;
+
+ extern (C) BlkInfo function(void*) gc_query;
+
+ extern (C) void function(void*) gc_addRoot;
+ extern (C) void function(void*, size_t) gc_addRange;
+
+ extern (C) void function(void*) gc_removeRoot;
+ extern (C) void function(void*) gc_removeRange;
}
-extern (C) void gc_setHandle(void* p)
+Proxy pthis;
+Proxy* proxy;
+
+static this()
{
- void* oldp = gc_getHandle();
- gc_t g = cast(gc_t)p;
- if (g.gcversion != gcx.GCVERSION)
- throw new Error("incompatible gc versions");
+ pthis.gc_enable = &gc_enable;
+ pthis.gc_disable = &gc_disable;
+ pthis.gc_collect = &gc_collect;
+ pthis.gc_minimize = &gc_minimize;
+
+ pthis.gc_getAttr = &gc_getAttr;
+ pthis.gc_setAttr = &gc_setAttr;
+ pthis.gc_clrAttr = &gc_clrAttr;
+
+ pthis.gc_malloc = &gc_malloc;
+ pthis.gc_calloc = &gc_calloc;
+ pthis.gc_realloc = &gc_realloc;
+ pthis.gc_extend = &gc_extend;
+ pthis.gc_reserve = &gc_reserve;
+ pthis.gc_free = &gc_free;
- // Add our static data to the new gc
- GC.scanStaticData(g);
+ pthis.gc_addrOf = &gc_addrOf;
+ pthis.gc_sizeOf = &gc_sizeOf;
- _gc = g;
+ pthis.gc_query = &gc_query;
+
+ pthis.gc_addRoot = &gc_addRoot;
+ pthis.gc_addRange = &gc_addRange;
+
+ pthis.gc_removeRoot = &gc_removeRoot;
+ pthis.gc_removeRange = &gc_removeRange;
+}
+
+extern (C) Proxy* gc_getProxy()
+{
+ return &pthis;
+}
+
+export extern (C) void gc_setProxy( Proxy* p )
+{
+ if( proxy !is null )
+ {
+ // TODO: Decide if this is an error condition.
+ }
+ proxy = p;
+ // TODO: Add known ranges and roots to the proxy.
}
-extern (C) void gc_endHandle()
+export extern (C) void gc_clrProxy()
{
- GC.unscanStaticData(_gc);
+ // TODO: Remove known ranges and roots from the proxy.
+ proxy = null;
}
extern (C) void* rt_stackBottom();
extern (C) void* rt_stackTop();
- extern (C) void* rt_staticDataBottom();
- extern (C) void* rt_staticDataTop();
extern (C) void rt_finalize( void* p, bool det = true );
- alias void delegate( void*, void* ) scanFn;
-
- extern (C) void rt_scanStaticData( scanFn scan );
-
version (MULTI_THREADED)
{
extern (C) bool thread_needLock();
extern (C) void thread_suspendAll();
extern (C) void thread_resumeAll();
+ alias void delegate( void*, void* ) scanFn;
extern (C) void thread_scanAll( scanFn fn, void* curStackTop = null );
}
}
- static void scanStaticData(gc_t g)
- {
- //debug(PRINTF) printf("+GC.scanStaticData()\n");
- auto pbot = rt_staticDataBottom();
- auto ptop = rt_staticDataTop();
- g.addRange(pbot, ptop - pbot);
- //debug(PRINTF) printf("-GC.scanStaticData()\n");
- }
-
- static void unscanStaticData(gc_t g)
- {
- auto pbot = rt_staticDataBottom();
- g.removeRange(pbot);
- }
-
/**
* add p to list of roots
*/
pool.mark.copy(&pool.freebits);
}
- rt_scanStaticData( &mark );
-
version (MULTI_THREADED)
{
if (!noStack)
extern (C) void gc_enable()
{
-
+ if( proxy is null )
+ return;
+ return proxy.gc_enable();
}
extern (C) void gc_disable()
{
-
+ if( proxy is null )
+ return;
+ return proxy.gc_disable();
}
extern (C) void gc_collect()
{
-
+ if( proxy is null )
+ return;
+ return proxy.gc_collect();
}
extern (C) void gc_minimize()
{
-
+ if( proxy is null )
+ return;
+ return proxy.gc_minimize();
}
extern (C) uint gc_getAttr( void* p )
{
- return 0;
+ if( proxy is null )
+ return 0;
+ return proxy.gc_getAttr( p );
}
extern (C) uint gc_setAttr( void* p, uint a )
{
- return 0;
+ if( proxy is null )
+ return 0;
+ return proxy.gc_setAttr( p, a );
}
extern (C) uint gc_clrAttr( void* p, uint a )
{
- return 0;
+ if( proxy is null )
+ return 0;
+ return proxy.gc_clrAttr( p, a );
}
extern (C) void* gc_malloc( size_t sz, uint ba = 0 )
{
- void* p = malloc( sz );
+ if( proxy is null )
+ {
+ void* p = malloc( sz );
- if( sz && p is null )
- onOutOfMemoryError();
- return p;
+ if( sz && p is null )
+ onOutOfMemoryError();
+ return p;
+ }
+ return proxy.gc_malloc( sz, ba );
}
extern (C) void* gc_calloc( size_t sz, uint ba = 0 )
{
- void* p = calloc( 1, sz );
+ if( proxy is null )
+ {
+ void* p = calloc( 1, sz );
- if( sz && p is null )
- onOutOfMemoryError();
- return p;
+ if( sz && p is null )
+ onOutOfMemoryError();
+ return p;
+ }
+ return proxy.gc_calloc( sz, ba );
}
extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0 )
{
- p = realloc( p, sz );
+ if( proxy is null )
+ {
+ p = realloc( p, sz );
- if( sz && p is null )
- onOutOfMemoryError();
- return p;
+ if( sz && p is null )
+ onOutOfMemoryError();
+ return p;
+ }
+ return proxy.gc_realloc( p, sz, ba );
}
extern (C) size_t gc_extend( void* p, size_t mx, size_t sz )
{
- return 0;
+ if( proxy is null )
+ return 0;
+ return proxy.gc_extend( p, mx, sz );
}
extern (C) size_t gc_reserve( size_t sz )
{
- return 0;
+ if( proxy is null )
+ return 0;
+ return proxy.gc_reserve( sz );
}
extern (C) void gc_free( void* p )
{
- free( p );
+ if( proxy is null )
+ return free( p );
+ return proxy.gc_free( p );
}
extern (C) void* gc_addrOf( void* p )
{
- return null;
+ if( proxy is null )
+ return null;
+ return proxy.gc_addrOf( p );
}
extern (C) size_t gc_sizeOf( void* p )
{
- return 0;
+ if( proxy is null )
+ return 0;
+ return proxy.gc_sizeOf( p );
}
extern (C) BlkInfo gc_query( void* p )
{
- return BlkInfo.init;
+ if( proxy is null )
+ return BlkInfo.init;
+ return proxy.gc_query( p );
}
+// TODO: Implement range storage.
+// TODO: Implement root storage.
+
extern (C) void gc_addRoot( void* p )
{
-
+ if( proxy is null )
+ return;
+ return proxy.gc_addRoot( p );
}
extern (C) void gc_addRange( void* p, size_t sz )
{
-
+ if( proxy is null )
+ return;
+ return proxy.gc_addRange( p, sz );
}
extern (C) void gc_removeRoot( void *p )
{
-
+ if( proxy is null )
+ return;
+ return proxy.gc_removeRoot( p );
}
extern (C) void gc_removeRange( void *p )
{
+ if( proxy is null )
+ return;
+ return proxy.gc_removeRange( p );
+}
+
+struct Proxy
+{
+ extern (C) void function() gc_enable;
+ extern (C) void function() gc_disable;
+ extern (C) void function() gc_collect;
+ extern (C) void function() gc_minimize;
+
+ extern (C) uint function(void*) gc_getAttr;
+ extern (C) uint function(void*, uint) gc_setAttr;
+ extern (C) uint function(void*, uint) gc_clrAttr;
+
+ extern (C) void* function(size_t, uint) gc_malloc;
+ extern (C) void* function(size_t, uint) gc_calloc;
+ extern (C) void* function(void*, size_t, uint ba) gc_realloc;
+ extern (C) size_t function(void*, size_t, size_t) gc_extend;
+ extern (C) size_t function(size_t) gc_reserve;
+ extern (C) void function(void*) gc_free;
+
+ extern (C) void* function(void*) gc_addrOf;
+ extern (C) size_t function(void*) gc_sizeOf;
+ extern (C) BlkInfo function(void*) gc_query;
+
+ extern (C) void function(void*) gc_addRoot;
+ extern (C) void function(void*, size_t) gc_addRange;
+
+ extern (C) void function(void*) gc_removeRoot;
+ extern (C) void function(void*) gc_removeRange;
}
-extern (C) void* gc_getHandle()
+Proxy pthis;
+Proxy* proxy;
+
+static this()
{
- return null;
+ pthis.gc_enable = &gc_enable;
+ pthis.gc_disable = &gc_disable;
+ pthis.gc_collect = &gc_collect;
+ pthis.gc_minimize = &gc_minimize;
+
+ pthis.gc_getAttr = &gc_getAttr;
+ pthis.gc_setAttr = &gc_setAttr;
+ pthis.gc_clrAttr = &gc_clrAttr;
+
+ pthis.gc_malloc = &gc_malloc;
+ pthis.gc_calloc = &gc_calloc;
+ pthis.gc_realloc = &gc_realloc;
+ pthis.gc_extend = &gc_extend;
+ pthis.gc_reserve = &gc_reserve;
+ pthis.gc_free = &gc_free;
+
+ pthis.gc_addrOf = &gc_addrOf;
+ pthis.gc_sizeOf = &gc_sizeOf;
+
+ pthis.gc_query = &gc_query;
+
+ pthis.gc_addRoot = &gc_addRoot;
+ pthis.gc_addRange = &gc_addRange;
+
+ pthis.gc_removeRoot = &gc_removeRoot;
+ pthis.gc_removeRange = &gc_removeRange;
}
-extern (C) void gc_setHandle(void* p)
+extern (C) Proxy* gc_getProxy()
{
+ return &pthis;
}
-extern (C) void gc_endHandle()
+export extern (C) void gc_setProxy( Proxy* p )
{
+ if( proxy !is null )
+ {
+ // error?
+ }
+ proxy = p;
+ ///foreach range
+ //proxy.addRange();
+ //foreach root
+ //proxy.addRoot()
}
+export extern (C) void gc_clrProxy()
+{
+ // foreach root
+ // proxy.removeRoot();
+ // foreach range
+ // proxy.removeReange();
+ proxy = null;
+}
\ No newline at end of file