From: bdemsky Date: Fri, 15 Apr 2011 22:39:24 +0000 (+0000) Subject: simplify the gc code... X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=0937ce0a7db548ea465f032003abf4aa76979916;p=IRC.git simplify the gc code... --- diff --git a/Robust/src/Runtime/garbage.c b/Robust/src/Runtime/garbage.c index 35801dc3..0a267c08 100644 --- a/Robust/src/Runtime/garbage.c +++ b/Robust/src/Runtime/garbage.c @@ -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; isize; 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;iindex;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;iindex;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;iindex;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; isize; 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; isize; 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;iindex;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;