#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);
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
{
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 */
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;