From 2de999ba38693e629f67783972d03bf8dcfaf259 Mon Sep 17 00:00:00 2001 From: jjenista Date: Tue, 25 Aug 2009 18:11:59 +0000 Subject: [PATCH] Still haven't worked all the bugs out of MLP's support for method calls, but stable at least --- Robust/src/Analysis/MLP/MLPAnalysis.java | 3 +- Robust/src/IR/Flat/BuildCode.java | 66 +++++++++++++++--------- Robust/src/Runtime/mlp_runtime.c | 5 ++ Robust/src/Runtime/mlp_runtime.h | 6 ++- Robust/src/Runtime/workschedule.c | 6 ++- Robust/src/Tests/mlp/tinyTest/test.java | 6 ++- 6 files changed, 62 insertions(+), 30 deletions(-) diff --git a/Robust/src/Analysis/MLP/MLPAnalysis.java b/Robust/src/Analysis/MLP/MLPAnalysis.java index 8b26318b..531795b6 100644 --- a/Robust/src/Analysis/MLP/MLPAnalysis.java +++ b/Robust/src/Analysis/MLP/MLPAnalysis.java @@ -41,14 +41,13 @@ public class MLPAnalysis { // there is an empty stack it means all variables are available. private Hashtable< FlatNode, Stack > seseStacks; - private Hashtable< FlatNode, Set > livenessRootView; private Hashtable< FlatNode, Set > livenessVirtualReads; private Hashtable< FlatNode, VarSrcTokTable > variableResults; private Hashtable< FlatNode, Set > notAvailableResults; private Hashtable< FlatNode, CodePlan > codePlans; - private Hashtable wdvNodesToSpliceIn; + private Hashtable< FlatEdge, FlatWriteDynamicVarNode > wdvNodesToSpliceIn; public static int maxSESEage = -1; diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 0a0f7c42..e5610635 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -286,6 +286,7 @@ public class BuildCode { outmethod.println(" int i;"); if (state.MLP) { + outmethod.println(" pthread_once( &mlpOnceObj, mlpInitOncePerThread );"); outmethod.println(" workScheduleInit( "+state.MLP_NUMCORES+", invokeSESEmethod );"); } @@ -2842,11 +2843,20 @@ public class BuildCode { output.println(" {"); + // set up the parent + if( fsen == mlpa.getMainSESE() ) { + output.println(" SESEcommon* parentCommon = NULL;"); + } else if( fsen.getParent() != null ) { + output.println(" SESEcommon* parentCommon = &("+paramsprefix+"->common);"); + } else { + output.println(" SESEcommon* parentCommon = (SESEcommon*) peekItem( seseCallStack );"); + } + // before doing anything, lock your own record and increment the running children if( fsen != mlpa.getMainSESE() ) { - output.println(" pthread_mutex_lock( &("+paramsprefix+"->common.lock) );"); - output.println(" ++("+paramsprefix+"->common.numRunningChildren);"); - output.println(" pthread_mutex_unlock( &("+paramsprefix+"->common.lock) );"); + output.println(" pthread_mutex_lock( &(parentCommon->lock) );"); + output.println(" ++(parentCommon->numRunningChildren);"); + output.println(" pthread_mutex_unlock( &(parentCommon->lock) );"); } // just allocate the space for this record @@ -2854,6 +2864,9 @@ public class BuildCode { fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+ fsen.getSESErecordName()+" ) );"); + // and keep the thread-local sese stack up to date + output.println(" addNewItem( seseCallStack, (void*) seseToIssue);"); + // fill in common data output.println(" seseToIssue->common.classID = "+fsen.getIdentifier()+";"); output.println(" psem_init( &(seseToIssue->common.stallSem) );"); @@ -2864,23 +2877,19 @@ public class BuildCode { output.println(" seseToIssue->common.doneExecuting = FALSE;"); output.println(" pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );"); output.println(" seseToIssue->common.numRunningChildren = 0;"); - - if( fsen != mlpa.getMainSESE() ) { - output.println(" seseToIssue->common.parent = (SESEcommon*) "+paramsprefix+";"); - } else { - output.println(" seseToIssue->common.parent = NULL;"); - } + output.println(" seseToIssue->common.parent = parentCommon;"); // all READY in-vars should be copied now and be done with it Iterator tempItr = fsen.getReadyInVarSet().iterator(); while( tempItr.hasNext() ) { TempDescriptor temp = tempItr.next(); - if( fsen != mlpa.getMainSESE() ) { + if( fsen != mlpa.getMainSESE() && + fsen.getParent() != null ) { output.println(" seseToIssue->"+temp+" = "+ generateTemp( fsen.getParent().getfmBogus(), temp, null )+";"); } else { output.println(" seseToIssue->"+temp+" = "+ - generateTemp( state.getMethodFlat( typeutil.getMain() ), temp, null )+";"); + generateTemp( fsen.getfmEnclosing(), temp, null )+";"); } } @@ -2937,8 +2946,13 @@ public class BuildCode { output.println(" pthread_mutex_unlock( &(src->lock) );"); output.println(" seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;"); output.println(" } else {"); - output.println(" seseToIssue->"+dynInVar+" = "+ - generateTemp( fsen.getParent().getfmBogus(), dynInVar, null )+";"); + if( fsen.getParent() != null ) { + output.println(" seseToIssue->"+dynInVar+" = "+ + generateTemp( fsen.getParent().getfmBogus(), dynInVar, null )+";"); + } else { + output.println(" seseToIssue->"+dynInVar+" = "+ + generateTemp( fsen.getfmEnclosing(), dynInVar, null )+";"); + } output.println(" }"); output.println(" }"); @@ -2948,9 +2962,11 @@ public class BuildCode { } // maintain pointers for for finding dynamic SESE - // instances from static names + // instances from static names SESEandAgePair p = new SESEandAgePair( fsen, 0 ); - if( fsen.getParent().getNeededStaticNames().contains( p ) ) { + if( fsen.getParent() != null && + fsen.getParent().getNeededStaticNames().contains( p ) ) { + for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) { SESEandAgePair p1 = new SESEandAgePair( fsen, i ); SESEandAgePair p2 = new SESEandAgePair( fsen, i-1 ); @@ -2982,8 +2998,20 @@ public class BuildCode { return; } + output.println(" /* SESE exiting */"); + String com = paramsprefix+"->common"; + // take yourself off the thread-local sese call stack + output.println(" if( isEmpty( seseCallStack ) ) {"); + output.println(" printf( \"Error, sese call stack is empty.\\n\" );"); + output.println(" exit( -1 );"); + output.println(" }"); + output.println(" if( (void*)"+paramsprefix+" != getItem( seseCallStack ) ) {"); + output.println(" printf( \"Error, sese call stack mismatch.\\n\" );"); + output.println(" exit( -1 );"); + output.println(" }"); + // 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 @@ -2991,7 +3019,6 @@ public class BuildCode { output.println(" while( "+com+".numRunningChildren > 0 ) {"); output.println(" pthread_cond_wait( &("+com+".runningChildrenCond), &("+com+".lock) );"); output.println(" }"); - //output.println(" pthread_mutex_unlock( &("+com+".lock) );"); // copy out-set from local temps into the sese record Iterator itr = fsexn.getFlatEnter().getOutVarSet().iterator(); @@ -3003,7 +3030,6 @@ public class BuildCode { } // mark yourself done, your SESE data is now read-only - //output.println(" pthread_mutex_lock( &("+com+".lock) );"); output.println(" "+com+".doneExecuting = TRUE;"); output.println(" pthread_cond_signal( &("+com+".doneCond) );"); output.println(" pthread_mutex_unlock( &("+com+".lock) );"); @@ -3761,12 +3787,6 @@ public class BuildCode { } else output.print(task.getSafeSymbol()+"("); - /* - if (addSESErecord) { - output.print("SESErecord* currentSESE, "); - } - */ - boolean printcomma=false; if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) { if (md!=null) { diff --git a/Robust/src/Runtime/mlp_runtime.c b/Robust/src/Runtime/mlp_runtime.c index bd3455e7..f9860130 100644 --- a/Robust/src/Runtime/mlp_runtime.c +++ b/Robust/src/Runtime/mlp_runtime.c @@ -10,7 +10,12 @@ #include "workschedule.h" + __thread struct Queue* seseCallStack; +__thread pthread_once_t mlpOnceObj = PTHREAD_ONCE_INIT; +void mlpInitOncePerThread() { + seseCallStack = createQueue(); +} void* mlpAllocSESErecord( int size ) { diff --git a/Robust/src/Runtime/mlp_runtime.h b/Robust/src/Runtime/mlp_runtime.h index a4f26d35..71fb7727 100644 --- a/Robust/src/Runtime/mlp_runtime.h +++ b/Robust/src/Runtime/mlp_runtime.h @@ -51,9 +51,11 @@ typedef struct SESEcommon_t { } SESEcommon; -// a thread-local stack of SESE's that have called a -// new method context +// a thread-local stack of SESEs and function to +// ensure it is initialized once per thread extern __thread struct Queue* seseCallStack; +extern __thread pthread_once_t mlpOnceObj; +void mlpInitOncePerThread(); // simple mechanical allocation and diff --git a/Robust/src/Runtime/workschedule.c b/Robust/src/Runtime/workschedule.c index 5b24b68d..08bb5dfb 100644 --- a/Robust/src/Runtime/workschedule.c +++ b/Robust/src/Runtime/workschedule.c @@ -5,7 +5,7 @@ #include "mem.h" #include "Queue.h" #include "workschedule.h" - +#include "mlp_runtime.h" // NOTE: Converting this from a work-stealing strategy @@ -154,6 +154,9 @@ void* workerMain( void* arg ) { void* workUnit; + // make sure init mlp once-per-thread stuff + pthread_once( &mlpOnceObj, mlpInitOncePerThread ); + // all workers wait until system is ready pthread_mutex_lock ( &systemLock ); while( !systemStarted ) { @@ -161,6 +164,7 @@ void* workerMain( void* arg ) { } pthread_mutex_unlock( &systemLock ); + // then continue to process work while( 1 ) { pthread_mutex_lock( &systemLock ); diff --git a/Robust/src/Tests/mlp/tinyTest/test.java b/Robust/src/Tests/mlp/tinyTest/test.java index 2e3cea0e..8677ea17 100644 --- a/Robust/src/Tests/mlp/tinyTest/test.java +++ b/Robust/src/Tests/mlp/tinyTest/test.java @@ -40,9 +40,11 @@ public class Test { //setTo3( foo ); } - public static void mightPrint( int x, int i, int sum ) { + public static void mightPrint( int x, int i, int sum ) { if( i == x - 1 ) { - System.out.println( "sum of integers 0-"+i+" is "+sum ); + sese output { + System.out.println( "sum of integers 0-"+i+" is "+sum ); + } } } -- 2.34.1