9 import Analysis.TaskStateAnalysis.*;
10 import Analysis.CallGraph.*;
11 import Analysis.Disjoint.*;
12 import Analysis.OoOJava.*;
13 import Analysis.Loops.*;
14 import Analysis.Locality.*;
18 public class BuildOoOJavaCode extends BuildCode {
20 protected OoOJavaAnalysis oooa;
22 protected String maxTaskRecSizeStr="__maxTaskRecSize___";
24 protected String mlperrstr =
26 "sprintf(errmsg, \"MLP error at %s:%d\", __FILE__, __LINE__); "+
27 "perror(errmsg); exit(-1); }";
29 protected RuntimeConflictResolver rcr = null;
33 public BuildOoOJavaCode(State st,
37 OoOJavaAnalysis oooa, CallGraph callgraph
39 super( st, temptovar, typeutil, sa, callgraph);
45 protected void additionalIncludesMethodsHeader(PrintWriter outmethodheader) {
47 outmethodheader.println("#include <stdlib.h>");
48 outmethodheader.println("#include <stdio.h>");
49 outmethodheader.println("#include <string.h>");
50 outmethodheader.println("#include \"mlp_runtime.h\"");
51 outmethodheader.println("#include \"psemaphore.h\"");
52 outmethodheader.println("#include \"memPool.h\"");
55 outmethodheader.println("#include \"rcr_runtime.h\"");
58 // spit out a global to inform all worker threads what
59 // the maximum size is for any task record
60 outmethodheader.println("extern int "+maxTaskRecSizeStr+";");
64 protected void preCodeGenInitialization() {
66 // have to initialize some SESE compiler data before
67 // analyzing normal methods, which must happen before
68 // generating SESE internal code
70 Iterator<FlatSESEEnterNode> seseit = oooa.getAllSESEs().iterator();
72 while( seseit.hasNext() ) {
73 FlatSESEEnterNode fsen = seseit.next();
77 //TODO signal the object that will report errors
80 rcr = new RuntimeConflictResolver(PREFIX,
83 System.out.println("Runtime Conflict Resolver started.");
84 } catch (FileNotFoundException e) {
85 System.out.println("Runtime Conflict Resolver could not create output file.");
91 protected void initializeSESE(FlatSESEEnterNode fsen) {
93 FlatMethod fm = fsen.getfmEnclosing();
94 MethodDescriptor md = fm.getMethod();
95 ClassDescriptor cn = md.getClassDesc();
97 // Creates bogus method descriptor to index into tables
98 Modifiers modBogus = new Modifiers();
99 MethodDescriptor mdBogus =
100 new MethodDescriptor(modBogus,
101 new TypeDescriptor(TypeDescriptor.VOID),
102 "sese_"+fsen.getPrettyIdentifier()+fsen.getIdentifier()
105 mdBogus.setClassDesc(fsen.getcdEnclosing() );
106 FlatMethod fmBogus = new FlatMethod(mdBogus, null);
107 fsen.setfmBogus(fmBogus);
108 fsen.setmdBogus(mdBogus);
110 Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
111 inSetAndOutSet.addAll(fsen.getInVarSet() );
112 inSetAndOutSet.addAll(fsen.getOutVarSet() );
114 // Build paramsobj for bogus method descriptor
115 ParamsObject objectparams = new ParamsObject(mdBogus, tag++);
116 paramstable.put(mdBogus, objectparams);
118 Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
119 while( itr.hasNext() ) {
120 TempDescriptor temp = itr.next();
121 TypeDescriptor type = temp.getType();
123 objectparams.addPtr(temp);
125 objectparams.addPrim(temp);
129 // Build normal temp object for bogus method descriptor
130 TempObject objecttemps = new TempObject(objectparams, mdBogus, tag++);
131 tempstable.put(mdBogus, objecttemps);
133 for( Iterator nodeit = fsen.getNodeSet().iterator(); nodeit.hasNext(); ) {
134 FlatNode fn = (FlatNode)nodeit.next();
135 TempDescriptor[] writes = fn.writesTemps();
137 for( int i = 0; i < writes.length; i++ ) {
138 TempDescriptor temp = writes[i];
139 TypeDescriptor type = temp.getType();
142 objecttemps.addPtr(temp);
144 objecttemps.addPrim(temp);
151 protected void postCodeGenCleanUp() {
154 System.out.println("Runtime Conflict Resolver Done.");
159 protected void additionalCodeGen(PrintWriter outmethodheader,
160 PrintWriter outstructs,
161 PrintWriter outmethod) {
163 // Output function prototypes and structures for SESE's and code
165 // spit out a global to inform all worker threads with
166 // the maximum size is for any task record
167 outmethod.println("int "+maxTaskRecSizeStr+" = 0;");
169 // first generate code for each sese's internals
170 Iterator<FlatSESEEnterNode> seseit;
171 seseit = oooa.getAllSESEs().iterator();
173 while( seseit.hasNext() ) {
174 FlatSESEEnterNode fsen = seseit.next();
175 generateMethodSESE(fsen, outstructs, outmethodheader, outmethod);
178 // then write the invokeSESE switch to decouple scheduler
179 // from having to do unique details of sese invocation
180 generateSESEinvocationMethod(outmethodheader, outmethod);
184 protected void additionalCodeAtTopOfMain(PrintWriter outmethod) {
186 // do a calculation to determine which task record
187 // is the largest, store that as a global value for
188 // allocating records
189 Iterator<FlatSESEEnterNode> seseit = oooa.getAllSESEs().iterator();
190 while( seseit.hasNext() ) {
191 FlatSESEEnterNode fsen = seseit.next();
192 outmethod.println("if( sizeof( "+fsen.getSESErecordName()+
193 " ) > "+maxTaskRecSizeStr+
194 " ) { "+maxTaskRecSizeStr+
195 " = sizeof( "+fsen.getSESErecordName()+
199 outmethod.println(" runningSESE = NULL;");
201 outmethod.println(" workScheduleInit( "+state.OOO_NUMCORES+", invokeSESEmethod );");
203 //initializes data structures needed for the RCR traverser
204 if( state.RCR && rcr != null ) {
205 outmethod.println(" initializeStructsRCR();");
206 outmethod.println(" createAndFillMasterHashStructureArray();");
211 protected void additionalCodeAtBottomOfMain(PrintWriter outmethod) {
212 outmethod.println(" workScheduleBegin();");
216 protected void additionalIncludesMethodsImplementation(PrintWriter outmethod) {
217 outmethod.println("#include <stdlib.h>");
218 outmethod.println("#include <stdio.h>");
219 outmethod.println("#include \"mlp_runtime.h\"");
220 outmethod.println("#include \"psemaphore.h\"");
223 outmethod.println("#include \"trqueue.h\"");
224 outmethod.println("#include \"RuntimeConflictResolver.h\"");
225 outmethod.println("#include \"rcr_runtime.h\"");
226 outmethod.println("#include \"hashStructure.h\"");
231 protected void additionalIncludesStructsHeader(PrintWriter outstructs) {
232 outstructs.println("#include \"mlp_runtime.h\"");
233 outstructs.println("#include \"psemaphore.h\"");
235 outstructs.println("#include \"rcr_runtime.h\"");
240 protected void additionalClassObjectFields(PrintWriter outclassdefs) {
241 outclassdefs.println(" int oid;");
245 protected void additionalCodeAtTopMethodsImplementation(PrintWriter outmethod) {
246 outmethod.print("extern __thread int oid;\n");
247 outmethod.print("extern int oidIncrement;\n");
251 protected void additionalCodeAtTopFlatMethodBody(PrintWriter output, FlatMethod fm) {
253 // declare variables for naming static and dynamic SESE's
254 ContextTaskNames context = oooa.getContextTaskNames(fm);
256 output.println(" /* static SESE names */");
257 Iterator<SESEandAgePair> pItr = context.getNeededStaticNames().iterator();
258 while( pItr.hasNext() ) {
259 SESEandAgePair pair = pItr.next();
260 output.println(" void* "+pair+" = NULL;");
263 output.println(" /* dynamic variable sources */");
264 Iterator<TempDescriptor> dynSrcItr = context.getDynamicVarSet().iterator();
265 while( dynSrcItr.hasNext() ) {
266 TempDescriptor dynSrcVar = dynSrcItr.next();
267 output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;");
268 output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;");
273 protected void generateMethodSESE(FlatSESEEnterNode fsen,
274 PrintWriter outputStructs,
275 PrintWriter outputMethHead,
276 PrintWriter outputMethods) {
278 ParamsObject objectparams = (ParamsObject) paramstable.get(fsen.getmdBogus() );
279 TempObject objecttemps = (TempObject) tempstable.get(fsen.getmdBogus() );
281 // generate locals structure
282 outputStructs.println("struct "+
283 fsen.getcdEnclosing().getSafeSymbol()+
284 fsen.getmdBogus().getSafeSymbol()+"_"+
285 fsen.getmdBogus().getSafeMethodDescriptor()+
288 outputStructs.println(" int size;");
289 outputStructs.println(" void * next;");
291 for(int i=0; i<objecttemps.numPointers(); i++) {
292 TempDescriptor temp=objecttemps.getPointer(i);
294 if (temp.getType().isNull())
295 outputStructs.println(" void * "+temp.getSafeSymbol()+";");
297 outputStructs.println(" struct "+
298 temp.getType().getSafeSymbol()+" * "+
299 temp.getSafeSymbol()+";");
301 outputStructs.println("};\n");
304 // divide in-set and out-set into objects and primitives to prep
305 // for the record generation just below
306 Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
307 inSetAndOutSet.addAll(fsen.getInVarSet() );
308 inSetAndOutSet.addAll(fsen.getOutVarSet() );
310 Set<TempDescriptor> inSetAndOutSetObjs = new HashSet<TempDescriptor>();
311 Set<TempDescriptor> inSetAndOutSetPrims = new HashSet<TempDescriptor>();
313 Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
314 while( itr.hasNext() ) {
315 TempDescriptor temp = itr.next();
316 TypeDescriptor type = temp.getType();
318 inSetAndOutSetObjs.add(temp);
320 inSetAndOutSetPrims.add(temp);
325 // generate the SESE record structure
326 outputStructs.println(fsen.getSESErecordName()+" {");
328 // data common to any SESE, and it must be placed first so
329 // a module that doesn't know what kind of SESE record this
330 // is can cast the pointer to a common struct
331 outputStructs.println(" SESEcommon common;");
333 // then garbage list stuff
334 outputStructs.println(" /* next is in-set and out-set objects that look like a garbage list */");
335 outputStructs.println(" int size;");
336 outputStructs.println(" void * next;");
338 // I think that the set of TempDescriptors inSetAndOutSetObjs
339 // calculated above should match the pointer object params
340 // used in the following code, but let's just leave the working
341 // implementation unless there is actually a problem...
343 Vector<TempDescriptor> inset=fsen.getInVarsForDynamicCoarseConflictResolution();
344 for(int i=0; i<inset.size(); i++) {
345 TempDescriptor temp=inset.get(i);
346 if (temp.getType().isNull())
347 outputStructs.println(" void * "+temp.getSafeSymbol()+
348 "; /* in-or-out-set obj in gl */");
350 outputStructs.println(" struct "+temp.getType().getSafeSymbol()+" * "+
351 temp.getSafeSymbol()+"; /* in-or-out-set obj in gl */");
354 for(int i=0; i<objectparams.numPointers(); i++) {
355 TempDescriptor temp=objectparams.getPointer(i);
356 if (!inset.contains(temp)) {
357 if (temp.getType().isNull())
358 outputStructs.println(" void * "+temp.getSafeSymbol()+
359 "; /* in-or-out-set obj in gl */");
361 outputStructs.println(" struct "+temp.getType().getSafeSymbol()+" * "+
362 temp.getSafeSymbol()+"; /* in-or-out-set obj in gl */");
366 outputStructs.println(" /* next is primitives for in-set and out-set and dynamic tracking */");
368 Iterator<TempDescriptor> itrPrims = inSetAndOutSetPrims.iterator();
369 while( itrPrims.hasNext() ) {
370 TempDescriptor temp = itrPrims.next();
371 TypeDescriptor type = temp.getType();
372 if(type.isPrimitive()) {
373 outputStructs.println(" "+temp.getType().getSafeSymbol()+" "+
374 temp.getSafeSymbol()+"; /* in-set or out-set primitive */");
378 // note that the sese record pointer will be added below, just primitive part of tracking here
379 Iterator<TempDescriptor> itrDynInVars = fsen.getDynamicInVarSet().iterator();
380 while( itrDynInVars.hasNext() ) {
381 TempDescriptor dynInVar = itrDynInVars.next();
382 outputStructs.println(" INTPTR "+dynInVar+"_srcOffset; /* dynamic tracking primitive */");
386 outputStructs.println(" /* everything after this should be pointers to an SESE record */");
388 // other half of info for dynamic tracking, the SESE record pointer
389 itrDynInVars = fsen.getDynamicInVarSet().iterator();
390 while( itrDynInVars.hasNext() ) {
391 TempDescriptor dynInVar = itrDynInVars.next();
392 String depRecField = dynInVar+"_srcSESE";
393 outputStructs.println(" SESEcommon* "+depRecField+";");
394 addingDepRecField(fsen, depRecField);
397 // statically known sese sources are record pointers, too
398 Iterator<SESEandAgePair> itrStaticInVarSrcs = fsen.getStaticInVarSrcs().iterator();
399 while( itrStaticInVarSrcs.hasNext() ) {
400 SESEandAgePair srcPair = itrStaticInVarSrcs.next();
401 outputStructs.println(" "+srcPair.getSESE().getSESErecordName()+"* "+srcPair+";");
402 addingDepRecField(fsen, srcPair.toString());
406 if (inset.size()!=0) {
407 outputStructs.println("struct rcrRecord rcrRecords["+inset.size()+"];");
411 if( fsen.getFirstDepRecField() != null ) {
412 outputStructs.println(" /* compiler believes first dependent SESE record field above is: "+
413 fsen.getFirstDepRecField()+" */");
415 outputStructs.println("};\n");
418 // write method declaration to header file
419 outputMethHead.print("void ");
420 outputMethHead.print(fsen.getSESEmethodName()+"(");
421 outputMethHead.print(fsen.getSESErecordName()+"* "+paramsprefix);
422 outputMethHead.println(");\n");
425 generateFlatMethodSESE(fsen.getfmBogus(),
426 fsen.getcdEnclosing(),
432 // used when generating the specific SESE record struct
433 // to remember the FIRST field name of sese records
434 // that the current SESE depends on--we need to know the
435 // offset to the first one for garbage collection
436 protected void addingDepRecField(FlatSESEEnterNode fsen,
438 if( fsen.getFirstDepRecField() == null ) {
439 fsen.setFirstDepRecField(field);
441 fsen.incNumDepRecs();
445 private void generateFlatMethodSESE(FlatMethod fm,
447 FlatSESEEnterNode fsen,
448 FlatSESEExitNode seseExit,
452 MethodDescriptor md = fm.getMethod();
454 output.print("void ");
455 output.print(fsen.getSESEmethodName()+"(");
456 output.print(fsen.getSESErecordName()+"* "+paramsprefix);
457 output.println("){\n");
460 TempObject objecttemp=(TempObject) tempstable.get(md);
462 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
463 output.print(" struct "+
465 md.getSafeSymbol()+"_"+
466 md.getSafeMethodDescriptor()+
467 "_locals "+localsprefix+"={");
468 output.print(objecttemp.numPointers()+",");
469 output.print("&(((SESEcommon*)(___params___))[1])");
470 for(int j=0; j<objecttemp.numPointers(); j++)
471 output.print(", NULL");
472 output.println("};");
475 output.println(" /* regular local primitives */");
476 for(int i=0; i<objecttemp.numPrimitives(); i++) {
477 TempDescriptor td=objecttemp.getPrimitive(i);
478 TypeDescriptor type=td.getType();
480 output.println(" void * "+td.getSafeSymbol()+";");
481 else if (type.isClass()||type.isArray())
482 output.println(" struct "+type.getSafeSymbol()+" * "+td.getSafeSymbol()+";");
484 output.println(" "+type.getSafeSymbol()+" "+td.getSafeSymbol()+";");
488 // declare variables for naming static and dynamic SESE's
489 ContextTaskNames context = oooa.getContextTaskNames(fsen);
491 output.println(" /* static SESE names */");
492 Iterator<SESEandAgePair> pItr = context.getNeededStaticNames().iterator();
493 while( pItr.hasNext() ) {
494 SESEandAgePair pair = pItr.next();
495 output.println(" SESEcommon* "+pair+" = NULL;");
498 // declare variables for tracking dynamic sources
499 output.println(" /* dynamic variable sources */");
500 Iterator<TempDescriptor> dynSrcItr = context.getDynamicVarSet().iterator();
501 while( dynSrcItr.hasNext() ) {
502 TempDescriptor dynSrcVar = dynSrcItr.next();
503 output.println(" SESEcommon* "+dynSrcVar+"_srcSESE = NULL;");
504 output.println(" INTPTR "+dynSrcVar+"_srcOffset = 0x1;");
508 // declare local temps for in-set primitives, and if it is
509 // a ready-source variable, get the value from the record
510 output.println(" /* local temps for in-set primitives */");
511 Iterator<TempDescriptor> itrInSet = fsen.getInVarSet().iterator();
512 while( itrInSet.hasNext() ) {
513 TempDescriptor temp = itrInSet.next();
514 TypeDescriptor type = temp.getType();
515 if( !type.isPtr() ) {
516 if( fsen.getReadyInVarSet().contains(temp) ) {
517 output.println(" "+type+" "+temp+" = "+paramsprefix+"->"+temp+";");
519 output.println(" "+type+" "+temp+";");
524 // declare local temps for out-set primitives if its not already
525 // in the in-set, and it's value will get written so no problem
526 output.println(" /* local temp for out-set prim, not already in the in-set */");
527 Iterator<TempDescriptor> itrOutSet = fsen.getOutVarSet().iterator();
528 while( itrOutSet.hasNext() ) {
529 TempDescriptor temp = itrOutSet.next();
530 TypeDescriptor type = temp.getType();
531 if( !type.isPtr() && !fsen.getInVarSet().contains(temp) ) {
532 output.println(" "+type+" "+temp+";");
537 // initialize thread-local var to a the task's record, which is fused
538 // with the param list
540 output.println(" // code of this task's body should use this to access the running task record");
541 output.println(" runningSESE = &(___params___->common);");
542 output.println(" childSESE = 0;");
546 // eom - setup memory queue
547 output.println(" // set up memory queues ");
548 output.println(" int numMemoryQueue=0;");
549 output.println(" int memoryQueueItemID=0;");
550 Analysis.OoOJava.ConflictGraph graph = oooa.getConflictGraph(fsen);
551 if( graph != null && graph.hasConflictEdge() ) {
552 output.println(" {");
553 Set<Analysis.OoOJava.SESELock> lockSet = oooa.getLockMappings(graph);
554 System.out.println("#lockSet="+lockSet);
555 if( lockSet.size() > 0 ) {
556 output.println(" numMemoryQueue=" + lockSet.size() + ";");
557 output.println(" runningSESE->numMemoryQueue=numMemoryQueue;");
558 output.println(" runningSESE->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);");
561 output.println(" }");
565 // set up a task's mem pool to recycle the allocation of children tasks
566 // don't bother if the task never has children (a leaf task)
567 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
568 output.println("/////////////////////////////////////////////");
569 output.println("//");
570 output.println("// TODO: use poolcreate to make one record pool");
571 output.println("// per WORKER THREAD and never destroy it...");
572 output.println("//");
573 output.println("/////////////////////////////////////////////");
574 if( !fsen.getIsLeafSESE() ) {
575 output.println(" runningSESE->taskRecordMemPool = poolcreate( "+
576 maxTaskRecSizeStr+", freshTaskRecordInitializer );");
577 if (state.RCR && !rcr.hasEmptyTraversers(fsen)) {
578 output.println(" createTR();");
579 output.println(" runningSESE->allHashStructures=TRqueue->allHashStructures;");
582 // make it clear we purposefully did not initialize this
583 output.println(" runningSESE->taskRecordMemPool = (MemPool*)0x7;");
585 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
588 // copy in-set into place, ready vars were already
589 // copied when the SESE was issued
590 Iterator<TempDescriptor> tempItr;
592 // static vars are from a known SESE
593 output.println(" // copy variables from static sources");
594 tempItr = fsen.getStaticInVarSet().iterator();
595 while( tempItr.hasNext() ) {
596 TempDescriptor temp = tempItr.next();
597 VariableSourceToken vst = fsen.getStaticInVarSrc(temp);
598 SESEandAgePair srcPair = new SESEandAgePair(vst.getSESE(), vst.getAge() );
599 output.println(" "+generateTemp(fsen.getfmBogus(), temp)+
600 " = "+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+";");
603 output.println(" // decrement references to static sources");
604 for( Iterator<SESEandAgePair> pairItr = fsen.getStaticInVarSrcs().iterator(); pairItr.hasNext(); ) {
605 SESEandAgePair srcPair = pairItr.next();
606 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
607 output.println(" {");
608 output.println(" SESEcommon* src = &("+paramsprefix+"->"+srcPair+"->common);");
609 output.println(" RELEASE_REFERENCE_TO( src );");
610 output.println(" }");
611 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
615 // dynamic vars come from an SESE and src
616 output.println(" // copy variables from dynamic sources");
617 tempItr = fsen.getDynamicInVarSet().iterator();
618 while( tempItr.hasNext() ) {
619 TempDescriptor temp = tempItr.next();
620 TypeDescriptor type = temp.getType();
622 // go grab it from the SESE source
623 output.println(" if( "+paramsprefix+"->"+temp+"_srcSESE != NULL ) {");
626 if( type.isNull() ) {
628 } else if( type.isClass() || type.isArray() ) {
629 typeStr = "struct "+type.getSafeSymbol()+"*";
631 typeStr = type.getSafeSymbol();
634 output.println(" "+generateTemp(fsen.getfmBogus(), temp)+
635 " = *(("+typeStr+"*) ((void*)"+
636 paramsprefix+"->"+temp+"_srcSESE + "+
637 paramsprefix+"->"+temp+"_srcOffset));");
639 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
640 output.println(" SESEcommon* src = "+paramsprefix+"->"+temp+"_srcSESE;");
641 output.println(" RELEASE_REFERENCE_TO( src );");
642 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
644 // or if the source was our parent, its already in our record to grab
645 output.println(" } else {");
646 output.println(" "+generateTemp(fsen.getfmBogus(), temp)+
647 " = "+paramsprefix+"->"+temp+";");
648 output.println(" }");
651 // Check to see if we need to do a GC if this is a
652 // multi-threaded program...
653 if ((GENERATEPRECISEGC) || (this.state.MULTICOREGC)) {
654 output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
655 //Don't bother if we aren't in recursive methods...The loops case will catch it
656 // if (callgraph.getAllMethods(md).contains(md)) {
657 // if(this.state.MULTICOREGC) {
658 // output.println("if(gcflag) gc("+localsprefixaddr+");");
660 // output.println("if (unlikely(needtocollect)) checkcollect("+localsprefixaddr+");");
665 if( state.COREPROF ) {
666 output.println("#ifdef CP_EVENTID_TASKEXECUTE");
667 output.println(" CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_BEGIN );");
668 output.println("#endif");
671 HashSet<FlatNode> exitset=new HashSet<FlatNode>();
672 exitset.add(seseExit);
673 generateCode(fsen.getNext(0), fm, exitset, output);
674 output.println("}\n\n");
678 // when a new mlp thread is created for an issued SESE, it is started
679 // by running this method which blocks on a cond variable until
680 // it is allowed to transition to execute. Then a case statement
681 // allows it to invoke the method with the proper SESE body, and after
682 // exiting the SESE method, executes proper SESE exit code before the
683 // thread can be destroyed
684 private void generateSESEinvocationMethod(PrintWriter outmethodheader,
685 PrintWriter outmethod
688 outmethodheader.println("void* invokeSESEmethod( void* seseRecord );");
689 outmethod.println("void* invokeSESEmethod( void* seseRecord ) {");
690 outmethod.println(" int status;");
691 outmethod.println(" char errmsg[128];");
693 // generate a case for each SESE class that can be invoked
694 outmethod.println(" switch( ((SESEcommon*)seseRecord)->classID ) {");
695 outmethod.println(" ");
696 Iterator<FlatSESEEnterNode> seseit;
697 seseit = oooa.getAllSESEs().iterator();
699 while( seseit.hasNext() ) {
700 FlatSESEEnterNode fsen = seseit.next();
702 outmethod.println(" /* "+fsen.getPrettyIdentifier()+" */");
703 outmethod.println(" case "+fsen.getIdentifier()+":");
704 outmethod.println(" "+fsen.getSESEmethodName()+"( seseRecord );");
706 if( fsen.getIsMainSESE() ) {
707 outmethod.println(" workScheduleExit();");
710 outmethod.println(" break;");
711 outmethod.println("");
714 // default case should never be taken, error out
715 outmethod.println(" default:");
716 outmethod.println(" printf(\"Error: unknown SESE class ID in invoke method.\\n\");");
717 outmethod.println(" exit(-30);");
718 outmethod.println(" break;");
719 outmethod.println(" }");
720 outmethod.println(" return NULL;");
721 outmethod.println("}\n\n");
726 protected void stallMEMRCR(FlatMethod fm,
728 Set<WaitingElement> waitingElementSet, PrintWriter output) {
729 output.println("// stall on parent's stall sites ");
730 output.println(" {");
731 output.println(" REntry* rentry;");
732 output.println(" // stallrecord sometimes is used as a task record for instance ");
733 output.println(" // when you call RELEASE_REFERENCE_TO on a stall record.");
734 output.println(" // so the parent field must be initialized.");
735 output.println(" SESEstall * stallrecord=(SESEstall *) poolalloc(runningSESE->taskRecordMemPool);");
736 output.println(" stallrecord->common.parent=runningSESE;");
737 output.println(" stallrecord->common.unresolvedDependencies=10000;");
738 output.println(" stallrecord->common.rcrstatus=1;");
739 output.println(" stallrecord->common.offsetToParamRecords=(INTPTR) & (((SESEstall *)0)->rcrRecords);");
740 output.println(" stallrecord->common.refCount = 3;");
741 output.println(" int localCount=10000;");
742 output.println(" stallrecord->rcrRecords[0].index=0;");
743 output.println(" stallrecord->rcrRecords[0].flag=0;");
744 output.println(" stallrecord->rcrRecords[0].next=NULL;");
745 output.println(" stallrecord->common.parentsStallSem=&runningSESEstallSem;");
746 output.println(" psem_reset( &runningSESEstallSem);");
747 output.println(" stallrecord->tag=runningSESEstallSem.tag;");
749 TempDescriptor stalltd=null;
750 for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext(); ) {
751 WaitingElement waitingElement =(WaitingElement) iterator.next();
752 if (waitingElement.getStatus() >= ConflictNode.COARSE) {
753 output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["
754 + waitingElement.getQueueID() + "]," + waitingElement.getStatus()
755 + ", (SESEcommon *) stallrecord, 1LL);");
757 throw new Error("Fine-grained conflict: This should not happen in RCR");
759 output.println(" rentry->queue=runningSESE->memoryQueueArray["
760 + waitingElement.getQueueID() + "];");
761 output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["
762 + waitingElement.getQueueID() + "],rentry)==NOTREADY) {");
763 output.println(" localCount--;");
764 output.println(" }");
765 output.println("#if defined(RCR)&&!defined(OOO_DISABLE_TASKMEMPOOL)");
766 output.println(" else poolfreeinto(runningSESE->memoryQueueArray["+
767 waitingElement.getQueueID()+
768 "]->rentrypool, rentry);");
769 output.println("#endif");
771 stalltd=waitingElement.getTempDesc();
772 } else if (stalltd!=waitingElement.getTempDesc()) {
773 throw new Error("Multiple temp descriptors at stall site"+stalltd+"!="+waitingElement.getTempDesc());
777 //did all of the course grained stuff
778 output.println(" if(!atomic_sub_and_test(localCount, &(stallrecord->common.unresolvedDependencies))) {");
779 //have to do fine-grained work also
780 output.println(" stallrecord->___obj___=(struct ___Object___ *)"
781 + generateTemp(fm, stalltd) + ";");
782 output.println(" stallrecord->common.classID=-"
783 + rcr.getTraverserID(stalltd, fn) + ";");
785 output.println(" enqueueTR(TRqueue, (void *)stallrecord);");
787 if (state.COREPROF) {
788 output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
790 .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );");
791 output.println("#endif");
794 output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
796 if (state.COREPROF) {
797 output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
799 .println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );");
800 output.println("#endif");
803 output.println(" } else {"); //exit if condition
804 //release traversers reference if we didn't use traverser
805 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
806 output.println(" RELEASE_REFERENCES_TO((SESEcommon *)stallrecord, 2);");
807 output.println("#endif");
808 output.println(" }");
809 //release our reference to stall record
810 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
811 output.println(" RELEASE_REFERENCE_TO((SESEcommon *)stallrecord);");
812 output.println("#endif");
813 output.println(" }"); //exit block
817 protected void additionalCodePreNode(FlatMethod fm,
819 PrintWriter output) {
820 // insert pre-node actions from the code plan
822 CodePlan cp = oooa.getCodePlan(fn);
826 // the current task for a code plan is either the
827 // locally-defined enclosing task, or the caller proxy task.
828 // When it is the caller proxy, it is possible to ask what are
829 // all the possible tasks that the proxy might stand for
830 FlatSESEEnterNode currentSESE = cp.getCurrentSESE();
832 FlatMethod fmContext;
833 if( currentSESE.getIsCallerProxySESE() ) {
834 fmContext = oooa.getContainingFlatMethod(fn);
836 fmContext = currentSESE.getfmBogus();
839 ContextTaskNames contextTaskNames;
840 if( currentSESE.getIsCallerProxySESE() ) {
841 contextTaskNames = oooa.getContextTaskNames(oooa.getContainingFlatMethod(fn) );
843 contextTaskNames = oooa.getContextTaskNames(currentSESE);
846 // for each sese and age pair that this parent statement
847 // must stall on, take that child's stall semaphore, the
848 // copying of values comes after the statement
849 Iterator<VariableSourceToken> vstItr = cp.getStallTokens().iterator();
850 while( vstItr.hasNext() ) {
851 VariableSourceToken vst = vstItr.next();
853 SESEandAgePair pair = new SESEandAgePair(vst.getSESE(), vst.getAge() );
855 output.println(" {");
857 pair.getSESE().getSESErecordName()+"* child = ("+
858 pair.getSESE().getSESErecordName()+"*) "+pair+";");
860 output.println(" SESEcommon* childCom = (SESEcommon*) "+pair+";");
862 if( state.COREPROF ) {
863 output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
864 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );");
865 output.println("#endif");
868 output.println(" pthread_mutex_lock( &(childCom->lock) );");
869 output.println(" if( childCom->doneExecuting == FALSE ) {");
870 output.println(" psem_reset( &runningSESEstallSem );");
871 output.println(" childCom->parentsStallSem = &runningSESEstallSem;");
872 output.println(" pthread_mutex_unlock( &(childCom->lock) );");
873 output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
874 output.println(" } else {");
875 output.println(" pthread_mutex_unlock( &(childCom->lock) );");
876 output.println(" }");
878 // copy things we might have stalled for
879 Iterator<TempDescriptor> tdItr = cp.getCopySet(vst).iterator();
880 while( tdItr.hasNext() ) {
881 TempDescriptor td = tdItr.next();
882 output.println(" "+generateTemp(fmContext, td)+
883 " = child->"+vst.getAddrVar().getSafeSymbol()+";");
886 if( state.COREPROF ) {
887 output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
888 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );");
889 output.println("#endif");
892 output.println(" }");
895 // for each variable with a dynamic source, stall just for that variable
896 Iterator<TempDescriptor> dynItr = cp.getDynamicStallSet().iterator();
897 while( dynItr.hasNext() ) {
898 TempDescriptor dynVar = dynItr.next();
900 // only stall if the dynamic source is not yourself, denoted by src==NULL
901 // otherwise the dynamic write nodes will have the local var up-to-date
902 output.println(" {");
903 output.println(" if( "+dynVar+"_srcSESE != NULL ) {");
905 output.println(" SESEcommon* childCom = (SESEcommon*) "+dynVar+"_srcSESE;");
907 if( state.COREPROF ) {
908 output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
909 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_BEGIN );");
910 output.println("#endif");
913 output.println(" pthread_mutex_lock( &(childCom->lock) );");
914 output.println(" if( childCom->doneExecuting == FALSE ) {");
915 output.println(" psem_reset( &runningSESEstallSem );");
916 output.println(" childCom->parentsStallSem = &runningSESEstallSem;");
917 output.println(" pthread_mutex_unlock( &(childCom->lock) );");
918 output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
919 output.println(" } else {");
920 output.println(" pthread_mutex_unlock( &(childCom->lock) );");
921 output.println(" }");
923 TypeDescriptor type = dynVar.getType();
925 if( type.isNull() ) {
927 } else if( type.isClass() || type.isArray() ) {
928 typeStr = "struct "+type.getSafeSymbol()+"*";
930 typeStr = type.getSafeSymbol();
933 output.println(" "+generateTemp(fmContext, dynVar)+
934 " = *(("+typeStr+"*) ((void*)"+
935 dynVar+"_srcSESE + "+dynVar+"_srcOffset));");
937 if( state.COREPROF ) {
938 output.println("#ifdef CP_EVENTID_TASKSTALLVAR");
939 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLVAR, CP_EVENTTYPE_END );");
940 output.println("#endif");
943 output.println(" }");
944 output.println(" }");
947 // for each assignment of a variable to rhs that has a dynamic source,
948 // copy the dynamic sources
949 Iterator dynAssignItr = cp.getDynAssigns().entrySet().iterator();
950 while( dynAssignItr.hasNext() ) {
951 Map.Entry me = (Map.Entry)dynAssignItr.next();
952 TempDescriptor lhs = (TempDescriptor) me.getKey();
953 TempDescriptor rhs = (TempDescriptor) me.getValue();
955 output.println(" {");
956 output.println(" SESEcommon* oldSrc = "+lhs+"_srcSESE;");
958 output.println(" "+lhs+"_srcSESE = "+rhs+"_srcSESE;");
959 output.println(" "+lhs+"_srcOffset = "+rhs+"_srcOffset;");
961 // no matter what we did above, track reference count of whatever
962 // this variable pointed to, do release last in case we're just
963 // copying the same value in because 1->2->1 is safe but ref count
964 // 1->0->1 has a window where it looks like it should be free'd
965 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
966 output.println(" if( "+rhs+"_srcSESE != NULL ) {");
967 output.println(" ADD_REFERENCE_TO( "+rhs+"_srcSESE );");
968 output.println(" }");
969 output.println(" if( oldSrc != NULL ) {");
970 output.println(" RELEASE_REFERENCE_TO( oldSrc );");
971 output.println(" }");
972 output.println(" }");
973 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
976 // for each lhs that is dynamic from a non-dynamic source, set the
977 // dynamic source vars to the current SESE
978 dynItr = cp.getDynAssignCurr().iterator();
979 while( dynItr.hasNext() ) {
980 TempDescriptor dynVar = dynItr.next();
982 assert contextTaskNames.getDynamicVarSet().contains(dynVar);
984 // first release a reference to current record
985 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
986 output.println(" if( "+dynVar+"_srcSESE != NULL ) {");
987 output.println(" RELEASE_REFERENCE_TO( oldSrc );");
988 output.println(" }");
989 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
991 output.println(" "+dynVar+"_srcSESE = NULL;");
995 // handling stall site, consider that one of several tasks might be
996 // executing, so create a switch on task ID, because waiting elements
997 // generated by this stall site should be inserted into possibly a
998 // different memory queue index, depending on which task type it is
999 // update: only generate the switch statement if there is at least
1000 // one non-empty case that will go in it!
1001 boolean atLeastOneCase = false;
1003 // create a case for each class of task that might be executing
1004 Iterator<FlatSESEEnterNode> taskItr = oooa.getPossibleExecutingRBlocks(fn).iterator();
1005 while( taskItr.hasNext() ) {
1006 FlatSESEEnterNode parent = taskItr.next();
1007 ConflictGraph graph = oooa.getConflictGraph(parent);
1009 if( graph == null ) {
1013 Set<SESELock> seseLockSet = oooa.getLockMappings(graph);
1014 Set<WaitingElement> waitingElementSet = graph.getStallSiteWaitingElementSet(fn, seseLockSet);
1016 if( waitingElementSet.size() == 0 ) {
1020 // TODO: THIS STRATEGY CAN BE OPTIMIZED EVEN FURTHER, IF THERE
1021 // IS EXACTLY ONE CASE, DON'T GENERATE A SWITCH AT ALL
1022 if( atLeastOneCase == false ) {
1023 atLeastOneCase = true;
1024 output.println(" // potential stall site ");
1025 output.println(" switch( runningSESE->classID ) {");
1028 output.println(" case "+parent.getIdentifier()+": {");
1031 stallMEMRCR(fm, fn, waitingElementSet, output);
1034 output.println(" REntry* rentry;");
1036 for( Iterator iterator = waitingElementSet.iterator(); iterator.hasNext(); ) {
1037 WaitingElement waitingElement = (WaitingElement) iterator.next();
1039 if (waitingElement.getStatus() >= ConflictNode.COARSE) {
1040 output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["
1041 + waitingElement.getQueueID() + "]," + waitingElement.getStatus()
1042 + ", runningSESE);");
1044 output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["
1045 + waitingElement.getQueueID() + "]," + waitingElement.getStatus()
1046 + ", runningSESE, (void*)&"
1047 + generateTemp(fm, waitingElement.getTempDesc()) + ");");
1049 output.println(" rentry->parentStallSem=&runningSESEstallSem;");
1050 output.println(" psem_reset( &runningSESEstallSem);");
1051 output.println(" rentry->tag=runningSESEstallSem.tag;");
1052 output.println(" rentry->queue=runningSESE->memoryQueueArray["
1053 + waitingElement.getQueueID() + "];");
1054 output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["
1055 + waitingElement.getQueueID() + "],rentry)==NOTREADY){");
1056 if (state.COREPROF) {
1057 output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
1058 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_BEGIN );");
1059 output.println("#endif");
1062 output.println(" psem_take( &runningSESEstallSem, (struct garbagelist *)&___locals___ );");
1064 if (state.COREPROF) {
1065 output.println("#ifdef CP_EVENTID_TASKSTALLMEM");
1066 output.println(" CP_LOGEVENT( CP_EVENTID_TASKSTALLMEM, CP_EVENTTYPE_END );");
1067 output.println("#endif");
1069 output.println(" } ");
1073 output.println(" } break; // end case "+parent.getIdentifier());
1076 if( atLeastOneCase ) {
1077 output.println(" } // end stall site switch");
1083 protected void additionalCodePostNode(FlatMethod fm,
1085 PrintWriter output) {
1087 // insert post-node actions from the code-plan (none right now...)
1091 public void generateFlatSESEEnterNode(FlatMethod fm,
1092 FlatSESEEnterNode fsen,
1093 PrintWriter output) {
1095 // there may be an SESE in an unreachable method, skip over
1096 if( !oooa.getAllSESEs().contains(fsen) ) {
1100 // assert we are never generating code for the caller proxy
1101 // it should only appear in analysis results
1102 assert !fsen.getIsCallerProxySESE();
1105 output.println(" { // issue new task instance");
1107 if( state.COREPROF ) {
1108 output.println("#ifdef CP_EVENTID_TASKDISPATCH");
1109 output.println(" CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_BEGIN );");
1110 output.println("#endif");
1114 // before doing anything, lock your own record and increment the running children
1115 if( !fsen.getIsMainSESE() ) {
1116 output.println(" childSESE++;");
1119 // allocate the space for this record
1120 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1122 output.println("#ifdef CP_EVENTID_POOLALLOC");
1123 output.println(" CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_BEGIN );");
1124 output.println("#endif");
1125 if( !fsen.getIsMainSESE() ) {
1127 fsen.getSESErecordName()+"* seseToIssue = ("+
1128 fsen.getSESErecordName()+"*) poolalloc( runningSESE->taskRecordMemPool );");
1129 output.println(" CHECK_RECORD( seseToIssue );");
1132 fsen.getSESErecordName()+"* seseToIssue = ("+
1133 fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+
1134 fsen.getSESErecordName()+" ) );");
1136 output.println("#ifdef CP_EVENTID_POOLALLOC");
1137 output.println(" CP_LOGEVENT( CP_EVENTID_POOLALLOC, CP_EVENTTYPE_END );");
1138 output.println("#endif");
1140 output.println("#else // OOO_DISABLE_TASKMEMPOOL");
1142 fsen.getSESErecordName()+"* seseToIssue = ("+
1143 fsen.getSESErecordName()+"*) mlpAllocSESErecord( sizeof( "+
1144 fsen.getSESErecordName()+" ) );");
1145 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1148 // set up the SESE in-set and out-set objects, which look
1149 // like a garbage list
1150 output.println(" struct garbagelist * gl= (struct garbagelist *)&(((SESEcommon*)(seseToIssue))[1]);");
1151 output.println(" gl->size="+calculateSizeOfSESEParamList(fsen)+";");
1152 output.println(" gl->next = NULL;");
1153 output.println(" seseToIssue->common.rentryIdx=0;");
1156 //flag the SESE status as 1...it will be reset
1157 output.println(" seseToIssue->common.rcrstatus=1;");
1160 // there are pointers to SESE records the newly-issued SESE
1161 // will use to get values it depends on them for--how many
1162 // are there, and what is the offset from the total SESE
1163 // record to the first dependent record pointer?
1164 output.println(" seseToIssue->common.numDependentSESErecords="+
1165 fsen.getNumDepRecs()+";");
1167 // we only need this (and it will only compile) when the number of dependent
1168 // SESE records is non-zero
1169 if( fsen.getFirstDepRecField() != null ) {
1170 output.println(" seseToIssue->common.offsetToDepSESErecords=(INTPTR)sizeof("+
1171 fsen.getSESErecordName()+") - (INTPTR)&((("+
1172 fsen.getSESErecordName()+"*)0)->"+fsen.getFirstDepRecField()+");"
1177 fsen.getInVarsForDynamicCoarseConflictResolution().size() > 0
1179 output.println(" seseToIssue->common.offsetToParamRecords=(INTPTR) & ((("+
1180 fsen.getSESErecordName()+"*)0)->rcrRecords);");
1183 // fill in common data
1184 output.println(" int localCount=0;");
1185 output.println(" seseToIssue->common.classID = "+fsen.getIdentifier()+";");
1186 output.println(" seseToIssue->common.unresolvedDependencies = 10000;");
1187 output.println(" seseToIssue->common.parentsStallSem = NULL;");
1188 output.println(" initQueue(&seseToIssue->common.forwardList);");
1189 output.println(" seseToIssue->common.doneExecuting = FALSE;");
1190 output.println(" seseToIssue->common.numRunningChildren = 0;");
1191 output.println("#ifdef OOO_DISABLE_TASKMEMPOOL");
1192 output.println(" pthread_cond_init( &(seseToIssue->common.runningChildrenCond), NULL );");
1193 output.println("#endif");
1194 output.println(" seseToIssue->common.parent = runningSESE;");
1195 // start with refCount = 2, one being the count that the child itself
1196 // will decrement when it retires, to say it is done using its own
1197 // record, and the other count is for the parent that will remember
1198 // the static name of this new child below
1200 // if we're using RCR, ref count is 3 because the traverser has
1202 if( !fsen.getIsMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0) {
1203 output.println(" seseToIssue->common.refCount = 10003;");
1205 output.println(" seseToIssue->common.refCount = 10002;");
1207 output.println(" int refCount=10000;");
1209 output.println(" seseToIssue->common.refCount = 2;");
1212 // all READY in-vars should be copied now and be done with it
1213 Iterator<TempDescriptor> tempItr = fsen.getReadyInVarSet().iterator();
1214 while( tempItr.hasNext() ) {
1215 TempDescriptor temp = tempItr.next();
1217 // determine whether this new task instance is in a method context,
1218 // or within the body of another task
1219 assert !fsen.getIsCallerProxySESE();
1220 FlatSESEEnterNode parent = fsen.getLocalParent();
1221 if( parent != null && !parent.getIsCallerProxySESE() ) {
1222 output.println(" seseToIssue->"+temp+" = "+
1223 generateTemp(parent.getfmBogus(), temp)+";");
1225 output.println(" seseToIssue->"+temp+" = "+
1226 generateTemp(fsen.getfmEnclosing(), temp)+";");
1230 // before potentially adding this SESE to other forwarding lists,
1232 output.println("#ifdef OOO_DISABLE_TASKMEMPOOL");
1233 output.println(" pthread_mutex_init( &(seseToIssue->common.lock), NULL );");
1234 output.println("#endif");
1236 if( !fsen.getIsMainSESE() ) {
1237 // count up outstanding dependencies, static first, then dynamic
1238 Iterator<SESEandAgePair> staticSrcsItr = fsen.getStaticInVarSrcs().iterator();
1239 while( staticSrcsItr.hasNext() ) {
1240 SESEandAgePair srcPair = staticSrcsItr.next();
1241 output.println(" {");
1242 output.println(" SESEcommon* src = (SESEcommon*)"+srcPair+";");
1243 output.println(" pthread_mutex_lock( &(src->lock) );");
1244 // FORWARD TODO - ...what? make it a chain of arrays instead of true linked-list?
1245 output.println(" if( !src->doneExecuting ) {");
1246 output.println(" addNewItem( &src->forwardList, seseToIssue );");
1247 output.println(" ++(localCount);");
1248 output.println(" }");
1249 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1250 output.println(" ADD_REFERENCE_TO( src );");
1251 output.println("#endif");
1252 output.println(" pthread_mutex_unlock( &(src->lock) );");
1253 output.println(" }");
1255 // whether or not it is an outstanding dependency, make sure
1256 // to pass the static name to the child's record
1257 output.println(" seseToIssue->"+srcPair+" = "+
1258 "("+srcPair.getSESE().getSESErecordName()+"*)"+
1262 // dynamic sources might already be accounted for in the static list,
1263 // so only add them to forwarding lists if they're not already there
1264 Iterator<TempDescriptor> dynVarsItr = fsen.getDynamicInVarSet().iterator();
1265 while( dynVarsItr.hasNext() ) {
1266 TempDescriptor dynInVar = dynVarsItr.next();
1267 output.println(" {");
1268 output.println(" SESEcommon* src = (SESEcommon*)"+dynInVar+"_srcSESE;");
1270 // the dynamic source is NULL if it comes from your own space--you can't pass
1271 // the address off to the new child, because you're not done executing and
1272 // might change the variable, so copy it right now
1273 output.println(" if( src != NULL ) {");
1274 output.println(" pthread_mutex_lock( &(src->lock) );");
1278 output.println(" if( isEmpty( &src->forwardList ) ||");
1279 output.println(" seseToIssue != peekItem( &src->forwardList ) ) {");
1280 output.println(" if( !src->doneExecuting ) {");
1281 output.println(" addNewItem( &src->forwardList, seseToIssue );");
1282 output.println(" ++(localCount);");
1283 output.println(" }");
1284 output.println(" }");
1285 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1286 output.println(" ADD_REFERENCE_TO( src );");
1287 output.println("#endif");
1288 output.println(" pthread_mutex_unlock( &(src->lock) );");
1289 output.println(" seseToIssue->"+dynInVar+"_srcOffset = "+dynInVar+"_srcOffset;");
1290 output.println(" } else {");
1293 // determine whether this new task instance is in a method context,
1294 // or within the body of another task
1295 assert !fsen.getIsCallerProxySESE();
1296 FlatSESEEnterNode parent = fsen.getLocalParent();
1297 if( parent != null && !parent.getIsCallerProxySESE() ) {
1298 output.println(" seseToIssue->"+dynInVar+" = "+
1299 generateTemp(parent.getfmBogus(), dynInVar)+";");
1301 output.println(" seseToIssue->"+dynInVar+" = "+
1302 generateTemp(fsen.getfmEnclosing(), dynInVar)+";");
1305 output.println(" }");
1306 output.println(" }");
1308 // even if the value is already copied, make sure your NULL source
1309 // gets passed so child knows it already has the dynamic value
1310 output.println(" seseToIssue->"+dynInVar+"_srcSESE = "+dynInVar+"_srcSESE;");
1314 // maintain pointers for finding dynamic SESE
1315 // instances from static names, do a shuffle as instances age
1316 // and also release references that have become too old
1317 if( !fsen.getIsMainSESE() ) {
1319 FlatSESEEnterNode currentSESE = fsen.getLocalParent();
1321 ContextTaskNames contextTaskNames;
1322 if( currentSESE == null ) {
1323 contextTaskNames = oooa.getContextTaskNames(oooa.getContainingFlatMethod(fsen) );
1325 contextTaskNames = oooa.getContextTaskNames(currentSESE);
1328 SESEandAgePair pairNewest = new SESEandAgePair(fsen, 0);
1329 SESEandAgePair pairOldest = new SESEandAgePair(fsen, fsen.getOldestAgeToTrack() );
1330 if( contextTaskNames.getNeededStaticNames().contains(pairNewest) ) {
1331 output.println(" {");
1332 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1333 output.println(" SESEcommon* oldest = "+pairOldest+";");
1334 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1336 for( int i = fsen.getOldestAgeToTrack(); i > 0; --i ) {
1337 SESEandAgePair pair1 = new SESEandAgePair(fsen, i);
1338 SESEandAgePair pair2 = new SESEandAgePair(fsen, i-1);
1339 output.println(" "+pair1+" = "+pair2+";");
1341 output.println(" "+pairNewest+" = &(seseToIssue->common);");
1343 // no need to add a reference to whatever is the newest record, because
1344 // we initialized seseToIssue->refCount to *2*
1345 // but release a reference to whatever was the oldest BEFORE the shift
1346 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1347 output.println(" if( oldest != NULL ) {");
1348 output.println(" RELEASE_REFERENCE_TO( oldest );");
1349 output.println(" }");
1350 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1351 output.println(" }");
1357 //////////////////////
1358 // count up memory conflict dependencies,
1359 ///////////////////////
1360 if( !fsen.getIsMainSESE() ) {
1362 if( state.COREPROF ) {
1363 output.println("#ifdef CP_EVENTID_PREPAREMEMQ");
1364 output.println(" CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_BEGIN );");
1365 output.println("#endif");
1369 dispatchMEMRC(fm, fsen, output);
1372 // there may be several task types that can get to this
1373 // program point (issue this new task) so create a switch
1374 // based on task ID, each type of task has a different index
1375 // scheme for its memory queue's, and the cases here drop the
1376 // new task instance in the right bucket
1377 boolean atLeastOneCase = false;
1379 // create a case for each class of task that might be executing
1380 Iterator<FlatSESEEnterNode> taskItr = oooa.getPossibleExecutingRBlocks(fsen).iterator();
1381 while( taskItr.hasNext() ) {
1382 FlatSESEEnterNode parent = taskItr.next();
1383 ConflictGraph graph = oooa.getConflictGraph(parent);
1385 if( graph == null || !graph.hasConflictEdge() ) {
1389 Set<SESELock> seseLockSet = oooa.getLockMappings(graph);
1391 SESEWaitingQueue seseWaitingQueue =
1392 graph.getWaitingElementSetBySESEID(fsen.getIdentifier(), seseLockSet);
1394 if( seseWaitingQueue.getWaitingElementSize() == 0 ) {
1398 if( atLeastOneCase == false ) {
1399 atLeastOneCase = true;
1400 output.println(" // add new task instance to current task's memory queues if needed ");
1401 output.println(" switch( runningSESE->classID ) {");
1404 output.println(" case "+parent.getIdentifier()+": {");
1405 output.println(" REntry* rentry=NULL;");
1406 output.println(" INTPTR* pointer=NULL;");
1407 output.println(" seseToIssue->common.rentryIdx=0;");
1409 Set<Integer> queueIDSet=seseWaitingQueue.getQueueIDSet();
1410 for (Iterator iterator = queueIDSet.iterator(); iterator.hasNext(); ) {
1411 Integer key = (Integer) iterator.next();
1412 int queueID=key.intValue();
1413 Set<WaitingElement> waitingQueueSet =
1414 seseWaitingQueue.getWaitingElementSet(queueID);
1415 int enqueueType=seseWaitingQueue.getType(queueID);
1416 if(enqueueType==SESEWaitingQueue.EXCEPTION) {
1417 output.println(" INITIALIZEBUF(runningSESE->memoryQueueArray[" + queueID+ "]);");
1419 for (Iterator iterator2 = waitingQueueSet.iterator(); iterator2.hasNext(); ) {
1420 WaitingElement waitingElement
1421 = (WaitingElement) iterator2.next();
1422 if (waitingElement.getStatus() >= ConflictNode.COARSE) {
1423 output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1424 + waitingElement.getStatus()
1425 + ", &(seseToIssue->common));");
1427 TempDescriptor td = waitingElement.getTempDesc();
1428 // decide whether waiting element is dynamic or static
1429 if (fsen.getDynamicInVarSet().contains(td)) {
1430 // dynamic in-var case
1431 output.println(" pointer=seseToIssue->"
1432 + waitingElement.getDynID()
1433 + "_srcSESE+seseToIssue->"
1434 + waitingElement.getDynID()
1436 output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1437 + waitingElement.getStatus()
1438 + ", &(seseToIssue->common), pointer );");
1439 } else if (fsen.getStaticInVarSet().contains(td)) {
1440 // static in-var case
1441 VariableSourceToken vst = fsen.getStaticInVarSrc(td);
1444 String srcId = "SESE_" + vst.getSESE().getPrettyIdentifier()
1445 + vst.getSESE().getIdentifier()
1446 + "_" + vst.getAge();
1447 output.println(" pointer=(void*)&seseToIssue->"
1453 output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1454 + waitingElement.getStatus()
1455 + ", &(seseToIssue->common), pointer );");
1458 output.println(" rentry=mlpCreateFineREntry(runningSESE->memoryQueueArray["+ queueID+ "],"
1459 + waitingElement.getStatus()
1460 + ", &(seseToIssue->common), (void*)&seseToIssue->"
1461 + waitingElement.getDynID()
1465 output.println(" rentry->queue=runningSESE->memoryQueueArray["
1466 + waitingElement.getQueueID()
1469 if(enqueueType==SESEWaitingQueue.NORMAL) {
1470 output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;");
1471 output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["
1472 + waitingElement.getQueueID()
1473 + "],rentry)==NOTREADY) {");
1474 output.println(" localCount++;");
1475 output.println(" }");
1477 output.println(" ADDRENTRYTOBUF(runningSESE->memoryQueueArray[" + waitingElement.getQueueID() + "],rentry);");
1480 if(enqueueType!=SESEWaitingQueue.NORMAL) {
1481 output.println(" localCount+=RESOLVEBUF(runningSESE->memoryQueueArray["
1482 + queueID+ "],&seseToIssue->common);");
1485 output.println(" } break; // end case "+parent.getIdentifier());
1489 if( atLeastOneCase ) {
1490 output.println(" } // end stall site switch");
1494 if( state.COREPROF ) {
1495 output.println("#ifdef CP_EVENTID_PREPAREMEMQ");
1496 output.println(" CP_LOGEVENT( CP_EVENTID_PREPAREMEMQ, CP_EVENTTYPE_END );");
1497 output.println("#endif");
1501 // Enqueue Task Record
1503 if( fsen != oooa.getMainSESE() && fsen.getInVarsForDynamicCoarseConflictResolution().size()>0) {
1504 output.println(" enqueueTR(TRqueue, (void *)seseToIssue);");
1508 // if there were no outstanding dependencies, issue here
1509 output.println(" if( atomic_sub_and_test(10000-localCount,&(seseToIssue->common.unresolvedDependencies) ) ) {");
1510 output.println(" workScheduleSubmit( (void*)seseToIssue );");
1511 output.println(" }");
1515 if( state.COREPROF ) {
1516 output.println("#ifdef CP_EVENTID_TASKDISPATCH");
1517 output.println(" CP_LOGEVENT( CP_EVENTID_TASKDISPATCH, CP_EVENTTYPE_END );");
1518 output.println("#endif");
1521 output.println(" } // end task issue");
1525 void dispatchMEMRC(FlatMethod fm,
1526 FlatSESEEnterNode newChild,
1527 PrintWriter output) {
1528 // what we need to do here is create RCR records for the
1529 // new task and insert it into the appropriate parent queues
1530 // IF NEEDED!!!!!!!!
1531 assert newChild.getParents().size() > 0;
1533 output.println(" switch( runningSESE->classID ) {");
1535 Iterator<FlatSESEEnterNode> pItr = newChild.getParents().iterator();
1536 while( pItr.hasNext() ) {
1538 FlatSESEEnterNode parent = pItr.next();
1539 ConflictGraph graph = oooa.getConflictGraph(parent);
1541 if( graph != null && graph.hasConflictEdge() ) {
1542 Set<SESELock> seseLockSet = oooa.getLockMappings(graph);
1543 SESEWaitingQueue seseWaitingQueue=graph.getWaitingElementSetBySESEID(newChild.getIdentifier(), seseLockSet);
1544 if(seseWaitingQueue.getWaitingElementSize()>0) {
1546 output.println(" /* "+parent.getPrettyIdentifier()+" */");
1547 output.println(" case "+parent.getIdentifier()+": {");
1549 output.println(" REntry* rentry=NULL;");
1550 output.println(" INTPTR* pointer=NULL;");
1551 output.println(" seseToIssue->common.rentryIdx=0;");
1552 Vector<TempDescriptor> invars=newChild.getInVarsForDynamicCoarseConflictResolution();
1553 //System.out.println(fm.getMethod()+"["+invars+"]");
1555 Vector<Long> queuetovar=new Vector<Long>();
1557 for(int i=0; i<invars.size(); i++) {
1558 TempDescriptor td=invars.get(i);
1559 Set<WaitingElement> weset=seseWaitingQueue.getWaitingElementSet(td);
1561 //TODO FIX MEEEEE!!!!
1562 //Weset is sometimes null which breaks the following code and
1563 //we don't know what weset = null means. For now, we bail when it's null
1564 //until we find out what to do....
1565 // if(weset == null) {
1568 //UPDATE: This hack DOES NOT FIX IT!.
1573 Set<Integer> queueSet=new HashSet<Integer>();
1574 for (Iterator iterator = weset.iterator(); iterator.hasNext(); ) {
1575 WaitingElement we = (WaitingElement) iterator.next();
1576 Integer queueID=new Integer(we.getQueueID());
1577 if(!queueSet.contains(queueID)) {
1579 queueSet.add(queueID);
1583 output.println(" seseToIssue->rcrRecords["+i+"].flag="+numqueues+";");
1584 output.println(" seseToIssue->rcrRecords["+i+"].index=0;");
1585 output.println(" seseToIssue->rcrRecords["+i+"].next=NULL;");
1586 output.println(" int dispCount"+i+"=0;");
1588 for (Iterator<WaitingElement> wtit = weset.iterator(); wtit.hasNext(); ) {
1589 WaitingElement waitingElement = wtit.next();
1590 int queueID = waitingElement.getQueueID();
1591 if (queueID >= queuetovar.size())
1592 queuetovar.setSize(queueID + 1);
1593 Long l = queuetovar.get(queueID);
1594 long val = (l != null)?l.longValue():0;
1595 val = val | (1 << i);
1596 queuetovar.set(queueID, new Long(val));
1600 HashSet generatedqueueentry=new HashSet();
1601 for(int i=0; i<invars.size(); i++) {
1602 TempDescriptor td=invars.get(i);
1603 Set<WaitingElement> weset=seseWaitingQueue.getWaitingElementSet(td);
1607 //TODO FIX MEEEEE!!!!
1608 //Weset is sometimes null which breaks the following code and
1609 //we don't know what weset = null means. For now, we bail when it's null
1610 //until we find out what to do....
1611 // if(weset == null) {
1614 //UPDATE: This hack DOES NOT FIX IT!.
1618 for(Iterator<WaitingElement> wtit=weset.iterator(); wtit.hasNext(); ) {
1619 WaitingElement waitingElement=wtit.next();
1620 int queueID=waitingElement.getQueueID();
1622 if(waitingElement.isBogus()) {
1626 if (generatedqueueentry.contains(queueID))
1629 generatedqueueentry.add(queueID);
1631 assert(waitingElement.getStatus()>=ConflictNode.COARSE);
1632 long mask=queuetovar.get(queueID);
1633 output.println(" rentry=mlpCreateREntry(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "]," + waitingElement.getStatus() + ", &(seseToIssue->common), "+mask+"LL);");
1634 output.println(" rentry->count=2;");
1635 output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;");
1636 output.println(" rentry->queue=runningSESE->memoryQueueArray[" + waitingElement.getQueueID()+"];");
1638 output.println(" if(ADDRENTRY(runningSESE->memoryQueueArray["+ waitingElement.getQueueID()+ "],rentry)==READY) {");
1639 for(int j=0; mask!=0; j++) {
1641 output.println(" dispCount"+j+"++;");
1644 output.println(" } else ");
1645 output.println(" refCount--;");
1648 if (newChild.getDynamicInVarSet().contains(td)) {
1649 // dynamic in-var case
1650 //output.println(" pointer=seseToIssue->"+waitingElement.getDynID()+
1651 // "_srcSESE+seseToIssue->"+waitingElement.getDynID()+
1653 //output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+
1654 // ", &(seseToIssue->common), pointer );");
1657 for(int i=0; i<invars.size(); i++) {
1658 output.println(" if(!dispCount"+i+" || !atomic_sub_and_test(dispCount"+i+",&(seseToIssue->rcrRecords["+i+"].flag)))");
1659 output.println(" localCount++;");
1661 output.println(" } break;");
1666 output.println(" } // end switch");
1668 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1669 output.println(" RELEASE_REFERENCES_TO((SESEcommon *)seseToIssue, refCount);");
1670 output.println("#endif");
1674 public void generateFlatSESEExitNode(FlatMethod fm,
1675 FlatSESEExitNode fsexn,
1676 PrintWriter output) {
1678 // get the enter node for this exit that has meta data embedded
1679 FlatSESEEnterNode fsen = fsexn.getFlatEnter();
1681 // there may be an SESE in an unreachable method, skip over
1682 if( !oooa.getAllSESEs().contains(fsen) ) {
1686 // assert we are never generating code for the caller proxy
1687 // it should only appear in analysis results
1688 assert !fsen.getIsCallerProxySESE();
1691 if( state.COREPROF ) {
1692 output.println("#ifdef CP_EVENTID_TASKEXECUTE");
1693 output.println(" CP_LOGEVENT( CP_EVENTID_TASKEXECUTE, CP_EVENTTYPE_END );");
1694 output.println("#endif");
1697 output.println(" /* SESE exiting */");
1699 if( state.COREPROF ) {
1700 output.println("#ifdef CP_EVENTID_TASKRETIRE");
1701 output.println(" CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_BEGIN );");
1702 output.println("#endif");
1706 // this SESE cannot be done until all of its children are done
1707 // so grab your own lock with the condition variable for watching
1708 // that the number of your running children is greater than zero
1709 output.println(" atomic_add(childSESE, &runningSESE->numRunningChildren);");
1710 output.println(" pthread_mutex_lock( &(runningSESE->lock) );");
1711 output.println(" if( runningSESE->numRunningChildren > 0 ) {");
1712 output.println(" stopforgc( (struct garbagelist *)&___locals___ );");
1713 output.println(" do {");
1714 output.println(" pthread_cond_wait( &(runningSESE->runningChildrenCond), &(runningSESE->lock) );");
1715 output.println(" } while( runningSESE->numRunningChildren > 0 );");
1716 output.println(" restartaftergc();");
1717 output.println(" }");
1721 ////////////////////////////////////////
1722 // go through all out-vars and determine where to get them
1723 ////////////////////////////////////////
1724 output.println(" // copy ready out-set primitive variables from locals into record");
1725 Iterator<TempDescriptor> itr = fsen.getReadyOutVarSet().iterator();
1726 while( itr.hasNext() ) {
1727 TempDescriptor temp = itr.next();
1729 // only have to do this for primitives, non-arrays
1731 temp.getType().isPrimitive() && !temp.getType().isArray()
1737 String from = generateTemp(fsen.getfmBogus(), temp);
1739 output.println(" "+paramsprefix+
1740 "->"+temp.getSafeSymbol()+
1744 // static vars are from a known SESE
1745 Iterator<TempDescriptor> tempItr;
1746 output.println(" // copy out-set from static sources");
1747 tempItr = fsen.getStaticOutVarSet().iterator();
1748 while( tempItr.hasNext() ) {
1749 TempDescriptor temp = tempItr.next();
1750 VariableSourceToken vst = fsen.getStaticOutVarSrc(temp);
1751 SESEandAgePair srcPair = new SESEandAgePair(vst.getSESE(), vst.getAge() );
1752 output.println(" "+paramsprefix+
1753 "->"+temp.getSafeSymbol()+
1754 " = "+paramsprefix+"->"+srcPair+"->"+vst.getAddrVar()+";");
1757 //output.println(" // decrement references to static sources");
1758 //for( Iterator<SESEandAgePair> pairItr = fsen.getStaticOutVarSrcs().iterator(); pairItr.hasNext(); ) {
1759 // SESEandAgePair srcPair = pairItr.next();
1760 // output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1761 // output.println(" {");
1762 // output.println(" SESEcommon* src = &("+paramsprefix+"->"+srcPair+"->common);");
1763 // output.println(" RELEASE_REFERENCE_TO( src );");
1764 // output.println(" }");
1765 // output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1768 output.println(" // copy out-set from dynamic sources");
1769 tempItr = fsen.getDynamicOutVarSet().iterator();
1770 while( tempItr.hasNext() ) {
1771 TempDescriptor temp = tempItr.next();
1772 TypeDescriptor type = temp.getType();
1774 // go grab it from the SESE source, when the source is NULL it is
1775 // this exiting task, so nothing to do!
1776 output.println(" if( "+temp+"_srcSESE != NULL ) {");
1778 output.println(" "+paramsprefix+
1779 "->"+temp.getSafeSymbol()+
1780 " = *(void**)( (void*)"+
1782 temp+"_srcOffset);");
1784 //output.println("#ifndef OOO_DISABLE_TASKMEMPOOL" );
1785 //output.println(" SESEcommon* src = "+paramsprefix+"->"+temp+"_srcSESE;");
1786 //output.println(" RELEASE_REFERENCE_TO( src );");
1787 //output.println("#endif // OOO_DISABLE_TASKMEMPOOL" );
1789 output.println(" }");
1795 // mark yourself done, your task data is now read-only
1796 output.println(" runningSESE->doneExecuting = TRUE;");
1798 // if parent is stalling on you, let them know you're done
1799 if( !fsen.getIsMainSESE() ) {
1800 output.println(" if( runningSESE->parentsStallSem != NULL ) {");
1801 output.println(" psem_give( runningSESE->parentsStallSem );");
1802 output.println(" }");
1805 output.println(" pthread_mutex_unlock( &(runningSESE->lock) );");
1807 // decrement dependency count for all SESE's on your forwarding list
1810 output.println(" while( !isEmpty( &runningSESE->forwardList ) ) {");
1811 output.println(" SESEcommon* consumer = (SESEcommon*) getItem( &runningSESE->forwardList );");
1815 output.println(" if(consumer->rentryIdx>0){");
1816 output.println(" // resolved null pointer");
1817 output.println(" int idx;");
1818 output.println(" for(idx=0;idx<consumer->rentryIdx;idx++){");
1819 output.println(" resolvePointer(consumer->rentryArray[idx]);");
1820 output.println(" }");
1821 output.println(" }");
1824 output.println(" if( atomic_sub_and_test( 1, &(consumer->unresolvedDependencies) ) ){");
1825 output.println(" workScheduleSubmit( (void*)consumer );");
1826 output.println(" }");
1827 output.println(" }");
1830 // clean up its lock element from waiting queue, and decrement dependency count for next SESE block
1831 if( !fsen.getIsMainSESE() ) {
1833 output.println(" /* check memory dependency*/");
1834 output.println(" {");
1835 output.println(" int idx;");
1836 output.println(" for(idx=0;idx<___params___->common.rentryIdx;idx++){");
1837 output.println(" REntry* re=___params___->common.rentryArray[idx];");
1838 output.println(" RETIRERENTRY(re->queue,re);");
1839 output.println(" }");
1840 output.println(" }");
1843 Vector<TempDescriptor> inset=fsen.getInVarsForDynamicCoarseConflictResolution();
1844 if (state.RCR && inset.size() > 0) {
1845 /* Make sure the running SESE is finished */
1846 output.println(" if (unlikely(runningSESE->rcrstatus!=0)) {");
1847 output.println(" if(CAS(&runningSESE->rcrstatus,1,0)==2) {");
1848 output.println(" while(runningSESE->rcrstatus) {");
1849 output.println(" BARRIER();");
1850 output.println(" sched_yield();");
1851 output.println(" }");
1852 output.println(" }");
1853 output.println(" }");
1854 output.println("{");
1855 output.println(" int idx,idx2;");
1857 output.println(" struct rcrRecord *rec;");
1858 output.println(" struct Hashtable_rcr ** hashstruct=runningSESE->parent->allHashStructures;");
1860 for (int i = 0; i < inset.size(); i++) {
1861 output.println(" rec=&" + paramsprefix + "->rcrRecords[" + i + "];");
1862 output.println(" while(rec!=NULL) {");
1863 output.println(" for(idx2=0;idx2<rec->index;idx2++) {");
1865 int weaklyConnectedComponentIndex = rcr.getWeakID(inset.get(i), fsen);
1867 output.println(" rcr_RETIREHASHTABLE(hashstruct[" + weaklyConnectedComponentIndex
1868 + "],&(___params___->common), rec->array[idx2], (BinItem_rcr *) rec->ptrarray[idx2]);");
1870 output.println(" }"); // exit idx2 for loop
1871 output.println(" rec=rec->next;");
1872 output.println(" }"); // exit rec while loop
1874 output.println("}");
1878 // a task has variables to track static/dynamic instances
1879 // that serve as sources, release the parent's ref of each
1880 // non-null var of these types
1881 output.println(" // releasing static SESEs");
1882 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1884 ContextTaskNames contextTaskNames = oooa.getContextTaskNames(fsen);
1886 Iterator<SESEandAgePair> pItr = contextTaskNames.getNeededStaticNames().iterator();
1887 while( pItr.hasNext() ) {
1888 SESEandAgePair pair = pItr.next();
1889 output.println(" if( "+pair+" != NULL ) {");
1890 output.println(" RELEASE_REFERENCE_TO( "+pair+" );");
1891 output.println(" }");
1893 output.println(" // releasing dynamic variable sources");
1894 Iterator<TempDescriptor> dynSrcItr = contextTaskNames.getDynamicVarSet().iterator();
1895 while( dynSrcItr.hasNext() ) {
1896 TempDescriptor dynSrcVar = dynSrcItr.next();
1897 output.println(" if( "+dynSrcVar+"_srcSESE != NULL ) {");
1898 output.println(" RELEASE_REFERENCE_TO( "+dynSrcVar+"_srcSESE );");
1899 output.println(" }");
1902 // destroy this task's mempool if it is not a leaf task
1903 if( !fsen.getIsLeafSESE() ) {
1904 output.println(" pooldestroy( runningSESE->taskRecordMemPool );");
1905 if (state.RCR && fsen.getInVarsForDynamicCoarseConflictResolution().size() > 0 ) {
1906 output.println(" returnTR();");
1909 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1912 output.println("{");
1913 output.println("SESEcommon *myparent=runningSESE->parent;");
1915 // if this is not the Main sese (which has no parent) then return
1916 // THIS task's record to the PARENT'S task record pool, and only if
1917 // the reference count is now zero
1918 if( !fsen.getIsMainSESE() ) {
1919 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1920 output.println(" RELEASE_REFERENCE_TO( runningSESE );");
1921 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1923 // the main task has no parent, just free its record
1924 output.println(" mlpFreeSESErecord( runningSESE );");
1928 // last of all, decrement your parent's number of running children
1929 output.println(" if( myparent != NULL ) {");
1930 output.println(" if( atomic_sub_and_test( 1, &(myparent->numRunningChildren) ) ) {");
1931 output.println(" pthread_mutex_lock ( &(myparent->lock) );");
1932 output.println(" pthread_cond_signal ( &(myparent->runningChildrenCond) );");
1933 output.println(" pthread_mutex_unlock( &(myparent->lock) );");
1934 output.println(" }");
1935 output.println(" }");
1937 output.println("}");
1939 // as this thread is wrapping up the task, make sure the thread-local var
1940 // for the currently running task record references an invalid task
1941 output.println(" runningSESE = (SESEcommon*) 0x1;");
1943 if( state.COREPROF ) {
1944 output.println("#ifdef CP_EVENTID_TASKRETIRE");
1945 output.println(" CP_LOGEVENT( CP_EVENTID_TASKRETIRE, CP_EVENTTYPE_END );");
1946 output.println("#endif");
1951 public void generateFlatWriteDynamicVarNode(FlatMethod fm,
1952 FlatWriteDynamicVarNode fwdvn,
1956 Hashtable<TempDescriptor, VSTWrapper> writeDynamic = fwdvn.getVar2src();
1958 assert writeDynamic != null;
1960 Iterator wdItr = writeDynamic.entrySet().iterator();
1961 while( wdItr.hasNext() ) {
1962 Map.Entry me = (Map.Entry)wdItr.next();
1963 TempDescriptor refVar = (TempDescriptor) me.getKey();
1964 VSTWrapper vstW = (VSTWrapper) me.getValue();
1965 VariableSourceToken vst = vstW.vst;
1967 output.println(" {");
1968 output.println(" SESEcommon* oldSrc = "+refVar+"_srcSESE;");
1971 // if there is no given source, this variable is ready so
1972 // mark src pointer NULL to signify that the var is up-to-date
1973 output.println(" "+refVar+"_srcSESE = NULL;");
1975 // otherwise we track where it will come from
1976 SESEandAgePair instance = new SESEandAgePair(vst.getSESE(), vst.getAge() );
1977 output.println(" "+refVar+"_srcSESE = "+instance+";");
1978 output.println(" "+refVar+"_srcOffset = (INTPTR) &((("+
1979 vst.getSESE().getSESErecordName()+"*)0)->"+vst.getAddrVar()+");");
1982 // no matter what we did above, track reference count of whatever
1983 // this variable pointed to, do release last in case we're just
1984 // copying the same value in because 1->2->1 is safe but ref count
1985 // 1->0->1 has a window where it looks like it should be free'd
1986 output.println("#ifndef OOO_DISABLE_TASKMEMPOOL");
1987 output.println(" if( "+refVar+"_srcSESE != NULL ) {");
1988 output.println(" ADD_REFERENCE_TO( "+refVar+"_srcSESE );");
1989 output.println(" }");
1990 output.println(" if( oldSrc != NULL ) {");
1991 output.println(" RELEASE_REFERENCE_TO( oldSrc );");
1992 output.println(" }");
1993 output.println("#endif // OOO_DISABLE_TASKMEMPOOL");
1995 output.println(" }");
2000 protected void generateFlatNew(FlatMethod fm,
2002 PrintWriter output) {
2004 if( fn.getType().isArray() ) {
2005 int arrayid = state.getArrayNumber(fn.getType() )+state.numClasses();
2007 if( GENERATEPRECISEGC ) {
2008 output.println(generateTemp(fm, fn.getDst())+
2009 "=allocate_newarray_mlp("+localsprefixaddr+
2010 ", "+arrayid+", "+generateTemp(fm, fn.getSize())+
2012 oooa.getHeapAnalysis().getAllocationSiteFromFlatNew(fn).getUniqueAllocSiteID()+
2014 output.println(" oid += oidIncrement;");
2016 output.println(generateTemp(fm, fn.getDst())+
2017 "=allocate_newarray("+arrayid+
2018 ", "+generateTemp(fm, fn.getSize())+
2024 if( GENERATEPRECISEGC ) {
2025 output.println(generateTemp(fm, fn.getDst())+
2026 "=allocate_new_mlp("+localsprefixaddr+
2027 ", "+fn.getType().getClassDesc().getId()+
2029 oooa.getHeapAnalysis().getAllocationSiteFromFlatNew(fn).getUniqueAllocSiteID()+
2031 output.println(" oid += oidIncrement;");
2033 output.println(generateTemp(fm, fn.getDst())+
2034 "=allocate_new("+fn.getType().getClassDesc().getId()+
2041 private int calculateSizeOfSESEParamList(FlatSESEEnterNode fsen) {
2043 Set<TempDescriptor> tdSet=new HashSet<TempDescriptor>();
2045 for (Iterator iterator = fsen.getInVarSet().iterator(); iterator.hasNext(); ) {
2046 TempDescriptor tempDescriptor = (TempDescriptor) iterator.next();
2047 if(!tempDescriptor.getType().isPrimitive() || tempDescriptor.getType().isArray()) {
2048 tdSet.add(tempDescriptor);
2052 for (Iterator iterator = fsen.getOutVarSet().iterator(); iterator.hasNext(); ) {
2053 TempDescriptor tempDescriptor = (TempDescriptor) iterator.next();
2054 if(!tempDescriptor.getType().isPrimitive() || tempDescriptor.getType().isArray()) {
2055 tdSet.add(tempDescriptor);
2059 return tdSet.size();
2063 private String calculateSizeOfSESEParamSize(FlatSESEEnterNode fsen) {
2064 HashMap <String,Integer> map=new HashMap();
2065 HashSet <TempDescriptor> processed=new HashSet<TempDescriptor>();
2068 // space for all in and out set primitives
2069 Set<TempDescriptor> inSetAndOutSet = new HashSet<TempDescriptor>();
2070 inSetAndOutSet.addAll(fsen.getInVarSet() );
2071 inSetAndOutSet.addAll(fsen.getOutVarSet() );
2073 Set<TempDescriptor> inSetAndOutSetPrims = new HashSet<TempDescriptor>();
2075 Iterator<TempDescriptor> itr = inSetAndOutSet.iterator();
2076 while( itr.hasNext() ) {
2077 TempDescriptor temp = itr.next();
2078 TypeDescriptor type = temp.getType();
2079 if( !type.isPtr() ) {
2080 inSetAndOutSetPrims.add(temp);
2084 Iterator<TempDescriptor> itrPrims = inSetAndOutSetPrims.iterator();
2085 while( itrPrims.hasNext() ) {
2086 TempDescriptor temp = itrPrims.next();
2087 TypeDescriptor type = temp.getType();
2088 if(type.isPrimitive()) {
2089 Integer count=map.get(type.getSymbol());
2091 count=new Integer(1);
2092 map.put(type.getSymbol(), count);
2094 map.put(type.getSymbol(), new Integer(count.intValue()+1));
2099 Set<String> keySet=map.keySet();
2100 for (Iterator iterator = keySet.iterator(); iterator.hasNext(); ) {
2101 String key = (String) iterator.next();
2102 rtr+="+sizeof("+key+")*"+map.get(key);