Talk:Resource Tracking for FlightGear: Difference between revisions

Jump to navigation Jump to search
m
m (→‎Nasal GC Tracking: archive code snippets)
 
Line 154: Line 154:
= Nasal GC Tracking =
= Nasal GC Tracking =


{{WIP}}
ThorstenB once posted a patch that tracks GC invocations over time (printf) which should be easy to also expose to the property tree and log/plot accordingly.
ThorstenB once posted a patch that tracks GC invocations over time (printf) which should be easy to also expose to the property tree and log/plot accordingly.
Also, it shows "GC pressure" (=symbols/references) per namespace.
Also, it shows "GC pressure" (=symbols/references) per namespace.
Line 169: Line 168:


with &FGNasalSys::trackGC being registed then.
with &FGNasalSys::trackGC being registed then.


looking at the code, there's something called initGlobals at: http://sourceforge.net/p/flightgear/simgear/ci/next/tree/simgear/nasal/code.c#l161
looking at the code, there's something called initGlobals at: http://sourceforge.net/p/flightgear/simgear/ci/next/tree/simgear/nasal/code.c#l161
Line 205: Line 202:
And then the C++ code can do stuff like fgSetInt(), SG_LOG() etc easily
And then the C++ code can do stuff like fgSetInt(), SG_LOG() etc easily


SimGear: http://codepad.org/xqOoW7rB
SimGear: http://codepad.org/ZSGZbMiV/raw.txt
<syntaxhighlight lang="cpp">
<syntaxhighlight lang="cpp">diff --git a/simgear/nasal/code.c b/simgear/nasal/code.c
diff --git a/src/Scripting/NasalSys.cxx b/src/Scripting/NasalSys.cxx
index 2bf4645..61a7ae8 100644
index 8e7622e..ea6890d 100644
--- a/simgear/nasal/code.c
--- a/src/Scripting/NasalSys.cxx
+++ b/simgear/nasal/code.c
+++ b/src/Scripting/NasalSys.cxx
@@ -22,6 +22,19 @@ void printStackDEBUG(naContext ctx);
@@ -60,6 +60,11 @@ void postinitNasalGUI(naRef globals, naContext c);
   
   
  static FGNasalSys* nasalSys = 0;
  struct Globals* globals = 0;
   
   
+static
+extern unsigned int gRefCount,gObjCount;
+void TrackGarbageCollectionCallback(unsigned int refs, unsigned int objs) {
+
+ SG_LOG(SG_NASAL, SG_ALERT, "Nasal GC: References:"<<refs<< " Objects:"<<objs);
+void registerGCTracker(TrackGCcb cb) {
+// check if globals is a valid pointer
+if (!globals) {
+fprintf(stderr, "Globals must be set up first!)");
+return;
+}
+}
+
+
  // Listener class for loading Nasal modules on demand
+printf("Registering GC tracking callback!");
  class FGNasalModuleListener : public SGPropertyChangeListener
+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; i<NUM_NASAL_TYPES; i++)
        naGC_init(&(globals->pools[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; i<NUM_NASAL_TYPES; i++)
@@ -53,6 +58,14 @@ static void garbageCollect()
        c = c->nextAll;
    }
+    // 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)
  {
  {
@@ -819,6 +824,9 @@ void FGNasalSys::init()
    int i;
+   gRefCount ++;
   
   
     _context = naNewContext();
     if(IS_NUM(r) || IS_NIL(r))
        return;
@@ -249,6 +263,8 @@ static void mark(naRef r)
    if(PTR(r).obj->mark == 1)
        return;
   
   
+    // register a custom GC tracking callback
+    gObjCount++;
+   registerGCTracker(&TrackGarbageCollectionCallback);
+
+
     // Start with globals. Add it to itself as a recursive
     PTR(r).obj->mark = 1;
    // sub-reference under the name "globals". This gives client-code
    switch(PTR(r).obj->type) {
    // write access to the namespace if someone wants to do something
    case T_VEC: markvec(r); break;
@@ -875,6 +883,7 @@ void FGNasalSys::init()
diff --git a/simgear/nasal/nasal.h b/simgear/nasal/nasal.h
    simgear::PathList directories = nasalDir.children(simgear::Dir::TYPE_DIR+
index 8b6b2c9..48ed460 100644
            simgear::Dir::NO_DOT_OR_DOTDOT, "");
--- a/simgear/nasal/nasal.h
    for (unsigned int i=0; i<directories.size(); ++i) {
+++ b/simgear/nasal/nasal.h
+ SG_LOG(SG_NASAL, SG_ALERT, "Adding Nasal module:" << directories[i].file() );
@@ -44,6 +44,10 @@ void* naGetUserData(naContext c) GCC_PURE;
        simgear::Dir dir(directories[i]);
        simgear::PathList scripts = dir.children(simgear::Dir::TYPE_FILE, ".nas");
// run GC now (may block)
        addModule(directories[i].file(), scripts);
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.
</syntaxhighlight>
</syntaxhighlight>


Navigation menu