if( state.MLPDEBUG ) {
System.out.println( "" );
- //printSESEHierarchy();
- //printSESELiveness();
- //System.out.println( fmMain.printMethod( livenessRootView ) );
- //System.out.println( fmMain.printMethod( variableResults ) );
- //System.out.println( fmMain.printMethod( notAvailableResults ) );
- //System.out.println( "CODE PLANS\n"+fmMain.printMethod( codePlans ) );
+ //System.out.println( "\nSESE Hierarchy\n--------------\n" ); printSESEHierarchy();
+ //System.out.println( "\nSESE Liveness\n-------------\n" ); printSESELiveness();
+ //System.out.println( "\nLiveness Root View\n------------------\n"+fmMain.printMethod( livenessRootView ) );
+ //System.out.println( "\nVariable Results\n----------------\n"+fmMain.printMethod( variableResults ) );
+ //System.out.println( "\nNot Available Results\n---------------------\n"+fmMain.printMethod( notAvailableResults ) );
+ //System.out.println( "\nCode Plans\n----------\n"+fmMain.printMethod( codePlans ) );
}
for( int i = 0; i < depth; ++i ) {
System.out.print( " " );
}
- System.out.println( fsen.getPrettyIdentifier() );
+ System.out.println( "- "+fsen.getPrettyIdentifier() );
Iterator<FlatSESEEnterNode> childItr = fsen.getChildren().iterator();
while( childItr.hasNext() ) {
public String toString() {
- return refVars+" ref "+addrVar+"@"+sese.getPrettyIdentifier()+"("+seseAge+")";
+ return refVars+"\tref "+addrVar+"\t@"+sese.getPrettyIdentifier()+"("+seseAge+")";
}
}
}
/* Build the actual methods */
- if( state.MLP ) {
- outmethod.println("/* GET RID OF THIS LATER */");
- outmethod.println("struct SESErecord* tempSESE;");
- outmethod.println("struct SESErecord* tempParentSESE;");
- }
outputMethods(outmethod);
// Output function prototypes and structures for SESE's and code
outmethod.println(" }");
if (state.MLP) {
+ FlatSESEEnterNode rootSESE = mlpa.getRootSESE();
outmethod.println(" mlpInit();");
- FlatSESEEnterNode rootSESE = mlpa.getRootSESE();
-
+ outmethod.print(" rootsese = mlpCreateSESErecord(");
+ outmethod.print(rootSESE.getIdentifier()+", 0, NULL, 0, NULL");
+ outmethod.println(");");
+
outmethod.println(" ");
}
}
if (state.MLP) {
outmethod.println("#include \"mlp_runtime.h\"");
+ outmethod.println("/* GET RID OF THIS LATER */");
+ outmethod.println("SESErecord* tempSESE;");
+ outmethod.println("SESErecord* tempParentSESE;");
+ outmethod.println("invokeSESEargs* tempSESEargs;");
}
//Store the sizes of classes & array elements
PrintWriter outmethod
) {
- outmethodheader.println("void invokeSESEmethod( int classID, struct SESErecord* invokee, struct SESErecord* parent );");
- outmethod.println( "void invokeSESEmethod( int classID, struct SESErecord* invokee, struct SESErecord* parent ) {");
+ outmethodheader.println("void* invokeSESEmethod( void* vargs );");
+ outmethod.println( "void* invokeSESEmethod( void* vargs ) {");
+ outmethod.println( " invokeSESEargs* args = (invokeSESEargs*) vargs;");
// use this info in the invocation cases to decide whether
// to gather SESE variables from a parent SESE record, or
// if parent is root, from noraml temps
- outmethod.println( " char parentIsRoot = (parent == NULL);");
+ outmethod.println( " char parentIsRoot = (args->parent == NULL);");
// generate a case for each SESE class that can be invoked
- outmethod.println( " switch( classID ) {");
+ outmethod.println( " switch( args->classID ) {");
outmethod.println( " ");
for(Iterator<FlatSESEEnterNode> seseit=mlpa.getAllSESEs().iterator();seseit.hasNext();) {
FlatSESEEnterNode fsen = seseit.next();
// first argument is parameter structure
output.print("(struct "+cn.getSafeSymbol()+bogusmd.getSafeSymbol()+"__params*)");
- output.print("&(invokee->paramStruct)");
+ output.print("&(args->invokee->paramStruct)");
// other arguments are primitive parameters
for(int i=0; i<objectparams.numPrimitives(); i++) {
TempDescriptor td=objectparams.getPrimitive(i);
TypeDescriptor type=td.getType();
assert type.isPrimitive();
- output.print(", invokee->vars["+i+"].sesetype_"+type.toString());
+ output.print(", args->invokee->vars["+i+"].sesetype_"+type.toString());
}
output.println(");");
return;
}
- output.println(" tempSESE = (struct SESErecord*) malloc( sizeof( struct SESErecord ) );");
- output.println(" tempSESE->vars = (struct SESEvar*) malloc( sizeof( struct SESEvar ) * "+
+ output.println(" tempSESE = (SESErecord*) malloc( sizeof( SESErecord ) );");
+ output.println(" tempSESE->vars = (SESEvar*) malloc( sizeof( SESEvar ) * "+
+fsen.numParameters()+
");");
output.println(" mlpIssue( tempSESE );");
output.println(" tempSESE = mlpSchedule();");
output.println(" tempParentSESE = mlpGetCurrent();");
- output.println(" invokeSESEmethod("+
- fsen.getIdentifier()+", "+
- "tempSESE, "+
- "tempParentSESE"+
- ");"
- );
+
+ // do a pthread_create wit invokeSESE as the argument
+ // and pack all args into a single void*
+ output.println(" tempSESEargs = (invokeSESEargs*) malloc( sizeof( invokeSESEargs ) );");
+ output.println(" tempSESEargs->classID = "+fsen.getIdentifier()+";");
+ output.println(" tempSESEargs->invokee = tempSESE;");
+ output.println(" tempSESEargs->parent = tempParentSESE;");
+
+ output.println(" invokeSESEmethod( (void*) tempSESEargs );");
}
public void generateFlatSESEExitNode(FlatMethod fm, LocalityBinding lb, FlatSESEExitNode fsen, PrintWriter output) {
#include "Queue.h"
+#define FALSE 0
+#define TRUE 1
+
+
// the root sese is accessible globally so
// buildcode can generate references to it
-struct SESErecord* rootsese;
+SESErecord* rootsese;
// the issuedQ, in this simple version, spits
// the class_age2instance maps an SESE class id and
// age value to a particular SESErecord instance
-static struct SESErecord** class_age2instance;
+static SESErecord** class_age2instance;
+
+
+// each core/pthread should have a current SESE
+static SESErecord* current;
+
+
+SESErecord* mlpCreateSESErecord( int classID,
+ int instanceID,
+ SESErecord* parent,
+ int numVars,
+ void* paramStruct
+ ) {
+
+ SESErecord* newrec = malloc( sizeof( SESErecord ) );
+
+ newrec->classID = classID;
+ newrec->instanceID = instanceID;
+ newrec->childInstanceIDs = 0;
+ newrec->parent = parent;
+ newrec->childrenList = createQueue();
+ newrec->vars = (SESEvar*) malloc( sizeof( SESEvar ) *
+ numVars
+ );
+ newrec->paramStruct = paramStruct;
+ newrec->forwardList = createQueue();
+ newrec->doneExecuting = FALSE;
+ newrec->startCondVar = (pthread_cond_t*) malloc( sizeof( pthread_cond_t ) );
+ newrec->startCondVarLock = (pthread_mutex_t*) malloc( sizeof( pthread_mutex_t ) );
+ newrec->forwardListLock = (pthread_mutex_t*) malloc( sizeof( pthread_mutex_t ) );
-// each core should have a current SESE
-static struct SESErecord* current;
+ pthread_cond_init ( newrec->startCondVar, NULL );
+ pthread_mutex_init( newrec->startCondVarLock, NULL );
+ pthread_mutex_init( newrec->forwardListLock, NULL );
+
+ 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 );
+}
void mlpInit( int totalNumSESEs, int maxSESEage ) {
- rootsese = (struct SESErecord*) malloc( sizeof( struct SESErecord ) );
issuedQ = createQueue();
- class_age2instance = (struct SESErecord**) malloc( sizeof( struct SESErecord* ) *
- maxSESEage *
+ class_age2instance = (SESErecord**) malloc( sizeof( SESErecord* ) *
+ maxSESEage *
totalNumSESEs
);
-
current = rootsese;
}
-struct SESErecord* mlpGetCurrent() {
+SESErecord* mlpGetCurrent() {
return current;
}
-void mlpIssue( struct SESErecord* sese ) {
+void mlpIssue( SESErecord* sese ) {
addNewItem( issuedQ, (void*) sese );
}
-struct SESErecord* mlpSchedule() {
+SESErecord* mlpSchedule() {
assert( !isEmpty( issuedQ ) );
- return (struct SESErecord*) getItem( issuedQ );
+ return (SESErecord*) getItem( issuedQ );
}
-void mlpStall( struct SESErecord* sese ) {
+void mlpStall( SESErecord* sese ) {
}
-void mlpNotifyExit( struct SESErecord* sese ) {
+void mlpNotifyExit( SESErecord* sese ) {
}
#include "Queue.h"
-// value mode means the variable's value
-// is present in the SESEvar struct
-#define SESEvar_MODE_VALUE 3001
-
-// static move means the variable's value
-// will come from a statically known SESE
-#define SESEvar_MODE_STATIC 3002
-
-// dynamic mode means the variable's value
-// will come from an SESE, and the exact
-// SESE will be determined at runtime
-#define SESEvar_MODE_DYNAMIC 3003
-
-
// a forward delcaration for SESEvar
-struct SESErecord;
+struct SESErecord_t;
-struct SESEvar {
- unsigned char mode;
+typedef struct SESEvar_t {
+ //unsigned char mode;
// the value when it is known will be placed
// in this location, which can be accessed
// if source==NULL it indicates the root
// SESE, which has no record, just normal
// temp names
- struct SESErecord* source;
- unsigned int index;
-};
+ //struct SESErecord_t* source;
+ //unsigned int index;
+} SESEvar;
-struct SESErecord {
+typedef struct SESErecord_t {
// the identifier for the class of sese's that
// are instances of one particular static code block
int classID;
// the parent itself
int instanceID;
+ // used to give out IDs to children
+ int childInstanceIDs;
+
+ // pointers to SESEs directly above or below
+ // in the heirarchy
+ struct SESErecord_t* parent;
+ struct Queue* childrenList;
+
// for state of vars after issue
- struct SESEvar* vars;
+ SESEvar* vars;
// when this sese is ready to be invoked,
// allocate and fill in this structure, and
// above var array at the call site
void* paramStruct;
+
+ pthread_cond_t* startCondVar;
+ pthread_mutex_t* startCondVarLock;
+
+
// use a list of SESErecords and a lock to let
// consumers tell this SESE who wants values
// forwarded to it
- pthread_mutex_t forwardListLock;// = PTHREAD_MUTUX_INITIALIZER;
- struct Queue* forwardList;
-};
+ pthread_mutex_t* forwardListLock;
+ struct Queue* forwardList;
+ int doneExecuting;
+} SESErecord;
+
+
+typedef struct invokeSESEargs_t {
+ int classID;
+ SESErecord* invokee;
+ SESErecord* parent;
+} invokeSESEargs;
+
+
+// simple mechanical allocation and deallocation
+// of SESE records
+SESErecord* mlpCreateSESErecord( int classID,
+ int instanceID,
+ SESErecord* parent,
+ int numVars,
+ void* paramStruct
+ );
+
+void mlpDestroySESErecord( SESErecord* sese );
+// main library functions
void mlpInit();
-struct SESErecord* mlpGetCurrent();
-struct SESErecord* mlpSchedule();
+SESErecord* mlpGetCurrent();
+SESErecord* mlpSchedule();
-void mlpIssue ( struct SESErecord* sese );
-void mlpStall ( struct SESErecord* sese );
-void mlpNotifyExit( struct SESErecord* sese );
+void mlpIssue ( SESErecord* sese );
+void mlpStall ( SESErecord* sese );
+void mlpNotifyExit( SESErecord* sese );
-extern struct SESErecord* rootsese;
+extern SESErecord* rootsese;
#endif /* __MLP_RUNTIME__ */