if(state.RCR) {
//no need to enqueue parent effect if coarse grained conflict clears us
output.println(" while(stallrecord.common.rcrstatus) ;");
- output.println(" BARRIER();");
+ output.println(" BARRIER();");
output.println(" stallrecord.common.parentsStallSem=&rentry->parentStallSem;");
output.println(" stallrecord.tag=rentry->tag;");
output.println(" stallrecord.___obj___=(struct ___Object___ *)"+generateTemp(fm, waitingElement.getTempDesc(), null)+";");
output.println(" struct garbagelist * gl= (struct garbagelist *)&(((SESEcommon*)(seseToIssue))[1]);");
output.println(" gl->size="+calculateSizeOfSESEParamList(fsen)+";");
output.println(" gl->next = NULL;");
+
+ if(state.RCR) {
+ //flag the SESE status as 1...it will be reset
+ output.println(" seseToIssue->rcrstatus=1;");
+ }
// there are pointers to SESE records the newly-issued SESE
// will use to get values it depends on them for--how many
// eom
// clean up its lock element from waiting queue, and decrement dependency count for next SESE block
- if( (state.MLP && fsen != mlpa.getMainSESE()) ||
- (state.OOOJAVA && fsen != oooa.getMainSESE())
- ) {
-
- output.println();
- output.println(" /* check memory dependency*/");
- output.println(" {");
- output.println(" int idx;");
- output.println(" for(idx=0;idx<___params___->common.rentryIdx;idx++){");
- output.println(" REntry* re=___params___->common.rentryArray[idx];");
- output.println(" RETIRERENTRY(re->queue,re);");
- output.println(" }");
- output.println(" }");
-
+ if((state.MLP && fsen != mlpa.getMainSESE()) ||
+ (state.OOOJAVA && fsen != oooa.getMainSESE())) {
+ output.println();
+ output.println(" /* check memory dependency*/");
+ output.println(" {");
+ output.println(" int idx;");
+ output.println(" for(idx=0;idx<___params___->common.rentryIdx;idx++){");
+ output.println(" REntry* re=___params___->common.rentryArray[idx];");
+ output.println(" RETIRERENTRY(re->queue,re);");
+ output.println(" }");
+ output.println(" }");
}
if (state.RCR&&fsen.getDynamicInVarSet().size()>0) {
+ /* Make sure the running SESE is finished */
+ output.println(" if (unlikely(runningSESE->rcrstatus!=0)) {");
+ output.println(" if(!CAS(&runningSESE->rcrstatus,1,0)) {");
+ output.println(" while(runningSESE->rcrstatus) {");
+ output.println(" BARRIER();");
+ output.println(" sched_yield();");
+ output.println(" }");
+ output.println(" }");
+ output.println(" }");
output.println("{");
output.println(" int idx,idx2;");
if (fsen.getDynamicInVarSet().size()==1) {
output.println(" struct rcrRecord *rec="+paramsprefix+"->rcrRecords[idx];");
output.println(" while(rec!=NULL) {");
output.println(" for(idx2=0;idx2<rec->index;idx2++) {");
- output.println(" rcr_RETIREHASHTABLE(allHashStructures[0],rec,rec->array[idx2]);");
+ output.println(" rcr_RETIREHASHTABLE(allHashStructures[0],rec,rec->array[idx2], rcr->ptrarray[idx2]);");
output.println(" }");//exit idx2 for loop
output.println(" rec=rec->next;");
output.println(" }");//exit rec while loop
private void printMasterTraverserInvocation() {
headerFile.println("\nint tasktraverse(SESEcommon * record);");
cFile.println("\nint tasktraverse(SESEcommon * record) {");
+ cFile.println(" if(!CAS(&record->rcrstatus,1,2)) return;");
cFile.println(" switch(record->classID) {");
for(Iterator<FlatSESEEnterNode> seseit=oooa.getAllSESEs().iterator();seseit.hasNext();) {
//Casts the ptr to a generic object struct so we can get to the ptr->allocsite field.
cFile.println("struct ___Object___ * ptr = (struct ___Object___ *) InVar;\nif (InVar != NULL) {\n " + queryVistedHashtable + "(ptr);\n do {");
-
+ if (taint.isRBlockTaint()) {
+ cFile.println(" if(unlikely(record->doneExecuting)) {");
+ cFile.println(" record->rcrstatus=0;");
+ cFile.println(" return;");
+ cFile.println(" }");
+ }
cFile.println(" switch(ptr->allocsite) {");
for(AllocSite singleCase: cases.keySet())
//we have resolved a heap root...see if this was the last dependence
cFile.println(" if(atomic_sub_and_test(1, &(record->common.unresolvedDependencies))) workScheduleSubmit((void *)record);");
cFile.println(" }");
- cFile.println("}");
+ cFile.println(" }");
+ cFile.println(" record->common.rcrstatus=0;");
}
}
cFile.println("}");
index=fsese.getInVarsForDynamicCoarseConflictResolution().indexOf(tmp);
}
+ String strrcr=taint.isRBlockTaint()?"&record->rcrRecords["+index+"], ":"NULL, ";
+
//Do call if we need it.
if(primConfWrite||objConfWrite) {
int heaprootNum = connectedHRHash.get(taint).id;
int traverserID = doneTaints.get(taint);
currCase.append(" int tmpkey"+depth+"=rcr_generateKey("+prefix+");\n");
if (objConfRead)
- currCase.append(" int tmpvar"+depth+"=rcr_WTWRITEBINCASE(allHashStructures["+heaprootNum+"], tmpkey"+depth+", (SESEcommon *) record, "+index+");\n");
+ currCase.append(" int tmpvar"+depth+"=rcr_WTWRITEBINCASE(allHashStructures["+heaprootNum+"], tmpkey"+depth+", (SESEcommon *) record, "+strrcr+index+");\n");
else
- currCase.append(" int tmpvar"+depth+"=rcr_WRITEBINCASE(allHashStructures["+heaprootNum+"], tmpkey"+depth+", (SESEcommon *) record, "+index+");\n");
+ currCase.append(" int tmpvar"+depth+"=rcr_WRITEBINCASE(allHashStructures["+heaprootNum+"], tmpkey"+depth+", (SESEcommon *) record, "+strrcr+index+");\n");
} else if (primConfRead||objConfRead) {
int heaprootNum = connectedHRHash.get(taint).id;
assert heaprootNum != -1;
int traverserID = doneTaints.get(taint);
currCase.append(" int tmpkey"+depth+"=rcr_generateKey("+prefix+");\n");
if (objConfRead)
- currCase.append(" int tmpvar"+depth+"=rcr_WTREADBINCASE(allHashStructures["+heaprootNum+"], tmpkey"+depth+", (SESEcommon *) record, "+index+");\n");
+ currCase.append(" int tmpvar"+depth+"=rcr_WTREADBINCASE(allHashStructures["+heaprootNum+"], tmpkey"+depth+", (SESEcommon *) record, "+strrcr+index+");\n");
else
- currCase.append(" int tmpvar"+depth+"=rcr_READBINCASE(allHashStructures["+heaprootNum+"], tmpkey"+depth+", (SESEcommon *) record, "+index+");\n");
+ currCase.append(" int tmpvar"+depth+"=rcr_READBINCASE(allHashStructures["+heaprootNum+"], tmpkey"+depth+", (SESEcommon *) record, "+strrcr+index+");\n");
}
if(primConfWrite||objConfWrite||primConfRead||objConfRead) {
currCase.append("if (!(tmpvar"+depth+"&READYMASK)) totalcount--;\n");
- currCase.append("if (!(tmpvar"+depth+"&SPEC)) {\n");
- if (taint.isStallSiteTaint()) {
- currCase.append(" struct rcrRecord * rcrrec=&record->rcrRecords["+index+"];\n");
- currCase.append(" struct rcrRecord * tmprec;\n");
- currCase.append(" if(likely(rcrrec->index<RCRSIZE)) {\n");
- currCase.append(" rcrrec->array[rcrrec->index++]=tmpkey"+depth+";\n");
- currCase.append("} else if(likely((tmprec=rcrrec->next)!=NULL)&&likely(tmprec->index<RCRSIZE)) {\n");
- currCase.append(" tmprec->array[tmprec->index++]=tmpkey"+depth+";\n");
- currCase.append("} else {\n");
- currCase.append(" struct rcrRecord *trec=RUNMALLOC(sizeof(struct rcrRecord));");
- currCase.append(" trec->array[0]=tmpkey"+depth+";\n");
- currCase.append(" trec->index=1;\n");
- currCase.append(" trec->next=tmprec;\n");
- currCase.append(" rcrrec->next=trec;\n");
- currCase.append("}\n");
- }
- currCase.append("}\n");
}
int pdepth=depth+1;
volatile int unresolvedDependencies;
pthread_cond_t doneCond;
- int doneExecuting;
+ volatile int doneExecuting;
pthread_cond_t runningChildrenCond;
int numRunningChildren;
#ifdef RCR
int offsetToParamRecords;
volatile int rcrstatus;
+ volatile int retired;
#endif
// for determining when task records can be returned
//__builtin_popcountll
+inline enqueuerecord(struct rcrRecord *rcrrec, int tmpkey, BinItem_rcr *item) {
+ if (likely(rcrrec!=NULL)) {
+ struct rcrRecord * tmprec;
+ if(likely(rcrrec->index<RCRSIZE)) {
+ int index=rcrrec->index++;
+ rcrrec->ptrarray[index]=item;
+ rcrrec->array[index]=tmpkey;
+ } else if(likely((tmprec=rcrrec->next)!=NULL)&&likely(tmprec->index<RCRSIZE)) {
+ int index=tmprec->index++;
+ tmprec->ptrarray[index]=item;
+ tmprec->array[index]=tmpkey;
+ } else {
+ struct rcrRecord *trec=RUNMALLOC(sizeof(struct rcrRecord));
+ trec->ptrarray[0]=item;
+ trec->array[0]=tmpkey;
+ trec->index=1;
+ trec->next=tmprec;
+ rcrrec->next=trec;
+ }
+ }
+}
+
//NOTE: only temporary
void rcr_createMasterHashTableArray(int maxSize){
}
return (((struct ___Object___ *) ptr)->oid)&RH_MASK;
}
-inline int rcr_BWRITEBINCASE(HashStructure *T, int key, SESEcommon *task, int index, int mode) {
+inline int rcr_BWRITEBINCASE(HashStructure *T, int key, SESEcommon *task, struct rcrRecord *rcrrec, int index, int mode) {
//chain of bins exists => tail is valid
//if there is something in front of us, then we are not ready
BinItem_rcr * val;
//release lock
be->head=b;
+ enqueuerecord(rcrrec, key, b);
return READY;
}
while(bintail->status!=READY) {
BARRIER();
}
- return SPECREADY;
+ return READY;
} else {
- return (bintail->status==READY)?SPECREADY:SPECNOTREADY;
+ return bintail->status;
}
} else {
be->head=val;
- return SPECREADY;
+ return READY;
}
}
} else {
if (val==((BinItem_rcr *)b)) {
b->item.status=READY;
be->head=val;
- if (status&SPEC)
- return SPECREADY;
- else
+ if (status&SPEC) {
+ return READY;
+ } else {
+ enqueuerecord(rcrrec, key, b);
return READY;
+ }
}
val=val->next;
}
while(b->item.status==NOTREADY) {
BARRIER();
}
- return status&SPEC;
+ return status&READY;
} else {
- return status;
+ if (!(status&SPEC))
+ enqueuerecord(rcrrec, key, b);
+ return status&READY;
}
}
-inline int rcr_BREADBINCASE(HashStructure *T, int key, SESEcommon *task, int index, int mode) {
+inline int rcr_BREADBINCASE(HashStructure *T, int key, SESEcommon *task, struct rcrRecord *rcrrec, int index, int mode) {
BinItem_rcr * val;
BinElement_rcr * be = &(T->array[key]);
//release lock
be->head=b;
-
+ enqueuerecord(rcrrec, key, b);
return READY;
}
if (!(td->bitindexrd & bit)) {
td->bitindexrd|=bit;
td->bitindexwr|=bit;
- status=status|SPEC;
} else
- status=SPECREADY;
+ status=READY;
be->head=val;
if (mode) {
while(bintail->status!=READY) {
BARRIER();
}
- return SPECREADY;
+ return READY;
} else {
return status;
}
- }
} else {
TraverserData * td = &((ReadBinItem_rcr *)bintail)->array[((ReadBinItem_rcr *)bintail)->index - 1];
if (unlikely(td->task==task)) {
int status=bintail->status;
if (!(td->bitindex & bit)) {
td->bitindex|=bit;
- status=status|SPEC;
} else
- status=SPECREADY;
+ status=READY;
be->head=val;
if (mode) {
while(bintail->status!=READY) {
BARRIER();
}
- return status&SPEC;
- } else {
- return status;
}
+ return status;
}
}
if (ISREADBIN(bintail->type)) {
- int stat=rcr_TAILREADCASE(T, val, bintail, key, task, index);
+ int stat=rcr_TAILREADCASE(T, val, bintail, key, task, rcrrec, index);
if (mode) {
struct BinItem_rcr * bt=be->tail;
while(bt->status!=READY) {
return stat;
}
} else {
- rcr_TAILWRITECASE(T, val, bintail, key, task, index);
+ rcr_TAILWRITECASE(T, val, bintail, key, task, rcrrec, index);
if (mode) {
struct BinItem_rcr * bt=be->tail;
while(bt->status!=READY) {
}
-int rcr_WRITEBINCASE(HashStructure *T, int key, SESEcommon *task, int index) {
- return rcr_BWRITEBINCASE(T, key, task, index, 0);
+int rcr_WRITEBINCASE(HashStructure *T, int key, SESEcommon *task, struct rcrRecord *rcrrec, int index) {
+ return rcr_BWRITEBINCASE(T, key, task, rcrrec, index, 0);
}
-int rcr_READBINCASE(HashStructure *T, int key, SESEcommon * task, int index) {
- return rcr_BREADBINCASE(T, key, task, index, 0);
+int rcr_READBINCASE(HashStructure *T, int key, SESEcommon * task, struct rcrRecord *rcrrec, int index) {
+ return rcr_BREADBINCASE(T, key, task, rcrrec, index, 0);
}
-int rcr_WTWRITEBINCASE(HashStructure *T, int key, SESEcommon *task, int index) {
- return rcr_BWRITEBINCASE(T, key, task, index, 1);
+int rcr_WTWRITEBINCASE(HashStructure *T, int key, SESEcommon *task, struct rcrRecord *rcrrec, int index) {
+ return rcr_BWRITEBINCASE(T, key, task, rcrrec, index, 1);
}
-int rcr_WTREADBINCASE(HashStructure *T, int key, SESEcommon * task, int index) {
- return rcr_BREADBINCASE(T, key, task, index, 1);
+int rcr_WTREADBINCASE(HashStructure *T, int key, SESEcommon * task, struct rcrRecord *rcrrec, int index) {
+ return rcr_BREADBINCASE(T, key, task, rcrrec, index, 1);
}
-int rcr_TAILREADCASE(HashStructure *T, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, int index) {
+ int rcr_TAILREADCASE(HashStructure *T, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, struct rcrRecord * rcrrec, int index) {
ReadBinItem_rcr * readbintail=(ReadBinItem_rcr*)T->array[key].tail;
int status, retval;
TraverserData *td;
rb->item.status=status;
T->array[key].tail->next=(BinItem_rcr*)rb;
T->array[key].tail=(BinItem_rcr*)rb;
+ enqueuerecord(rcrrec, key, rb);
} else { // group into old tail
td = &readbintail->array[readbintail->index++];
atomic_inc(&readbintail->item.total);
+ enqueuerecord(rcrrec, key, readbintail);
}
td->task=task;
return retval;
}
-void rcr_TAILWRITECASE(HashStructure *T, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, int index) {
+void rcr_TAILWRITECASE(HashStructure *T, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, struct rcrRecord *rcrrec, int index) {
ReadBinItem_rcr* rb=rcr_createReadBinItem();
TraverserData * td = &(rb->array[rb->index++]);
rb->item.total=1;
td->task=task;
td->bitindex=1<<index;
+ enqueuerecord(rcrrec, key, rb);
T->array[key].tail->next=(BinItem_rcr*)rb;
T->array[key].tail=(BinItem_rcr*)rb;
T->array[key].head=val;//released lock
}
-void rcr_RETIREHASHTABLE(HashStructure *T, SESEcommon *task, int key) {
- BinElement_rcr * be = &(T->array[key]);
- BinItem_rcr *b=be->head;
-
- if(ISREADBIN(READBIN)) {
- atomic_dec(&b->total);
+void rcr_RETIREHASHTABLE(HashStructure *T, SESEcommon *task, int key, BinItem_rcr *b) {
+ atomic_dec(&b->total);
+ if(ISREADBIN(b->type)) {
if (b->next==NULL || b->total>0) {
return;
}
}
- //We either have a write bin or we are at the end of a read bin
+ //We either have a write bin or we are at the end of a read bin
+ BinElement_rcr * be = &(T->array[key]);
{
// CHECK FIRST IF next is nonnull to guarantee that b.total cannot change
BinItem_rcr * val=(BinItem_rcr *)0x1;
} else if (ptr==val) {
val=val->next;
}
+ } else if (ptr->total==0) {
+ //skip past retired item
+ if (ptr==val)
+ val=val->next;
} else {
//write bin case
if (haveread)
val=val->next;
} else
break;
- } else { // write bin is already resolved
- val=val->next;
}
}
ptr=ptr->next;
//to store in each entry.
void RESOLVE(SESEcommon *record, bitvt mask);
-int rcr_WRITEBINCASE(HashStructure *T, int key, SESEcommon *task, int index);
-int rcr_READBINCASE(HashStructure *T, int key, SESEcommon * task, int index);
-
-int rcr_WTWRITEBINCASE(HashStructure *T, int key, SESEcommon *task, int index);
-int rcr_WTREADBINCASE(HashStructure *T, int key, SESEcommon * task, int index);
-int rcr_TAILREADCASE(HashStructure *T, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, int index);
-void rcr_TAILWRITECASE(HashStructure *T, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, int index);
-
+int rcr_WRITEBINCASE(HashStructure *T, int key, SESEcommon *task, struct rcrRecord *rcrrec, int index);
+int rcr_READBINCASE(HashStructure *T, int key, SESEcommon * task, struct rcrRecord *rcrrec, int index);
+
+int rcr_WTWRITEBINCASE(HashStructure *T, int key, SESEcommon *task, struct rcrRecord *rcrrec, int index);
+int rcr_WTREADBINCASE(HashStructure *T, int key, SESEcommon * task, struct rcrRecord *rcrrec, int index);
+int rcr_TAILREADCASE(HashStructure *T, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, struct rcrRecord *rcrrec, int index);
+void rcr_TAILWRITECASE(HashStructure *T, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, struct rcrRecord *rcrrec, int index);
+void rcr_RETIREHASHTABLE(HashStructure *T, SESEcommon *task, int key, BinItem_rcr *b);
#endif
int index;
int flag;
int array[RCRSIZE];
+ BinItem_rcr *ptrarray[RCRSIZE];
struct rcrRecord *next;
};