simplify the gc code...
authorbdemsky <bdemsky>
Fri, 15 Apr 2011 22:39:24 +0000 (22:39 +0000)
committerbdemsky <bdemsky>
Fri, 15 Apr 2011 22:39:24 +0000 (22:39 +0000)
Robust/src/Runtime/garbage.c

index 35801dc3347965db89d57113de34134bb53ab867..0a267c0888ea9d6ade0b832eecd279610cf7b126 100644 (file)
@@ -327,8 +327,23 @@ __thread char * memorytop=NULL;
 #endif
 #endif
 
+void initqueues() {
+  if (head==NULL) {
+    headindex=0;
+    tailindex=0;
+    head=tail=malloc(sizeof(struct pointerblock));
+  }
 
-void collect(struct garbagelist * stackptr) {
+#ifdef TASK
+  if (taghead==NULL) {
+    tagindex=0;
+    taghead=malloc(sizeof(struct pointerblock));
+    taghead->next=NULL;
+  }
+#endif
+}
+
+void doinitstuff() {
 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
   needtocollect=1;
   pthread_mutex_lock(&gclistlock);
@@ -339,14 +354,6 @@ void collect(struct garbagelist * stackptr) {
     pthread_cond_wait(&gccond, &gclistlock);
   }
 #endif
-#ifdef DELAYCOMP
-  ptrstack.prev=stackptr;
-  stackptr=(struct garbagelist *) &ptrstack;
-#if defined(STMARRAY)&&!defined(DUALVIEW)
-  arraystack.prev=stackptr;
-  stackptr=(struct garbagelist *) &arraystack;
-#endif
-#endif
 
 #ifdef GARBAGESTATS
   {
@@ -355,147 +362,165 @@ void collect(struct garbagelist * stackptr) {
       garbagearray[i]=0;
   }
 #endif
-
-  if (head==NULL) {
-    headindex=0;
-    tailindex=0;
-    head=tail=malloc(sizeof(struct pointerblock));
-  }
-
-#ifdef TASK
-  if (taghead==NULL) {
-    tagindex=0;
-    taghead=malloc(sizeof(struct pointerblock));
-    taghead->next=NULL;
-  }
-#endif
+  initqueues();
 
 #ifdef STM
-  if (c_table!=NULL) {
-    fixtable(&c_table, &c_list, &c_structs, c_size);
-    fixobjlist(newobjs);
+  litem.tc_size=c_size;
+  litem.tc_table=&c_table;
+  litem.tc_list=&c_list;
+  litem.tc_structs=&c_structs;
+  litem.objlist=newobjs;
 #ifdef STMSTATS
-    fixobjlist(lockedobjs);
+  litem.lockedlist=lockedobjs;
 #endif
-  }
 #endif
 #if defined(STM)||defined(THREADS)||defined(MLP)
 #ifdef MAC
-  *((char **)pthread_getspecific(memorybasekey))=NULL;
+  struct listitem *litem=pthread_getspecific(litemkey);
+  litem->base=((char **)pthread_getspecific(memorybasekey));
 #else
-  memorybase=NULL;
+  litem.base=&memorybase;
 #endif
 #endif
+}
 
-  /* Check current stack */
-#if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
-  {
-    struct listitem *listptr=list;
-    while(1) {
-#endif
-      
-  while(stackptr!=NULL) {
-    int i;
-    for(i=0; i<stackptr->size; i++) {
-      void * orig=stackptr->array[i];
-      ENQUEUE(orig, stackptr->array[i]);
-    }
-    stackptr=stackptr->next;
-  }
-#if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
-  /* Go to next thread */
-#ifndef MAC
-  //skip over us
-  if (listptr==&litem) {
+void searchoojroots() {
 #ifdef MLP
-    // update forward list & memory queue for the current SESE
-    updateForwardList(&((SESEcommon*)listptr->seseCommon)->forwardList,FALSE);
-    updateMemoryQueue((SESEcommon*)(listptr->seseCommon));
-#endif
-#ifdef THREADS
+#ifdef SQUEUE
   {
-    struct lockvector * lvector=listptr->lvector;
-    int i;
-    for(i=0;i<lvector->index;i++) {
-      struct ___Object___ *orig=lvector->locks[i].object;
-      ENQUEUE(orig, lvector->locks[i].object);
+    int        i;
+    deque*     dq;
+    dequeItem *di;
+    int        j;
+
+    // goes over ready-to-run SESEs
+    for( i = 0; i < numWorkSchedWorkers; ++i ) {
+      dq = &(deques[i]);
+
+      di=dq->head;
+
+      do {
+        // check all the relevant indices of this
+        // node in the deque, noting if we are in
+        // the top/bottom node which can be partially
+        // full
+
+          // WHAT? 
+          //SESEcommon* common = (SESEcommon*) n->itsDataArr[j];
+          //if(common==seseCommon){
+          // skip the current running SESE
+          //  continue;
+          //}
+       di=(dequeItem *) EXTRACTPTR((INTPTR)di);
+       SESEcommon* seseRec = (SESEcommon*) di->work;
+       if (seseRec!=NULL) {
+          struct garbagelist* gl     = (struct garbagelist*) &(seseRec[1]);
+          struct garbagelist* glroot = gl;
+         
+          updateAscendantSESE( seseRec );
+         
+          while( gl != NULL ) {
+            int k;
+            for( k = 0; k < gl->size; k++ ) {
+              void* orig = gl->array[k];
+              ENQUEUE( orig, gl->array[k] );
+            }
+            gl = gl->next;
+          } 
+        }
+        // we only have to move across the nodes
+        // of the deque if the top and bottom are
+        // not the same already
+         di=di->next;
+      } while( di !=NULL) ;
     }
-  }
-#endif
-    listptr=listptr->next;
-  }
+  }    
 #else
- {
-  struct listitem *litem=pthread_getspecific(litemkey);
-  if (listptr==litem) {
-#ifdef THREADS
   {
-    struct lockvector * lvector=listptr->lvector;
-    int i;
-    for(i=0;i<lvector->index;i++) {
-      struct ___Object___ *orig=lvector->locks[i].object;
-      ENQUEUE(orig, lvector->locks[i].object);
+    int        i;
+    deque*     dq;
+    dequeNode* botNode;
+    int        botIndx;
+    dequeNode* topNode;
+    int        topIndx;
+    dequeNode* n;
+    int        j;
+    int        jLo;
+    int        jHi;
+    
+    // goes over ready-to-run SESEs
+    for( i = 0; i < numWorkSchedWorkers; ++i ) {
+      dq = &(deques[i]);
+      
+      botNode = dqDecodePtr( dq->bottom );
+      botIndx = dqDecodeIdx( dq->bottom );
+      
+      topNode = dqDecodePtr( dq->top );
+      topIndx = dqDecodeIdx( dq->top );
+      
+      
+      n = botNode;
+      do {
+       // check all the relevant indices of this
+       // node in the deque, noting if we are in
+       // the top/bottom node which can be partially
+       // full
+       if( n == botNode ) { jLo = botIndx; } else { jLo = 0; }
+       if( n == topNode ) { jHi = topIndx; } else { jHi = DQNODE_ARRAYSIZE; }
+       
+       for( j = jLo; j < jHi; ++j ) {
+         
+         // WHAT?
+         //SESEcommon* common = (SESEcommon*) n->itsDataArr[j];
+         //if(common==seseCommon){
+         //  continue;
+         //}
+         
+          SESEcommon* seseRec = (SESEcommon*) n->itsDataArr[j];
+         
+         struct garbagelist* gl     = (struct garbagelist*) &(seseRec[1]);
+          struct garbagelist* glroot = gl;
+         
+          updateAscendantSESE( seseRec );
+         
+          while( gl != NULL ) {
+            int k;
+            for( k = 0; k < gl->size; k++ ) {
+              void* orig = gl->array[k];
+              ENQUEUE( orig, gl->array[k] );
+           }
+           gl = gl->next;
+         }
+       }
+       
+       // we only have to move across the nodes
+       // of the deque if the top and bottom are
+       // not the same already
+        if( botNode != topNode ) {
+          n = n->next;
+        }
+      } while( n != topNode );
     }
   }
 #endif
-    listptr=listptr->next;
-  }
- }
 #endif
-  if (listptr!=NULL) {
-#ifdef THREADS
-  {
-    struct lockvector * lvector=listptr->lvector;
-    int i;
-    for(i=0;i<lvector->index;i++) {
-      struct ___Object___ *orig=lvector->locks[i].object;
-      ENQUEUE(orig, lvector->locks[i].object);
-    }
-  }
-#endif
-#ifdef STM
-    if ((*listptr->tc_table)!=NULL) {
-      fixtable(listptr->tc_table, listptr->tc_list, listptr->tc_structs, listptr->tc_size);
-      fixobjlist(listptr->objlist);
-#ifdef STMSTATS
-      fixobjlist(listptr->lockedlist);
-#endif
-    }
-#endif
-#if defined(STM)||defined(THREADS)||defined(MLP)
-    *(listptr->base)=NULL;
-#endif
-#ifdef MLP
-    // update forward list & memory queue for all running SESEs.
-    if (listptr->seseCommon!=NULL) {
-      updateForwardList(&((SESEcommon*)listptr->seseCommon)->forwardList,FALSE);
-      updateMemoryQueue((SESEcommon*)(listptr->seseCommon));
-    }
-#endif
-    stackptr=listptr->stackptr;
-    listptr=listptr->next;
-  } else
-    break;
-}
 }
-#endif
-
-#ifdef FASTCHECK
-  ENQUEUE(___fcrevert___, ___fcrevert___);
-#endif
 
+void searchglobalroots() {
 #if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
   {
     int i;
-    stackptr=(struct garbagelist *)global_defs_p;
+    struct garbagelist * stackptr=(struct garbagelist *)global_defs_p;
     for(i=0; i<stackptr->size; i++) {
       void * orig=stackptr->array[i];
       ENQUEUE(orig, stackptr->array[i]);
     }
   }
 #endif
+}
 
+
+void searchtaskroots() {
 #ifdef TASK
   {
     /* Update objectsets */
@@ -588,128 +613,96 @@ void collect(struct garbagelist * stackptr) {
     genrehash(failedtasks);
   }
 #endif
+}
 
-#ifdef MLP
-#ifdef SQUEUE
-  {
-    int        i;
-    deque*     dq;
-    dequeItem *di;
-    int        j;
-
-    // goes over ready-to-run SESEs
-    for( i = 0; i < numWorkSchedWorkers; ++i ) {
-      dq = &(deques[i]);
-
-      di=dq->head;
+void searchstack(struct garbagelist *stackptr) {
+  while(stackptr!=NULL) {
+    int i;
+    for(i=0; i<stackptr->size; i++) {
+      void * orig=stackptr->array[i];
+      ENQUEUE(orig, stackptr->array[i]);
+    }
+    stackptr=stackptr->next;
+  }
+}
 
-      do {
-        // check all the relevant indices of this
-        // node in the deque, noting if we are in
-        // the top/bottom node which can be partially
-        // full
 
-          // WHAT? 
-          //SESEcommon* common = (SESEcommon*) n->itsDataArr[j];
-          //if(common==seseCommon){
-          // skip the current running SESE
-          //  continue;
-          //}
-       di=(dequeItem *) EXTRACTPTR((INTPTR)di);
-       SESEcommon* seseRec = (SESEcommon*) di->work;
-       if (seseRec!=NULL) {
-          struct garbagelist* gl     = (struct garbagelist*) &(seseRec[1]);
-          struct garbagelist* glroot = gl;
-         
-          updateAscendantSESE( seseRec );
-         
-          while( gl != NULL ) {
-            int k;
-            for( k = 0; k < gl->size; k++ ) {
-              void* orig = gl->array[k];
-              ENQUEUE( orig, gl->array[k] );
-            }
-            gl = gl->next;
-          } 
-        }
-        // we only have to move across the nodes
-        // of the deque if the top and bottom are
-        // not the same already
-         di=di->next;
-      } while( di !=NULL) ;
-    }
-  }    
+#if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
+void searchthreadroots(struct garbagelist * stackptr) {
+  /* Check current stack */
+  struct listitem *listptr=list;
+#ifdef MAC
+  struct listitem *litem=pthread_getspecific(litemkey);
+  litem->stackptr=stackptr;
 #else
-  {
-    int        i;
-    deque*     dq;
-    dequeNode* botNode;
-    int        botIndx;
-    dequeNode* topNode;
-    int        topIndx;
-    dequeNode* n;
-    int        j;
-    int        jLo;
-    int        jHi;
-    
-    // goes over ready-to-run SESEs
-    for( i = 0; i < numWorkSchedWorkers; ++i ) {
-      dq = &(deques[i]);
-      
-      botNode = dqDecodePtr( dq->bottom );
-      botIndx = dqDecodeIdx( dq->bottom );
-      
-      topNode = dqDecodePtr( dq->top );
-      topIndx = dqDecodeIdx( dq->top );
-      
-      
-      n = botNode;
-      do {
-       // check all the relevant indices of this
-       // node in the deque, noting if we are in
-       // the top/bottom node which can be partially
-       // full
-       if( n == botNode ) { jLo = botIndx; } else { jLo = 0; }
-       if( n == topNode ) { jHi = topIndx; } else { jHi = DQNODE_ARRAYSIZE; }
-       
-       for( j = jLo; j < jHi; ++j ) {
-         
-         // WHAT?
-         //SESEcommon* common = (SESEcommon*) n->itsDataArr[j];
-         //if(common==seseCommon){
-         //  continue;
-         //}
-         
-          SESEcommon* seseRec = (SESEcommon*) n->itsDataArr[j];
-         
-         struct garbagelist* gl     = (struct garbagelist*) &(seseRec[1]);
-          struct garbagelist* glroot = gl;
-         
-          updateAscendantSESE( seseRec );
-         
-          while( gl != NULL ) {
-            int k;
-            for( k = 0; k < gl->size; k++ ) {
-              void* orig = gl->array[k];
-              ENQUEUE( orig, gl->array[k] );
-           }
-           gl = gl->next;
-         }
-       }
-       
-       // we only have to move across the nodes
-       // of the deque if the top and bottom are
-       // not the same already
-        if( botNode != topNode ) {
-          n = n->next;
-        }
-      } while( n != topNode );
+  litem.stackptr=stackptr;
+#endif
+  
+  while(listptr!=NULL) {
+    searchstack(listptr->stackptr);
+#ifdef THREADS
+    struct lockvector * lvector=listptr->lvector;
+    int i;
+    for(i=0;i<lvector->index;i++) {
+      struct ___Object___ *orig=lvector->locks[i].object;
+      ENQUEUE(orig, lvector->locks[i].object);
+    }
+#endif
+#ifdef STM
+    if ((*listptr->tc_table)!=NULL) {
+      fixtable(listptr->tc_table, listptr->tc_list, listptr->tc_structs, listptr->tc_size);
+      fixobjlist(listptr->objlist);
+#ifdef STMSTATS
+      fixobjlist(listptr->lockedlist);
+#endif
     }
+#endif
+#if defined(STM)||defined(THREADS)||defined(MLP)
+    *(listptr->base)=NULL;
+#endif
+#ifdef MLP
+    // update forward list & memory queue for all running SESEs.
+    if (listptr->seseCommon!=NULL) {
+      updateForwardList(&((SESEcommon*)listptr->seseCommon)->forwardList,FALSE);
+      updateMemoryQueue((SESEcommon*)(listptr->seseCommon));
+    }
+#endif
+    listptr=listptr->next;
   }
+}
 #endif
+
+
+void searchroots(struct garbagelist * stackptr) {
+#if defined(THREADS)||defined(DSTM)||defined(STM)||defined(MLP)
+  searchthreadroots(stackptr);
+#else
+  searchstack(stackptr);
+#endif
+
+#ifdef FASTCHECK
+  ENQUEUE(___fcrevert___, ___fcrevert___);
 #endif
+  searchglobalroots();
+  searchtaskroots();
+  searchoojroots();
+}
 
 
+void collect(struct garbagelist * stackptr) {
+  doinitstuff();
+
+#ifdef DELAYCOMP
+  ptrstack.prev=stackptr;
+  stackptr=(struct garbagelist *) &ptrstack;
+#if defined(STMARRAY)&&!defined(DUALVIEW)
+  arraystack.prev=stackptr;
+  stackptr=(struct garbagelist *) &arraystack;
+#endif
+#endif
+  
+  searchroots(stackptr);
+
   while(moreItems()) {
     void * ptr=dequeue();
     void *cpy=ptr;