}
if (state.RCR&&fsen.getInVarsForDynamicCoarseConflictResolution().size()>0) {
- output.println(" seseToIssue->common.offsetToParamRecords=(INTPTR)sizeof("+fsen.getSESErecordName()+") - (INTPTR) & ((("+fsen.getSESErecordName()+"*)0)->rcrRecords);");
+ output.println(" seseToIssue->common.offsetToParamRecords=(INTPTR) & ((("+fsen.getSESErecordName()+"*)0)->rcrRecords);");
}
// fill in common data
}
//IMPORTANT: remember to change getTraverserInvocation if you change the line below
String methodName;
+ int index=-1;
+
if (taint.isStallSiteTaint()) {
methodName= "void traverse___" + removeInvalidChars(inVar) +
removeInvalidChars(rBlock) + "___(void * InVar, SESEcommon *record)";
} else {
methodName= "void traverse___" + removeInvalidChars(inVar) +
removeInvalidChars(rBlock) + "___(void * InVar, "+taint.getSESE().getSESErecordName() +" *record)";
+ FlatSESEEnterNode fsese=taint.getSESE();
+ TempDescriptor tmp=taint.getVar();
+ index=fsese.getInVarsForDynamicCoarseConflictResolution().indexOf(tmp);
}
cFile.println(methodName + " {");
headerFile.println(methodName + ";");
+ cFile.println(" int totalcount=RUNBIAS;\n");
+ if (taint.isStallSiteTaint()) {
+ //need to add this
+ } else {
+ cFile.println(" record->rcrRecords["+index+"].count=RUNBIAS;\n");
+ }
if(cSideDebug) {
cFile.println("printf(\"The traverser ran for " + methodName + "\\n\");");
}
if(cases.size() == 0) {
- cFile.println(" return; }");
+ cFile.println(" return;");
} else {
//clears queue and hashtable that keeps track of where we've been.
cFile.println(clearQueue + ";\n" + resetVisitedHashTable + ";");
cFile.append(cases.get(singleCase));
cFile.println(" default:\n break; ");
- cFile.println(" }\n } while((ptr = " + dequeueFromQueueInC + ") != NULL);\n}\n}\n");
+ cFile.println(" }\n } while((ptr = " + dequeueFromQueueInC + ") != NULL);\n}");
}
+ if (taint.isStallSiteTaint()) {
+ //need to add this
+ } else {
+ cFile.println(" if(atomic_sub_and_test(RUNBIAS-totalcount,&(record->rcrRecords["+index+"].count))) {");
+ cFile.println(" int flag=LOCKXCHG(&(record->rcrRecords["+index+"].flag),0);");
+ cFile.println(" if(flag) {");
+ //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.flush();
}
objConfRead|=effect.hasReadConflict;
objConfWrite|=effect.hasWriteConflict;
}
- currCase.append(" int tmpvar;");
-
- if (objConfRead) {
- currCase.append(" if(");
- checkWaitingQueue(currCase, taint, node);
- currCase.append("||!");
- }
int index=-1;
if (taint.isRBlockTaint()) {
assert heaprootNum != -1;
int allocSiteID = connectedHRHash.get(taint).getWaitingQueueBucketNum(node);
int traverserID = doneTaints.get(taint);
- currCase.append(" (tmpvar=rcr_WRITEBINCASE(allHashStructures["+heaprootNum+"],"+prefix+", (SESEcommon *) record, "+index+"))");
+ if (objConfRead)
+ currCase.append(" int tmpvar=rcr_WTWRITEBINCASE(allHashStructures["+heaprootNum+"],"+prefix+", (SESEcommon *) record, "+index+");\n");
+ else
+ currCase.append(" int tmpvar=rcr_WRITEBINCASE(allHashStructures["+heaprootNum+"],"+prefix+", (SESEcommon *) record, "+index+");\n");
} else if (primConfRead||objConfRead) {
int heaprootNum = connectedHRHash.get(taint).id;
assert heaprootNum != -1;
int allocSiteID = connectedHRHash.get(taint).getWaitingQueueBucketNum(node);
int traverserID = doneTaints.get(taint);
- currCase.append(" (tmpvar=rcr_READBINCASE(allHashStructures["+heaprootNum+"],"+prefix+", (SESEcommon *) record, "+index+"))");
- }
-
- if(objConfRead) {
- currCase.append("&READYMASK) {\n");
- putIntoWaitingQueue(currCase, taint, node, prefix);
- currCase.append(" break;\n");
- currCase.append(" }\n");
- } else if(primConfRead||primConfWrite||objConfWrite) {
- currCase.append(";\n");
+ if (objConfRead)
+ currCase.append(" int tmpvar=rcr_WTREADBINCASE(allHashStructures["+heaprootNum+"],"+prefix+", (SESEcommon *) record, "+index+");\n");
+ else
+ currCase.append(" int tmpvar=rcr_READBINCASE(allHashStructures["+heaprootNum+"],"+prefix+", (SESEcommon *) record, "+index+");\n");
}
+ currCase.append("if (!(tmpvar&READYMASK)) totalcount--;\n");
+ currCase.append("if (!(tmpvar&SPEC)) ; //add record\n");
//Conflicts
return c;
}
-#ifdef BIT64
-static inline INTPTR LOCKXCHG(volatile INTPTR * ptr, INTPTR val){
- INTPTR retval;
+static inline int LOCKXCHG32(volatile int* ptr, int val){
+ int retval;
//note: xchgl always implies lock
- __asm__ __volatile__("xchgq %0,%1"
+ __asm__ __volatile__("xchgl %0,%1"
: "=r"(retval)
: "m"(*ptr), "0"(val)
: "memory");
return retval;
}
-#else
-static inline int LOCKXCHG(volatile int* ptr, int val){
- int retval;
+
+#ifdef BIT64
+static inline INTPTR LOCKXCHG(volatile INTPTR * ptr, INTPTR val){
+ INTPTR retval;
//note: xchgl always implies lock
- __asm__ __volatile__("xchgl %0,%1"
+ __asm__ __volatile__("xchgq %0,%1"
: "=r"(retval)
: "m"(*ptr), "0"(val)
: "memory");
return retval;
}
+#else
+#define LOCKXCHG LOCKXCHG32
#endif
/*
}
//consider SPEC flag
-
int rcr_WRITEBINCASE(HashStructure *T, void *ptr, SESEcommon *task, int index) {
//chain of bins exists => tail is valid
//if there is something in front of us, then we are not ready
T->array[key].head=val;//released lock
}
-rcr_RETIREHASHTABLE(HashStructure *T, SESEcommon *task, int key) {
+void rcr_RETIREHASHTABLE(HashStructure *T, SESEcommon *task, int key) {
BinElement_rcr * be = &(T->array[key]);
BinItem_rcr *b=be->head;
if (ptr->status==NOTREADY) {
ReadBinItem_rcr* rptr=(ReadBinItem_rcr*)ptr;
for (i=0;i<rptr->index;i++) {
- RESOLVE(rptr->array[i]);
+ TaskDescriptor * td=&rptr->array[i];
+ RESOLVE(td->task, td->bitindex);
if (((INTPTR)rptr->array[i].task)&PARENTBIN) {
//parents go immediately
atomic_dec(&rptr->item.total);
break;
if(ptr->status==NOTREADY) {
WriteBinItem_rcr* wptr=(WriteBinItem_rcr*)ptr;
- RESOLVE(wptr);
+ RESOLVE(wptr->task, wptr->bitindexwr);
ptr->status=READY;
if(((INTPTR)wptr->task)&PARENTBIN) {
val=val->next;
be->head=val; // release lock
}
}
+
+void RESOLVE(SESEcommon *record, bitvt mask) {
+ int index=-1;
+ struct rcrRecord * array=(struct rcrRecord *)(((char *)record)+record->common.offsetToParamRecords);
+ while(mask!=0) {
+ int shift=__builtin_ctzll(mask)+1;
+ index+=shift;
+ if (atomic_sub_and_test(1,&array[index].count)) {
+ inf flag=LOCKXCHG(&array[index].flag,0);
+ if (flag) {
+ if(atomic_sub_and_test(1, &(record->common.unresolvedDependencies)))
+ workScheduleSubmit((void *)record);
+ }
+ }
+ mask=mask>>shift;
+ }
+}
-#ifndef HASHSTRUCTURE_H_\r
-#define HASHSTRUCTURE_H_\r
-\r
-#include "mlp_runtime.h"\r
-//#include "WaitingQueue.h"\r
-\r
-#define ITEM_NOT_AT_FRONT_OF_WAITINGQ 3\r
-#define TRAVERSER_FINISHED 2\r
-#define bitvt unsigned long long\r
-\r
-//Note READEFFECT = READBIN and WRITEEFFECT=WRITEBIN. They mean the same thing\r
-//but are named differently for clarity in code.\r
-#define READEFFECT 0\r
-#define WRITEEFFECT 1\r
-#define WAITINGQUEUENOTE 2\r
-\r
-#define READBIN 0\r
-#define WRITEBIN 1\r
-#define BINMASK 1\r
-#define PARENTBIN 1\r
-\r
-#define SPEC 2\r
-#define READY 1 //Item is ready and we haven't seen this bin before\r
-#define NOTREADY 0 //Item is not ready and we haven't seen this bin before\r
-#define SPECREADY (SPEC|READY) //Item is ready and we've seen this bin before\r
-#define SPECNOTREADY (SPEC|NOTREADY) //Item is not ready and we've seen this bin before\r
-#define READYMASK 1\r
-
-\r
-#define TRUE 1\r
-#define FALSE 0\r
-\r
-#define RNUMBINS 64\r
-#define RNUMREAD 64\r
-#define RNUMRENTRY 256\r
-#define RH_MASK (RNUMBINS)-1\r
-\r
-//Note: put resolved things at the end and unresolved at the front.\r
-typedef struct BinItem_rcr {\r
- int total;\r
- int status;\r
- int type;\r
- //TODO keep track of record ptr here\r
- struct BinItem_rcr * next;\r
-} BinItem_rcr;\r
-\r
-typedef struct BinElement_rcr {\r
- BinItem_rcr * head;\r
- BinItem_rcr * tail;\r
-} BinElement_rcr;\r
-\r
-typedef struct Hashtable_rcr {\r
- BinElement_rcr array[RNUMBINS];\r
- // WaitingQueueBin * waitingQueue;\r
-} HashStructure;\r
-\r
-//Todo this is a clone of REntry, remove data fields as necessary\r
-typedef struct Entry_rcr {\r
- SESEcommon * task;\r
- bitvt bitindex;\r
-} TraverserData;\r
-\r
-typedef struct WriteBinItem_rcr {\r
- BinItem_rcr item;\r
- SESEcommon * task;\r
- bitvt bitindexwr;\r
- bitvt bitindexrd;\r
-} WriteBinItem_rcr;\r
-\r
-typedef struct ReadBinItem_rcr {\r
- BinItem_rcr item;\r
- TraverserData array[RNUMREAD];\r
- //We don't need a head index since if the item before it was freed, then all these would be considered ready as well.\r
- int index;\r
-} ReadBinItem_rcr;\r
-\r
-extern HashStructure ** allHashStructures;\r
-\r
-void rcr_createMasterHashTableArray(int maxSize); //temporary\r
-HashStructure* rcr_createHashtable(int sizeofWaitingQueue);\r
-WriteBinItem_rcr* rcr_createWriteBinItem();\r
-ReadBinItem_rcr* rcr_createReadBinItem();\r
-int rcr_isReadBinItem(BinItem_rcr* b);\r
-int rcr_isWriteBinItem(BinItem_rcr* b);\r
-inline int rcr_generateKey(void * ptr);\r
-\r
-//Method signatures are not in their final form since I have still not decided what is the optimum amount of data\r
-//to store in each entry.\r
-\r
-int rcr_WRITEBINCASE(HashStructure *T, void *ptr, SESEcommon *task, int index);\r
-int rcr_READBINCASE(HashStructure *T, void *ptr, SESEcommon * task, int index);\r
-int rcr_TAILREADCASE(HashStructure *T, void * ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, int index);\r
-void rcr_TAILWRITECASE(HashStructure *T, void *ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, int index);\r
-\r
-#endif\r
+#ifndef HASHSTRUCTURE_H_
+#define HASHSTRUCTURE_H_
+
+#include "mlp_runtime.h"
+//#include "WaitingQueue.h"
+
+#define bitvt unsigned long long
+
+//Note READEFFECT = READBIN and WRITEEFFECT=WRITEBIN. They mean the same thing
+//but are named differently for clarity in code.
+#define READEFFECT 0
+#define WRITEEFFECT 1
+#define WAITINGQUEUENOTE 2
+
+#define READBIN 0
+#define WRITEBIN 1
+#define BINMASK 1
+#define PARENTBIN 1
+
+#define SPEC 2
+#define READY 1 //Item is ready and we haven't seen this bin before
+#define NOTREADY 0 //Item is not ready and we haven't seen this bin before
+#define SPECREADY (SPEC|READY) //Item is ready and we've seen this bin before
+#define SPECNOTREADY (SPEC|NOTREADY) //Item is not ready and we've seen this bin before
+#define READYMASK 1
+
+
+#define TRUE 1
+#define FALSE 0
+
+#define RNUMBINS 64
+#define RNUMREAD 64
+#define RNUMRENTRY 256
+#define RH_MASK (RNUMBINS)-1
+
+//Note: put resolved things at the end and unresolved at the front.
+typedef struct BinItem_rcr {
+ int total;
+ int status;
+ int type;
+ //TODO keep track of record ptr here
+ struct BinItem_rcr * next;
+} BinItem_rcr;
+
+typedef struct BinElement_rcr {
+ BinItem_rcr * head;
+ BinItem_rcr * tail;
+} BinElement_rcr;
+
+typedef struct Hashtable_rcr {
+ BinElement_rcr array[RNUMBINS];
+ // WaitingQueueBin * waitingQueue;
+} HashStructure;
+
+//Todo this is a clone of REntry, remove data fields as necessary
+typedef struct Entry_rcr {
+ SESEcommon * task;
+ bitvt bitindex;
+} TraverserData;
+
+typedef struct WriteBinItem_rcr {
+ BinItem_rcr item;
+ SESEcommon * task;
+ bitvt bitindexwr;
+ bitvt bitindexrd;
+} WriteBinItem_rcr;
+
+typedef struct ReadBinItem_rcr {
+ BinItem_rcr item;
+ TraverserData array[RNUMREAD];
+ //We don't need a head index since if the item before it was freed, then all these would be considered ready as well.
+ int index;
+} ReadBinItem_rcr;
+
+extern HashStructure ** allHashStructures;
+
+void rcr_createMasterHashTableArray(int maxSize); //temporary
+HashStructure* rcr_createHashtable(int sizeofWaitingQueue);
+WriteBinItem_rcr* rcr_createWriteBinItem();
+ReadBinItem_rcr* rcr_createReadBinItem();
+inline int rcr_generateKey(void * ptr);
+
+//Method signatures are not in their final form since I have still not decided what is the optimum amount of data
+//to store in each entry.
+
+int rcr_WRITEBINCASE(HashStructure *T, void *ptr, SESEcommon *task, int index);
+int rcr_READBINCASE(HashStructure *T, void *ptr, SESEcommon * task, int index);
+int rcr_TAILREADCASE(HashStructure *T, void * ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, int index);
+void rcr_TAILWRITECASE(HashStructure *T, void *ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, SESEcommon * task, int index);
+
+#endif
void * workerTR(void *);
#define RCRSIZE 32
+#define RUNBIAS 1000000
struct rcrRecord {
int count;