small optimization to the leak check, to mark the entities faster
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 15 Jul 2008 08:19:43 +0000 (08:19 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 15 Jul 2008 08:19:43 +0000 (08:19 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8404 d7cf8633-e32d-0410-b094-e92efae38249

progs.h
progsvm.h
prvm_edict.c

diff --git a/progs.h b/progs.h
index d5e59db..51e1c9d 100644 (file)
--- a/progs.h
+++ b/progs.h
@@ -33,7 +33,7 @@ typedef struct edict_engineprivate_s
        // mess up client interpolation or obscure severe QuakeC bugs)
        float freetime;
        // mark for the leak detector
-       qboolean marked;
+       int mark;
        // place in the code where it was allocated (for the leak detector)
        const char *allocation_origin;
        // initially false to prevent projectiles from moving on their first frame
index ce900af..8386e99 100644 (file)
--- a/progsvm.h
+++ b/progsvm.h
@@ -67,7 +67,7 @@ typedef struct prvm_edict_private_s
 {
        qboolean free;
        float freetime;
-       qboolean marked;
+       int mark;
        const char *allocation_origin;
 } prvm_edict_private_t;
 
index 204fb3b..96c3557 100644 (file)
@@ -2501,7 +2501,7 @@ static qboolean PRVM_IsEdictRelevant(prvm_edict_t *edict)
        return false;
 }
 
-static qboolean PRVM_IsEdictReferenced(prvm_edict_t *edict)
+static qboolean PRVM_IsEdictReferenced(prvm_edict_t *edict, int mark)
 {
        int i, j;
        int edictnum = PRVM_NUM_FOR_EDICT(edict);
@@ -2530,7 +2530,7 @@ static qboolean PRVM_IsEdictReferenced(prvm_edict_t *edict)
        for(j = 0; j < prog->num_edicts; ++j)
        {
                prvm_edict_t *ed = PRVM_EDICT_NUM(j);
-               if (!ed->priv.required->marked)
+               if (ed->priv.required->mark < mark)
                        continue;
                if(ed == edict)
                        continue;
@@ -2558,15 +2558,17 @@ static void PRVM_MarkReferencedEdicts()
 {
        int j;
        qboolean found_new;
+       int stage;
 
        for(j = 0; j < prog->num_edicts; ++j)
        {
                prvm_edict_t *ed = PRVM_EDICT_NUM(j);
                if(ed->priv.required->free)
                        continue;
-               ed->priv.required->marked = PRVM_IsEdictRelevant(ed);
+               ed->priv.required->mark = PRVM_IsEdictRelevant(ed) ? 1 : 0;
        }
 
+       stage = 1;
        do
        {
                found_new = false;
@@ -2575,16 +2577,18 @@ static void PRVM_MarkReferencedEdicts()
                        prvm_edict_t *ed = PRVM_EDICT_NUM(j);
                        if(ed->priv.required->free)
                                continue;
-                       if(ed->priv.required->marked)
+                       if(ed->priv.required->mark)
                                continue;
-                       if(PRVM_IsEdictReferenced(ed))
+                       if(PRVM_IsEdictReferenced(ed, stage))
                        {
-                               ed->priv.required->marked = true;
+                               ed->priv.required->mark = stage + 1;
                                found_new = true;
                        }
                }
+               ++stage;
        }
        while(found_new);
+       Con_DPrintf("leak check used %d stages to find all references\n", stage);
 }
 
 void PRVM_LeakTest()
@@ -2615,7 +2619,7 @@ void PRVM_LeakTest()
                prvm_edict_t *ed = PRVM_EDICT_NUM(j);
                if(ed->priv.required->free)
                        continue;
-               if(!ed->priv.required->marked)
+               if(!ed->priv.required->mark)
                if(ed->priv.required->allocation_origin)
                {
                        Con_Printf("Unreferenced edict found!\n  Allocated at: %s\n", ed->priv.required->allocation_origin);