// initializing variables can be found in printHeader()
private static final String getAllocSiteInC = "->allocsite";
- private static final String queryVistedHashtable = "hashRCRInsert(";
+ private static final String queryVistedHashtable = "hashRCRInsert";
private static final String addToQueueInC = "enqueueRCRQueue(";
private static final String dequeueFromQueueInC = "dequeueRCRQueue()";
private static final String clearQueue = "resetRCRQueue()";
String flatname;
if(fn instanceof FlatSESEEnterNode) {
flatname = ((FlatSESEEnterNode) fn).getPrettyIdentifier();
- }
- else {
+ } else {
flatname = fn.toString();
}
if(taint.isStallSiteTaint()) {
rBlock = taint.getStallSite().toString();
- }
- else if(taint.isRBlockTaint()) {
- rBlock = taint.getSESE().toPrettyString();
- }
- else {
+ } else if(taint.isRBlockTaint()) {
+ rBlock = taint.getSESE().getPrettyIdentifier();
+ } else {
System.out.println("RCR CRITICAL ERROR: TAINT IS NEITHER A STALLSITE NOR SESE! " + taint.toString());
return;
}
}
else {
//clears queue and hashtable that keeps track of where we've been.
- cFile.println(clearQueue + "; " + resetVisitedHashTable + ";");
+ cFile.println(clearQueue + ";\n" + resetVisitedHashTable + ";");
//Casts the ptr to a genericObjectStruct so we can get to the ptr->allocsite field.
- cFile.println("struct genericObjectStruct * ptr = (struct genericObjectStruct *) InVar;\nif(InVar != NULL) {\n " + queryVistedHashtable
- + "ptr);\n do { ");
+ cFile.println("struct genericObjectStruct * ptr = (struct genericObjectStruct *) InVar;\nif (InVar != NULL) {\n " + queryVistedHashtable
+ + "(ptr);\n do {");
- cFile.println(" switch(ptr->allocsite) { ");
+ cFile.println(" switch(ptr->allocsite) {");
for(AllocSite singleCase: cases.keySet())
cFile.append(cases.get(singleCase));
cFile.println(" default:\n break; ");
- cFile.println(" }\n } while((ptr = " + dequeueFromQueueInC + ") != NULL);\n}\n}");
+ cFile.println(" }\n } while((ptr = " + dequeueFromQueueInC + ") != NULL);\n}\n}\n");
}
cFile.flush();
}
//either currCase is continuing off a parent case or is its own.
assert currCase !=null;
- //Casts C pointer; depth is used to create unique "myPtr" name for when things are inlined
- String currPtr = "myPtr" + depth;
-
- String structType = node.original.getType().getSafeSymbol();
- currCase.append(" struct " + structType + " * "+currPtr+"= (struct "+ structType + " * ) " + prefix + ";\n");
-
//Primitives Test
if(node.hasPrimitiveConflicts()) {
//This will check hashstructure, if cannot continue, add all to waiting queue and break; s
- addCheckHashtableAndWaitingQ(currCase, taint, node, currPtr, depth);
- currCase.append(" break;\n } \n");
+ addCheckHashtableAndWaitingQ(currCase, taint, node, prefix, depth);
+ currCase.append(" break;\n }\n");
}
//Conflicts
for (ObjRef ref : node.objectRefs) {
// Will only process edge if there is some sort of conflict with the Child
if (ref.hasConflictsDownThisPath()) {
- String childPtr = currPtr +"->___" + ref.field + "___";
+ String childPtr = "((struct "+node.original.getType().getSafeSymbol()+" *)"+prefix +")->___" + ref.field + "___";
+ int pdepth=depth+1;
+ String currPtr = "myPtr" + pdepth;
+ String structType = ref.child.original.getType().getSafeSymbol();
+ currCase.append(" struct " + structType + " * "+currPtr+"= (struct "+ structType + " * ) " + childPtr + ";\n");
- // Checks if the child exists and has allocsite matching the conflict
- currCase.append(" if(" + childPtr + " != NULL && " + childPtr + getAllocSiteInC + "==" + ref.allocSite + ") { \n");
-
+ // Checks if the child exists and has allocsite matching the conflict
+ currCase.append(" if (" + currPtr + " != NULL && " + currPtr + getAllocSiteInC + "==" + ref.allocSite + ") {\n");
//Handles Direct Conflicts on child.
if(ref.hasDirectObjConflict()) {
//This method will touch the waiting queues if necessary.
//If there are no direct conflicts (determined by static + dynamic), finish check
if (ref.child.decendantsConflict() || ref.child.hasPrimitiveConflicts()) {
// Checks if we have visited the child before
- currCase.append(" if(" + queryVistedHashtable + childPtr + ")) {\n");
+
+ currCase.append(" if (" + queryVistedHashtable +"("+ currPtr + ")) {\n");
if (ref.child.getNumOfReachableParents() == 1 && !ref.child.isInsetVar) {
- addChecker(taint, ref.child, cases, currCase, childPtr, depth + 1);
+ addChecker(taint, ref.child, cases, currCase, currPtr, depth + 1);
}
else {
currCase.append(" " + addToQueueInC + childPtr + ");\n ");
Iterator<ConcreteRuntimeObjNode> it = node.enqueueToWaitingQueueUponConflict.iterator();
currCase.append(" int retval"+depth+" = "+ addCheckFromHashStructure + ptr + ");\n");
- currCase.append(" if(retval"+depth+" == " + conflictButTraverserCannotContinue + " || ");
+ currCase.append(" if (retval"+depth+" == " + conflictButTraverserCannotContinue + " || ");
checkWaitingQueue(currCase, t, node);
currCase.append(") {\n");
//If cannot continue, then add all the undetermined references that lead from this child, including self.
//NOTE if the C-side is changed, this will have to be changed accordingly
//TODO make sure this matches c-side
- sb.append(" put("+allocSiteID+", " +
+ sb.append(" putIntoWaitingQueue("+allocSiteID+", " +
"allHashStructures["+ heaprootNum +"]->waitingQueue, " +
resumePtr + ", " +
traverserID+");\n");
assert heaprootNum != -1;
int allocSiteID = connectedHRHash.get(taint).getWaitingQueueBucketNum(node);
- sb.append(" (check(" + "allHashStructures["+ heaprootNum +"]->waitingQueue, " + allocSiteID + ") == "+ allocQueueIsNotEmpty+")");
+ sb.append(" (isEmptyForWaitingQ(allHashStructures["+ heaprootNum +"]->waitingQueue, " + allocSiteID + ") == "+ allocQueueIsNotEmpty+")");
}
private void enumerateHeaproots() {
}\r
\r
//NOTE: allocSiteID is NOT the same as allocsite, rather it's an ID generated by the traverser for an alloc site for a traversal.\r
-void putIntoWaitingQueue(int allocSiteID, WaitingQueueBin * queue, int effectType, void * resumePtr, int traverserID) {\r
+void putIntoWaitingQueue(int allocSiteID, WaitingQueueBin * queue, void * resumePtr, int traverserID) {\r
//since Put SHOULD be done only by 1 thread (from 1 hashtable), the locking mechanism is removed.\r
WaitingQueueBin *qptr=&queue[allocSiteID];\r
WaitingQueueBinVector * tail = qptr->tail;\r
+ int effectType=0;//PLACEHOLDER....EITHER GET RID OF VARIABLE OR PASS IN\r
\r
if (tail == NULL) {\r
//completely empty case\r
}\r
\r
int isEmptyForWaitingQ(WaitingQueueBin * queue, int allocSiteID) {\r
- return (queue[allocSiteID]).size == 0;\r
+ return queue[allocSiteID].size;\r
}\r
\r
//This method should be called by the SESE block\r
int size;
} WaitingQueueBin;
-void putIntoWaitingQueue(int allocSiteID, WaitingQueueBin * queue, int effectType, void * resumePtr, int traverserID);
+void putIntoWaitingQueue(int allocSiteID, WaitingQueueBin * queue, void * resumePtr, int traverserID);
int isEmptyForWaitingQ(WaitingQueueBin * queue, int allocSiteID);
WaitingQueueBin * mallocWaitingQueue(int size);
WaitingQueueBinVector * returnWaitingQueueBinVectorToFreePool(struct BinVector_wq *ptr);
return (((struct genericObjectStruct *) ptr)->oid)&H_MASK;
}
-//TODO handle logic for waiting Queues separately
-//TODO pass in task to traverser
-int rcr_ADDTABLEITEM(HashStructure* table, void * ptr, int type, int traverserID, SESEcommon *task, void * heaproot){
+int rcr_WRITEBINCASE(HashStructure *T, void *ptr, int traverserID, SESEcommon *task, void *heaproot) {
+ //chain of bins exists => tail is valid
+ //if there is something in front of us, then we are not ready
BinItem_rcr * val;
int key=rcr_generateKey(ptr);
+ BinElement_rcr* be= &(T->array[key]); //do not grab head from here since it's locked (i.e. = 0x1)
//LOCK is still needed as different threads will remove items...
do {
val=(BinItem_rcr *)0x1;
- val=(BinItem_rcr *)LOCKXCHG((unsigned INTPTR*)&(table->array[key].head), (unsigned INTPTR)val);
+ val=(BinItem_rcr *)LOCKXCHG((unsigned INTPTR*)&(be->head), (unsigned INTPTR)val);
} while(val==(BinItem_rcr*)0x1);
if (val==NULL) {
- return rcr_EMPTYBINCASE(table, &table->array[key], ptr, type, traverserID, task, heaproot);
- } else {
- //else create item
- if (type == WRITEEFFECT) {
- return rcr_WRITEBINCASE(table, val, ptr, key, traverserID, task, heaproot);
- } else if (type == READEFFECT) {
- return rcr_READBINCASE(table, val, ptr, key, traverserID, task, heaproot);
- }
+ BinItem_rcr * b=(BinItem_rcr*)rcr_createWriteBinItem();
+ TraverserData * td = &((WriteBinItem_rcr*)b)->val;
+ b->total=1;
+ b->status=READY;
+
+ //common to both types
+ td->binitem = b;
+ td->hashtable=T;
+ td->resumePtr = ptr;
+ td->task= task;
+ td->traverserID = traverserID;
+ td->heaproot = heaproot;
+ be->tail=b;
+
+ //release lock
+ be->head=b;
+ return READY;
}
-}
-
-int rcr_EMPTYBINCASE(HashStructure *T, BinElement_rcr* be, void *ptr, int type, int traverserId, SESEcommon * task, void *heaproot){
- BinItem_rcr* b;
- TraverserData * td;
- //TODO: NEED PARENT CHECK HERE!!!!!!!!!
-
-
- if (type == WRITEEFFECT) {
- b=(BinItem_rcr*)rcr_createWriteBinItem();
- td = &((WriteBinItem_rcr*)b)->val;
- } else if (type == READEFFECT) {
- b=(BinItem_rcr*)rcr_createReadBinItem();
- ReadBinItem_rcr* readbin=(ReadBinItem_rcr*)b;
- td = &(readbin->array[readbin->index++]);
- }
- b->total=1;
- b->type= type;
- b->status = READY;
-
- //common to both types
- td->binitem = b;
- td->hashtable=T;
- td->resumePtr = ptr;
- td->task= task;
- td->traverserID = traverserId;
- td->heaproot = heaproot;
- be->tail=b;
-
- //release lock
- be->head=b;
-
- return READY;
-}
-
-int rcr_WRITEBINCASE(HashStructure *T, BinItem_rcr *val, void *ptr, int key, int traverserID, SESEcommon *task, void *heaproot) {
- //chain of bins exists => tail is valid
- //if there is something in front of us, then we are not ready
int status=NOTREADY;
- BinElement_rcr* be= &(T->array[key]); //do not grab head from here since it's locked (i.e. = 0x1)
BinItem_rcr *bintail=be->tail;
if (bintail->type == WRITEBIN) {
return status;
}
-int rcr_READBINCASE(HashStructure *T, BinItem_rcr *val, void *ptr, int key, int traverserID, SESEcommon * task, void *heaproot) {
+int rcr_READBINCASE(HashStructure *T, void *ptr, int traverserID, SESEcommon * task, void *heaproot) {
+ BinItem_rcr * val;
+ int key=rcr_generateKey(ptr);
BinElement_rcr * be = &(T->array[key]);
+
+ //LOCK is still needed as different threads will remove items...
+ do {
+ val=(BinItem_rcr *)0x1;
+ val=(BinItem_rcr *)LOCKXCHG((unsigned INTPTR*)&(be->head), (unsigned INTPTR)val);
+ } while(val==(BinItem_rcr*)0x1);
+
+ if (val==NULL) {
+ BinItem_rcr * b=(BinItem_rcr*)rcr_createReadBinItem();
+ ReadBinItem_rcr* readbin=(ReadBinItem_rcr*)b;
+ TraverserData * td = &(readbin->array[readbin->index++]);
+ b->total=1;
+ b->status = READY;
+
+ //common to both types
+ td->binitem = b;
+ td->hashtable=T;
+ td->resumePtr = ptr;
+ td->task= task;
+ td->traverserID = traverserID;
+ td->heaproot = heaproot;
+ be->tail=b;
+
+ //release lock
+ be->head=b;
+
+ return READY;
+ }
+
+
BinItem_rcr * bintail=be->tail;
+
//check if already added item or not.
if (bintail->type == WRITEBIN) {
TraverserData * td = &(((WriteBinItem_rcr *)bintail)->val);
TraverserData array[NUMREAD];\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
+ \r
} ReadBinItem_rcr;\r
\r
typedef struct WQNote_rcr {\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
-int rcr_ADDTABLEITEM(HashStructure* table, void * ptr, int type, int traverserID, SESEcommon *task, void * heaproot);\r
-int rcr_EMPTYBINCASE(HashStructure *T, BinElement_rcr* be, void *ptr, int type, int traverserId, SESEcommon * task, void *heaproot);\r
-int rcr_WRITEBINCASE(HashStructure *T, BinItem_rcr *val, void *ptr, int key, int traverserID, SESEcommon *task, void *heaproot);\r
-int rcr_READBINCASE(HashStructure *T, BinItem_rcr *val, void *ptr, int key, int traverserID, SESEcommon * task, void *heaproot);\r
+\r
+int rcr_WRITEBINCASE(HashStructure *T, void *ptr, int traverserID, SESEcommon *task, void *heaproot);\r
+int rcr_READBINCASE(HashStructure *T, void *ptr, int traverserID, SESEcommon * task, void *heaproot);\r
int rcr_TAILREADCASE(HashStructure *T, void * ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, int traverserID, SESEcommon * task, void *heaproot);\r
void rcr_TAILWRITECASE(HashStructure *T, void *ptr, BinItem_rcr *val, BinItem_rcr *bintail, int key, int traverserID, SESEcommon * task, void *heaproot);\r
int rcr_REMOVETABLEITEM(HashStructure* table, void * ptr, int traverserID, SESEcommon *task, void * heaproot);\r