}
}
- }
+ }
/* Check to see if we need to do a GC if this is a
// initialize thread-local var to a the task's record, which is fused
// with the param list
output.println(" ");
- output.println(" /* code of this task's body should use this to access the running task record */");
+ output.println(" // code of this task's body should use this to access the running task record");
output.println(" runningSESE = &(___params___->common);");
output.println(" ");
output.println(" "+pair.getSESE().getSESErecordName()+"* child = ("+
pair.getSESE().getSESErecordName()+"*) "+pair+";");
- output.println(" SESEcommon* common = (SESEcommon*) "+pair+";");
+ output.println(" SESEcommon* childCom = (SESEcommon*) "+pair+";");
+
if( state.COREPROF ) {
output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );");
output.println("#endif");
}
- output.println(" pthread_mutex_lock( &(common->lock) );");
- output.println(" if( common->doneExecuting == FALSE ) {");
- output.println(" stopforgc((struct garbagelist *)&___locals___);");
- output.println(" do {");
- output.println(" pthread_cond_wait( &(common->doneCond), &(common->lock) );");
- output.println(" } while( common->doneExecuting == FALSE );");
- output.println(" restartaftergc();");
- output.println(" }");
- output.println(" pthread_mutex_unlock( &(common->lock) );");
+
+ output.println(" pthread_mutex_lock( &(childCom->lock) );");
+ output.println(" if( childCom->doneExecuting == FALSE ) {");
+ output.println(" psem_reset( &runningSESEstallSem );");
+ output.println(" childCom->parentsStallSem = &runningSESEstallSem;");
+ output.println(" pthread_mutex_unlock( &(childCom->lock) );");
+ output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
+ output.println(" } else {");
+ output.println(" pthread_mutex_unlock( &(childCom->lock) );");
+ output.println(" }");
// copy things we might have stalled for
Iterator<TempDescriptor> tdItr = cp.getCopySet( vst ).iterator();
output.println(" "+generateTemp( fmContext, td, null )+
" = child->"+vst.getAddrVar().getSafeSymbol()+";");
}
+
if( state.COREPROF ) {
output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );");
output.println("#endif");
}
+
output.println(" }");
}
// otherwise the dynamic write nodes will have the local var up-to-date
output.println(" {");
output.println(" if( "+dynVar+"_srcSESE != NULL ) {");
- output.println(" SESEcommon* common = (SESEcommon*) "+dynVar+"_srcSESE;");
+
+ output.println(" SESEcommon* childCom = (SESEcommon*) "+dynVar+"_srcSESE;");
+
if( state.COREPROF ) {
output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );");
output.println("#endif");
}
- output.println(" psem_take( &(common->stallSem) );");
+
+ output.println(" pthread_mutex_lock( &(childCom->lock) );");
+ output.println(" if( childCom->doneExecuting == FALSE ) {");
+ output.println(" psem_reset( &runningSESEstallSem );");
+ output.println(" childCom->parentsStallSem = &runningSESEstallSem;");
+ output.println(" pthread_mutex_unlock( &(childCom->lock) );");
+ output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
+ output.println(" } else {");
+ output.println(" pthread_mutex_unlock( &(childCom->lock) );");
+ output.println(" }");
FlatMethod fmContext;
if( currentSESE.getIsCallerSESEplaceholder() ) {
fmContext = currentSESE.getfmBogus();
}
- TypeDescriptor type=dynVar.getType();
+ TypeDescriptor type = dynVar.getType();
String typeStr;
if( type.isNull() ) {
typeStr = "void*";
output.println(" "+generateTemp( fmContext, dynVar, null )+
" = *(("+typeStr+"*) ((void*)"+
dynVar+"_srcSESE + "+dynVar+"_srcOffset));");
+
if( state.COREPROF ) {
output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );");
output.println("#endif");
}
+
output.println(" }");
output.println(" }");
}
output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );");
output.println("#endif");
}
- output.println(" psem_take( &(rentry->parentStallSem) );");
+ output.println(" psem_take( &(rentry->parentStallSem), (struct garbagelist *)&___locals___ );");
if( state.COREPROF ) {
output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );");
output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );");
output.println("#endif");
}
- output.println(" psem_take( &(rentry->parentStallSem) );");
+ output.println(" psem_take( &(rentry->parentStallSem), (struct garbagelist *)&___locals___ );");
if( state.COREPROF ) {
output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );");
// fill in common data
output.println(" int localCount=0;");
output.println(" seseToIssue->common.classID = "+fsen.getIdentifier()+";");
- output.println(" psem_init( &(seseToIssue->common.stallSem) );");
+ output.println(" seseToIssue->common.parentsStallSem = NULL;");
output.println(" seseToIssue->common.forwardList = createQueue();");
output.println(" seseToIssue->common.unresolvedDependencies = 10000;");
- output.println(" pthread_cond_init( &(seseToIssue->common.doneCond), NULL );");
output.println(" seseToIssue->common.doneExecuting = FALSE;");
output.println(" pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );");
output.println(" seseToIssue->common.numRunningChildren = 0;");
output.println("#endif");
}
- String com = paramsprefix+"->common";
// this SESE cannot be done until all of its children are done
// so grab your own lock with the condition variable for watching
// that the number of your running children is greater than zero
- output.println(" pthread_mutex_lock( &("+com+".lock) );");
- output.println(" if ( "+com+".numRunningChildren > 0 ) {");
- output.println(" stopforgc((struct garbagelist *)&___locals___);");
+ output.println(" pthread_mutex_lock( &(runningSESE->lock) );");
+ output.println(" if( runningSESE->numRunningChildren > 0 ) {");
+ output.println(" stopforgc( (struct garbagelist *)&___locals___ );");
output.println(" do {");
- output.println(" pthread_cond_wait( &("+com+".runningChildrenCond), &("+com+".lock) );");
- output.println(" } while( "+com+".numRunningChildren > 0 );");
+ output.println(" pthread_cond_wait( &(runningSESE->runningChildrenCond), &(runningSESE->lock) );");
+ output.println(" } while( runningSESE->numRunningChildren > 0 );");
output.println(" restartaftergc();");
output.println(" }");
" = "+from+";");
}
- // mark yourself done, your SESE data is now read-only
- output.println(" "+com+".doneExecuting = TRUE;");
- output.println(" pthread_cond_signal( &("+com+".doneCond) );");
- output.println(" pthread_mutex_unlock( &("+com+".lock) );");
+ // mark yourself done, your task data is now read-only
+ output.println(" runningSESE->doneExecuting = TRUE;");
+
+ // if parent is stalling on you, let them know you're done
+ if( (state.MLP && fsexn.getFlatEnter() != mlpa.getMainSESE()) ||
+ (state.OOOJAVA && fsexn.getFlatEnter() != oooa.getMainSESE())
+ ) {
+ output.println(" if( runningSESE->parentsStallSem != NULL ) {");
+ output.println(" psem_give( runningSESE->parentsStallSem );");
+ output.println(" }");
+ }
+
+ output.println(" pthread_mutex_unlock( &(runningSESE->lock) );");
// decrement dependency count for all SESE's on your forwarding list
// FORWARD TODO
- output.println(" while( !isEmpty( "+com+".forwardList ) ) {");
- output.println(" SESEcommon* consumer = (SESEcommon*) getItem( "+com+".forwardList );");
+ output.println(" while( !isEmpty( runningSESE->forwardList ) ) {");
+ output.println(" SESEcommon* consumer = (SESEcommon*) getItem( runningSESE->forwardList );");
output.println(" if(consumer->rentryIdx>0){");
output.println(" }");
- output.println(" if( atomic_sub_and_test(1, &(consumer->unresolvedDependencies)) ){");
+ output.println(" if( atomic_sub_and_test( 1, &(consumer->unresolvedDependencies) ) ){");
output.println(" workScheduleSubmit( (void*)consumer );");
output.println(" }");
output.println(" }");
}
- // if parent is stalling on you, let them know you're done
- if( (state.MLP && fsexn.getFlatEnter() != mlpa.getMainSESE()) ||
- (state.OOOJAVA && fsexn.getFlatEnter() != oooa.getMainSESE())
- ) {
- output.println(" psem_give( &("+paramsprefix+"->common.stallSem) );");
- }
// last of all, decrement your parent's number of running children
- output.println(" if( "+paramsprefix+"->common.parent != NULL ) {");
- output.println(" if (atomic_sub_and_test(1, &"+paramsprefix+"->common.parent->numRunningChildren)) {");
- output.println(" pthread_mutex_lock( &("+paramsprefix+"->common.parent->lock) );");
- output.println(" pthread_cond_signal( &("+paramsprefix+"->common.parent->runningChildrenCond) );");
- output.println(" pthread_mutex_unlock( &("+paramsprefix+"->common.parent->lock) );");
+ output.println(" if( runningSESE->parent != NULL ) {");
+ output.println(" if( atomic_sub_and_test( 1, &(runningSESE->parent->numRunningChildren) ) ) {");
+ output.println(" pthread_mutex_lock ( &(runningSESE->parent->lock) );");
+ output.println(" pthread_cond_signal ( &(runningSESE->parent->runningChildrenCond) );");
+ output.println(" pthread_mutex_unlock( &(runningSESE->parent->lock) );");
output.println(" }");
output.println(" }");
+#include <stdlib.h>
+#include <errno.h>
#include "psemaphore.h"
-int psem_init( psemaphore* sem ) {
- if( pthread_mutex_init( &(sem->lock), NULL ) == -1 ) { return -1; }
- if( pthread_cond_init ( &(sem->cond), NULL ) == -1 ) { return -1; }
+void psem_init( psemaphore* sem ) {
+ pthread_mutex_init( &(sem->lock), NULL );
+ pthread_cond_init ( &(sem->cond), NULL );
sem->signaled = 0;
- return 0;
}
-int psem_take( psemaphore* sem ) {
- if( pthread_mutex_lock ( &(sem->lock) ) == -1 ) { return -1; }
- while( !sem->signaled ) {
- if( pthread_cond_wait ( &(sem->cond), &(sem->lock) ) == -1 ) { return -1; }
+void psem_take( psemaphore* sem, struct garbagelist* gl ) {
+ pthread_mutex_lock( &(sem->lock) );
+ if( !sem->signaled ) {
+ stopforgc( gl );
+ do {
+ pthread_cond_wait( &(sem->cond), &(sem->lock) );
+ } while( !sem->signaled );
+ restartaftergc();
}
- if( pthread_mutex_unlock( &(sem->lock) ) == -1 ) { return -1; }
- return 0;
+ pthread_mutex_unlock( &(sem->lock) );
}
-int psem_give( psemaphore* sem ) {
- if( pthread_mutex_lock ( &(sem->lock) ) == -1 ) { return -1; }
+void psem_give( psemaphore* sem ) {
+ pthread_mutex_lock ( &(sem->lock) );
sem->signaled = 1;
- if( pthread_cond_signal ( &(sem->cond) ) == -1 ) { return -1; }
- if( pthread_mutex_unlock( &(sem->lock) ) == -1 ) { return -1; }
+ pthread_cond_signal ( &(sem->cond) );
+ pthread_mutex_unlock( &(sem->lock) );
+}
+
+void psem_reset( psemaphore* sem ) {
+ // this should NEVER BE CALLED if it is possible
+ // the semaphore is still in use, NEVER
+ if( pthread_mutex_trylock( &(sem->lock) ) == EBUSY ) {
+ exit( -1 );
+ }
+ pthread_mutex_unlock( &(sem->lock) );
+ sem->signaled = 0;
}
#include "mem.h"
#include "workschedule.h"
#include "mlp_runtime.h"
+#include "psemaphore.h"
#include "coreprof/coreprof.h"
#ifdef RCR
#include "rcr_runtime.h"
WorkerData* myData = (WorkerData*) arg;
int oldState;
int haveWork;
+ struct garbagelist emptygarbagelist={0,NULL};
// once-per-thread stuff
CP_CREATE();
// oid with value 0 indicates an invalid object
oid = myData->id + 1;
+ // each thread has a single semaphore that a running
+ // task should hand off to children threads it is
+ // going to stall on
+ psem_init( &runningSESEstallSem );
+
+
#ifdef RCR
//allocate task record queue
pthread_t thread;
//pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldState );
// then continue to process work
+ //NOTE: ADD US TO THE GC LIST
+
+ pthread_mutex_lock(&gclistlock);
+ threadcount++;
+ litem.prev=NULL;
+ litem.next=list;
+ if(list!=NULL)
+ list->prev=&litem;
+ list=&litem;
+ pthread_mutex_unlock(&gclistlock);
+
+
+ //ALSO CREATE EMPTY GARBAGELIST TO PASS TO COLLECTOR
+
while( 1 ) {
// wait for work
#endif
haveWork = FALSE;
while( !haveWork ) {
+ //NOTE...Fix these things...
pthread_mutex_lock( &systemLockOut );
if( headqi->next == NULL ) {
pthread_mutex_unlock( &systemLockOut );
+ //NOTE: Do a check to see if we need to collect..
+ if (unlikely(needtocollect)) checkcollect(&emptygarbagelist);
sched_yield();
continue;
} else {
CP_LOGEVENT( CP_EVENTID_WORKSCHEDGRAB, CP_EVENTTYPE_END );
#endif
- pthread_mutex_lock(&gclistlock);
- threadcount++;
+ //let GC see current work
litem.seseCommon=(void*)workUnit;
- litem.prev=NULL;
- litem.next=list;
- if(list!=NULL)
- list->prev=&litem;
- list=&litem;
- seseCommon=(SESEcommon*)workUnit;
- pthread_mutex_unlock(&gclistlock);
+
+ //unclear how useful this is
+ if (unlikely(needtocollect)) checkcollect(&emptygarbagelist);
workFunc( workUnit );
-
- pthread_mutex_lock(&gclistlock);
- threadcount--;
- if (litem.prev==NULL) {
- list=litem.next;
- } else {
- litem.prev->next=litem.next;
- }
- if (litem.next!=NULL) {
- litem.next->prev=litem.prev;
- }
- pthread_mutex_unlock(&gclistlock);
}
+ //NOTE: Remove from GC LIST DOWN HERE....
+ pthread_mutex_lock(&gclistlock);
+ threadcount--;
+ if (litem.prev==NULL) {
+ list=litem.next;
+ } else {
+ litem.prev->next=litem.next;
+ }
+ if (litem.next!=NULL) {
+ litem.next->prev=litem.prev;
+ }
+ pthread_mutex_unlock(&gclistlock);
+
+
//pthread_cleanup_pop( 0 );
return NULL;