diff --git a/simgear/nasal/code.c b/simgear/nasal/code.c index 2bf4645..61a7ae8 100644 --- a/simgear/nasal/code.c +++ b/simgear/nasal/code.c @@ -22,6 +22,19 @@ void printStackDEBUG(naContext ctx); struct Globals* globals = 0; +extern unsigned int gRefCount,gObjCount; + +void registerGCTracker(TrackGCcb cb) { +// check if globals is a valid pointer +if (!globals) { +fprintf(stderr, "Globals must be set up first!)"); +return; +} + +printf("Registering GC tracking callback!"); +globals->gc_cb=cb; +} + static naRef bindFunction(naContext ctx, struct Frame* f, naRef code); #define ERR(c, msg) naRuntimeError((c),(msg)) @@ -168,6 +181,8 @@ static void initGlobals() globals->sem = naNewSem(); globals->lock = naNewLock(); + gObjCount = gRefCount = 0; + globals->allocCount = 256; // reasonable starting value for(i=0; ipools[i]), i); diff --git a/simgear/nasal/code.h b/simgear/nasal/code.h index e7cb3f3..5b0befc 100644 --- a/simgear/nasal/code.h +++ b/simgear/nasal/code.h @@ -41,6 +41,7 @@ struct Globals { // Garbage collecting allocators: struct naPool pools[NUM_NASAL_TYPES]; int allocCount; + TrackGCcb gc_cb; // Dead blocks waiting to be freed when it is safe void** deadBlocks; diff --git a/simgear/nasal/gc.c b/simgear/nasal/gc.c index 5ac9c43..6819d19 100644 --- a/simgear/nasal/gc.c +++ b/simgear/nasal/gc.c @@ -4,6 +4,9 @@ #define MIN_BLOCK_SIZE 32 +int gRefCount=0; +int gObjCount=0; + static void reap(struct naPool* p); static void mark(naRef r); @@ -38,6 +41,8 @@ static void garbageCollect() int i; struct Context* c; globals->allocCount = 0; + // https://www.mail-archive.com/flightgear-devel%40lists.sourceforge.net/msg31762.html + gObjCount = gRefCount=0; c = globals->allContexts; while(c) { for(i=0; inextAll; } + // check if there is a GC callback registered, if so call it + + TrackGCcb cb = globals->gc_cb; + if(cb) { + // callback is registered, so call it + (*cb) (gRefCount, gObjCount); + } + mark(globals->save); mark(globals->save_hash); mark(globals->symbols); @@ -242,6 +255,7 @@ static void markvec(naRef r) static void mark(naRef r) { int i; + gRefCount ++; if(IS_NUM(r) || IS_NIL(r)) return; @@ -249,6 +263,8 @@ static void mark(naRef r) if(PTR(r).obj->mark == 1) return; + gObjCount++; + PTR(r).obj->mark = 1; switch(PTR(r).obj->type) { case T_VEC: markvec(r); break; diff --git a/simgear/nasal/nasal.h b/simgear/nasal/nasal.h index 8b6b2c9..48ed460 100644 --- a/simgear/nasal/nasal.h +++ b/simgear/nasal/nasal.h @@ -44,6 +44,10 @@ void* naGetUserData(naContext c) GCC_PURE; // run GC now (may block) void naGC(); +struct Globals; +typedef void (*TrackGCcb) (unsigned int refs, unsigned int objects); +void registerGCTracker(TrackGCcb cb); + // "Save" this object in the context, preventing it (and objects // referenced by it) from being garbage collected.