private Hashtable< FlatNode, Set<TempDescriptor> > notAvailableResults;
private Hashtable< FlatNode, CodePlan > codePlans;
- private static final int maxSESEage = 2;
+ private static int maxSESEage = -1;
// use these methods in BuildCode to have access to analysis results
this.typeUtil = tu;
this.callGraph = callGraph;
this.ownAnalysis = ownAnalysis;
+ this.maxSESEage = state.MLP_MAXSESEAGE;
// initialize analysis data structures
allSESEs = new HashSet<FlatSESEEnterNode>();
private void outputMainMethod(PrintWriter outmethod) {
outmethod.println("int main(int argc, const char *argv[]) {");
outmethod.println(" int i;");
- if (state.MLP) {
- outmethod.println(" mlpInit( "+mlpa.getAllSESEs().size()+", "+mlpa.getMaxSESEage()+" );");
- }
if (state.DSM) {
outmethod.println("#ifdef TRANSSTATS \n");
outmethod.println("handle();\n");
if (state.THREAD||state.SINGLETM)
outmethod.println("pthread_exit(NULL);");
+ if (state.MLP) {
+ outmethod.println(" mlpInit( "+state.MLP_NUMCORES+", "+
+ "invokeSESEmethod, "+
+ "argc, "+
+ "argv, "+
+ state.MLP_MAXSESEAGE+" );");
+ }
+
outmethod.println("}");
}
PrintWriter outmethod
) {
- outmethodheader.println("void invokeSESEmethod( void* vargs );");
- outmethod.println( "void invokeSESEmethod( void* vargs ) {");
+ outmethodheader.println("void invokeSESEmethod( void* seseRecord );");
+ outmethod.println( "void invokeSESEmethod( void* seseRecord ) {");
outmethod.println( " int status;");
outmethod.println( " char errmsg[128];");
- outmethod.println( " invokeSESEargs* args = (invokeSESEargs*) vargs;");
-
- /*
- // wait on a condition variable that dispatcher will signal
- // then this SESE instance's dependencies are resolved
- outmethod.println( " status = pthread_mutex_lock( args->invokee->startCondVarLock );");
- outmethod.println( " "+mlperrstr);
- outmethod.println( " while( !(args->invokee->startedExecuting) ){");
- outmethod.println( " status = pthread_cond_wait( args->invokee->startCondVar, args->invokee->startCondVarLock );");
- outmethod.println( " "+mlperrstr);
- outmethod.println( " }");
- */
+ outmethod.println( " SESErecord* rec = (SESErecord*) seseRecord;");
// generate a case for each SESE class that can be invoked
- outmethod.println( " switch( args->classID ) {");
+ outmethod.println( " switch( rec->classID ) {");
outmethod.println( " ");
for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
FlatSESEEnterNode fsen = seseit.next();
private void generateSESEinvocation(FlatSESEEnterNode fsen,
PrintWriter output
) {
-
+ /*
FlatMethod fm = fsen.getEnclosingFlatMeth();
MethodDescriptor md = fm.getMethod();
ClassDescriptor cn = md.getClassDesc();
}
output.println(");");
+ */
}
protected void generateMethodSESE(FlatSESEEnterNode fsen,
PrintWriter outputMethods
) {
-
+ /*
FlatMethod fm = fsen.getEnclosingFlatMeth();
MethodDescriptor md = fm.getMethod();
ClassDescriptor cn = md.getClassDesc();
generateFlatMethodSESE(bogusfm, cn, fsen, fsen.getFlatExit(), outputMethods);
+ */
}
private void generateFlatMethodSESE(FlatMethod fm,
// TODO: only do this if we know the method actually
// contains an SESE issue, not currently an annotation
if( state.MLP ) {
+ /*
output.println(" SESErecord* tempSESE;");
output.println(" invokeSESEargs* tempSESEargs;");
+ */
}
/* Assign labels to FlatNode's if necessary.*/
}
if( state.MLP ) {
-
+ /*
CodePlan cp = mlpa.getCodePlan( fn );
if( cp != null ) {
}
}
+ */
}
}
// SESE nodes can be parsed for normal compilation, just skip over them
return;
}
-
- output.println("\n /* SESE "+fsen.getPrettyIdentifier()+" issue */");
- output.println(" tempSESE = mlpCreateSESErecord( "+
+
+ // output.println("\n /* SESE "+fsen.getPrettyIdentifier()+" issue */");
+
+ /*
+ output.println(" tempSESE = mlpCreateSESErecord( "+
fsen.getIdentifier()+", "+
"malloc( sizeof( "+fsen.namespaceStructNameString()+") ), "+
"NULL );");
output.println(" invokeSESEmethod( (void*) tempSESEargs );");
output.println("\n");
+ */
}
public void generateFlatSESEExitNode(FlatMethod fm, LocalityBinding lb, FlatSESEExitNode fsen, PrintWriter output) {
public boolean INSTRUCTIONFAILURE=false;
public boolean MLP=false;
public boolean MLPDEBUG=false;
+ public int MLP_NUMCORES=0;
+ public int MLP_MAXSESEAGE=0;
public static double TRUEPROB=0.8;
public static boolean PRINTFLAT=false;
public static boolean PRINTSCHEDULING=false;
state.INSTRUCTIONFAILURE=true;
else if (option.equals("-abcclose"))
state.ARRAYBOUNDARYCHECK=false;
+
else if (option.equals("-mlp")) {
- state.MLP=true;
- state.OWNERSHIP=true;
+ state.MLP = true;
+ state.OWNERSHIP = true;
+ state.MLP_NUMCORES = Integer.parseInt( args[++i] );
+ state.MLP_MAXSESEAGE = Integer.parseInt( args[++i] );
+
} else if (option.equals("-mlpdebug")) {
- state.MLP=true;
state.MLPDEBUG=true;
- state.OWNERSHIP=true;
+
} else if (option.equals("-help")) {
System.out.println("-classlibrary classlibrarydirectory -- directory where classlibrary is located");
System.out.println("-selfloop task -- this task doesn't self loop its parameters forever");
System.out.println("-optional -- enable optional arguments");
System.out.println("-abcclose close the array boundary check");
System.out.println("-scheduling do task scheduling");
- System.out.println("-mlp build mlp code");
- System.out.println("-mlp build mlp code, report progress and interim results");
+ System.out.println("-mlp <num cores> <max sese age> build mlp code");
+ System.out.println("-mlpdebug if mlp, report progress and interim results");
System.out.println("-multicore generate multi-core version binary");
System.out.println("-numcore set the number of cores (should be used together with -multicore), defaultly set as 1");
System.out.println("-interrupt generate raw version binary with interruption (should be used togethere with -raw)");
#include <stdio.h>
#include <assert.h>
-#include "mlp_runtime.h"
+#include "mem.h"
#include "Queue.h"
+#include "mlp_runtime.h"
+#include "workschedule.h"
#define FALSE 0
#define TRUE 1
-// the root sese is accessible globally so
-// buildcode can generate references to it
-//SESErecord* rootsese;
-
-
-// the issuedQ, in this simple version, spits
-// out SESErecord's in the order they were issued
-static struct Queue* issuedQ;
-
-
-
SESErecord* mlpCreateSESErecord( int classID,
- void* namespace,
- void* paramStruct
+ void* inSetObjs,
+ void* outSetObjsNotInInSet,
+ void* inSetPrims,
+ void* outSetPrimsNotInInSet
) {
- SESErecord* newrec = malloc( sizeof( SESErecord ) );
-
- //newrec->parent = parent;
- //newrec->childrenList = createQueue();
- //newrec->vars = malloc( sizeof( SESEvar ) * numVars );
-
- newrec->classID = classID;
- newrec->namespace = namespace;
- newrec->paramStruct = paramStruct;
+ SESErecord* newrec = RUNMALLOC( sizeof( SESErecord ) );
- newrec->forwardList = createQueue();
- newrec->doneExecuting = FALSE;
- //newrec->startedExecuting = FALSE;
+ newrec->classID = classID;
+ newrec->inSetObjs = inSetObjs;
+ newrec->outSetObjsNotInInSet = outSetObjsNotInInSet;
+ newrec->inSetPrims = inSetPrims;
+ newrec->outSetPrimsNotInInSet = outSetPrimsNotInInSet;
- psem_init ( &(newrec->stallSem) );
-
- /*
- pthread_cond_init ( newrec->startCondVar, NULL );
- pthread_mutex_init( newrec->startCondVarLock, NULL );
- pthread_mutex_init( newrec->forwardListLock, NULL );
- */
+ pthread_mutex_init( &(newrec->lock), NULL );
+ newrec->forwardList = createQueue();
+ newrec->doneExecuting = FALSE;
return newrec;
}
void mlpDestroySESErecord( SESErecord* sese ) {
- /*
- pthread_cond_destroy ( sese->startCondVar );
- pthread_mutex_destroy( sese->startCondVarLock );
- pthread_mutex_destroy( sese->forwardListLock );
- */
-
- /*
- free ( sese->startCondVar );
- free ( sese->startCondVarLock );
- free ( sese->forwardListLock );
- freeQueue( sese->forwardList );
- //freeQueue( sese->childrenList );
- free ( sese->vars );
- */
- free ( sese->namespace );
- free ( sese );
-}
+ pthread_mutex_destroy( &(sese->lock) );
+ freeQueue( sese->forwardList );
+ RUNFREE( sese->inSetObjs );
+ RUNFREE( sese->outSetObjsNotInInSet );
+ RUNFREE( sese->inSetPrims );
+ RUNFREE( sese->outSetPrimsNotInInSet );
+ RUNFREE( sese );
+}
-void mlpInit( int totalNumSESEs, int maxSESEage ) {
- issuedQ = createQueue();
+struct rootSESEinSetObjs { char** argv; };
+struct rootSESEinSetPrims { int argc; };
- /*
- class_age2instance = (SESErecord**) malloc( sizeof( SESErecord* ) *
- maxSESEage *
- totalNumSESEs
- );
- */
- //current = rootsese;
- //current = NULL;
-}
+void mlpInit( int numProcessors,
+ void(*workFunc)(void*),
+ int argc, char** argv,
+ int maxSESEage ) {
+ SESErecord* rootSESE;
+
+ struct rootSESEinSetObjs* inObjs = RUNMALLOC( sizeof( struct rootSESEinSetObjs ) );
+ struct rootSESEinSetPrims* inPrims = RUNMALLOC( sizeof( struct rootSESEinSetPrims ) );
-/*
-SESErecord* mlpGetCurrent() {
- return current;
-}
-*/
+ // first initialize the work scheduler
+ workScheduleInit( numProcessors, workFunc );
-void mlpIssue( SESErecord* sese ) {
- addNewItem( issuedQ, (void*) sese );
-}
+ // the prepare the root SESE
+ inObjs->argv = argv;
+ inPrims->argc = argc;
+ rootSESE = mlpCreateSESErecord( 0, inObjs, NULL, inPrims, NULL );
+ // skip the issue step because the root SESE will
+ // never have outstanding dependencies
+ workScheduleSubmit( (void*) rootSESE );
-SESErecord* mlpSchedule() {
- assert( !isEmpty( issuedQ ) );
- return (SESErecord*) getItem( issuedQ );
+ // now the work scheduler is initialized and work is
+ // in the hopper, so begin processing. This call
+ // will not return
+ workScheduleBegin();
}
-void mlpStall( SESErecord* sese ) {
-
+void mlpIssue( SESErecord* sese ) {
+
}
-void mlpNotifyExit( SESErecord* sese ) {
+void mlpStall( SESErecord* sese ) {
}
// forward delcarations
struct SESErecord_t;
-struct invokeSESEargs_t;
+
+/*
typedef struct SESEvar_t {
// the value when it is known will be placed
// in this location, which can be accessed
void* sesetype_object;
};
} SESEvar;
-
+*/
typedef struct SESErecord_t {
// the identifier for the class of sese's that
// are instances of one particular static code block
int classID;
- // for state of vars after issue
- void* namespace;
-
- // when this sese is ready to be invoked,
- // allocate and fill in this structure, and
- // the primitives will be passed out of the
- // above var array at the call site
- void* paramStruct;
-
- /*
- // for signaling transition from issue
- // to execute
- pthread_cond_t* startCondVar;
- pthread_mutex_t* startCondVarLock;
- int startedExecuting;
- */
-
- // this will not be generally sufficient, but
- // use a semaphore to let a child resume this
- // parent when stall dependency is satisfied
- psemaphore stallSem;
-
- // use a list of SESErecords and a lock to let
- // consumers tell this SESE who wants values
- // forwarded to it
- pthread_mutex_t forwardListLock;
- struct Queue* forwardList;
- int doneExecuting;
+ // The following fields have this structure:
+ // [INTPTR numPtrs][void* next][ptr0][ptr1]...
+ void* inSetObjs;
+ void* outSetObjsNotInInSet;
-} SESErecord;
+ // The following fields point to compile-time
+ // generated structures that have named
+ // primitive fields
+ void* inSetPrims;
+ void* outSetPrimsNotInInSet;
+ // the lock guards the following data SESE's
+ // use to coordinate with one another
+ pthread_mutex_t lock;
+ struct Queue* forwardList;
+ int doneExecuting;
-typedef struct invokeSESEargs_t {
- int classID;
- SESErecord* invokee;
- SESErecord* parent;
-} invokeSESEargs;
+} SESErecord;
// simple mechanical allocation and deallocation
// of SESE records
SESErecord* mlpCreateSESErecord( int classID,
- void* namespace,
- void* paramStruct
- );
+ void* inSetObjs,
+ void* outSetObjsNotInInSet,
+ void* inSetPrims,
+ void* outSetPrimsNotInInSet
+ );
void mlpDestroySESErecord( SESErecord* sese );
// main library functions
void mlpInit();
-
-//SESErecord* mlpGetCurrent();
-SESErecord* mlpSchedule();
-
-void mlpIssue ( SESErecord* sese );
-void mlpStall ( SESErecord* sese );
-void mlpNotifyExit( SESErecord* sese );
-
-
-extern SESErecord* rootsese;
+void mlpIssue( SESErecord* sese );
+void mlpStall( SESErecord* sese );
#endif /* __MLP_RUNTIME__ */
if( pthread_mutex_unlock( &(sem->lock) ) == -1 ) { return -1; }
}
-
-
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
+
+#include "mem.h"
#include "Queue.h"
#include "workschedule.h"
workFunc = func;
// allocate space for worker data
- workerDataArray = malloc( sizeof( workerData ) * numWorkers );
+ workerDataArray = RUNMALLOC( sizeof( workerData ) * numWorkers );
for( i = 0; i < numWorkers; ++i ) {
// the deque
SOURCE_FILES=$(PROGRAM).java
BUILDSCRIPT=~/research/Robust/src/buildscript
-BSFLAGS= -mlpdebug -nooptimize -debug -mainclass Test -ownership -ownallocdepth 1 -ownwritedots final -enable-assertions -flatirusermethods -ownaliasfile aliases.txt
-#BSFLAGS= -mainclass Test -ownership -ownallocdepth 1 -ownwritedots final -enable-assertions -flatirusermethods -ownaliasfile aliases.txt
+USEMLP= #-mlp 1 2 # -mlpdebug # use to turn mlp on and off and make sure rest of build not broken
+BSFLAGS= $(USEMLP) -nooptimize -debug -garbagestats -mainclass Test -ownership -ownallocdepth 1 -ownwritedots final -enable-assertions -flatirusermethods -ownaliasfile aliases.txt
all: $(PROGRAM).bin
NOJAVA=false
CHECKFLAG=false
RECOVERFLAG=false
-MLPFLAG=false
+MLP_ON=false
MLPDEBUG=false
MULTICOREFLAG=false
RAWFLAG=false
elif [[ $1 = '-minimize' ]]
then
JAVAOPTS="$JAVAOPTS -minimize"
+
elif [[ $1 = '-mlp' ]]
then
-MLPFLAG=true
-EXTRAOPTIONS="$EXTRAOPTIONS -precise -lpthread"
+MLP_ON=true
+EXTRAOPTIONS="$EXTRAOPTIONS -DPRECISE_GC -lpthread"
+JAVAOPTS="$JAVAOPTS -mlp $2 $3"
+shift
+shift
+
elif [[ $1 = '-mlpdebug' ]]
then
JAVAOPTS="$JAVAOPTS -mlpdebug"
-MLPFLAG=true
-EXTRAOPTIONS="$EXTRAOPTIONS -precise -lpthread"
+
elif [[ $1 = '-check' ]]
then
CHECKFLAG=true
FILES="$FILES $ROBUSTROOT/Runtime/localobjects.c"
fi
-if $MLPFLAG
+if $MLP_ON
then
FILES="$FILES $ROBUSTROOT/Runtime/mlp_runtime.c"
FILES="$FILES $ROBUSTROOT/Runtime/psemaphore.c"