From: yeom Date: Tue, 6 Apr 2010 02:11:40 +0000 (+0000) Subject: changes for handling unresolved in-var pointer. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=69ebfda5dfd8de6132df9a7b00765c84cab70acf;p=IRC.git changes for handling unresolved in-var pointer. --- diff --git a/Robust/src/Analysis/MLP/WaitingElement.java b/Robust/src/Analysis/MLP/WaitingElement.java index 97927046..1fa6c15c 100644 --- a/Robust/src/Analysis/MLP/WaitingElement.java +++ b/Robust/src/Analysis/MLP/WaitingElement.java @@ -3,11 +3,22 @@ package Analysis.MLP; import java.util.HashSet; import java.util.Iterator; +import IR.Flat.TempDescriptor; + public class WaitingElement { private int waitingID; private int status; private String dynID=""; + private TempDescriptor tempDesc; + + public void setTempDesc(TempDescriptor tempDesc){ + this.tempDesc=tempDesc; + } + + public TempDescriptor getTempDesc(){ + return tempDesc; + } public void setWaitingID(int waitingID) { this.waitingID = waitingID; diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 8832a0bc..a38b7a10 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -3359,55 +3359,7 @@ public class BuildCode { // create it's lock and take it immediately output.println(" pthread_mutex_init( &(seseToIssue->common.lock), NULL );"); // output.println(" pthread_mutex_lock( &(seseToIssue->common.lock) );"); - - // count up memory conflict dependencies, - // eom - ConflictGraph graph = null; - FlatSESEEnterNode parent = fsen.getParent(); - if (parent != null) { - if (parent.isCallerSESEplaceholder) { - graph = mlpa.getConflictGraphResults().get(parent.getfmEnclosing()); - } else { - graph = mlpa.getConflictGraphResults().get(parent); - } - } - if (graph != null && graph.hasConflictEdge()) { - HashSet seseLockSet = mlpa.getConflictGraphLockMap().get( - graph); - output.println(); - output.println(" //add memory queue element"); - Set waitingQueueSet = graph - .getWaitingElementSetBySESEID(fsen.getIdentifier(), - seseLockSet); - if (waitingQueueSet.size() > 0) { - output.println(" {"); - output.println(" REntry* rentry=NULL;"); - output.println(" seseToIssue->common.rentryIdx=0;"); - for (Iterator iterator = waitingQueueSet.iterator(); iterator - .hasNext();) { - WaitingElement waitingElement = (WaitingElement) iterator - .next(); - - if( waitingElement.getStatus() >= ConflictNode.COARSE ){ - output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", seseToIssue);"); - }else{ - output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", seseToIssue, seseToIssue->"+ waitingElement.getDynID() + ");"); - } - output.println(" rentry->queue=parentCommon->memoryQueueArray["+ waitingElement.getQueueID()+ "];"); - output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;"); - output - .println(" if(ADDRENTRY(parentCommon->memoryQueueArray[" - + waitingElement.getQueueID() - + "],rentry)==NOTREADY){"); - output.println(" ++(localCount);"); - output.println(" } "); - output.println(); - } - output.println(" }"); - } - output.println(); - } - + if( fsen != mlpa.getMainSESE() ) { // count up outstanding dependencies, static first, then dynamic Iterator staticSrcsItr = fsen.getStaticInVarSrcs().iterator(); @@ -3433,6 +3385,64 @@ public class BuildCode { // to pass the static name to the child's record output.println(" seseToIssue->"+srcPair+" = "+srcPair+";"); } + + //////////////// + // count up memory conflict dependencies, + // eom + ConflictGraph graph = null; + FlatSESEEnterNode parent = fsen.getParent(); + if (parent != null) { + if (parent.isCallerSESEplaceholder) { + graph = mlpa.getConflictGraphResults().get(parent.getfmEnclosing()); + } else { + graph = mlpa.getConflictGraphResults().get(parent); + } + } + if (graph != null && graph.hasConflictEdge()) { + HashSet seseLockSet = mlpa.getConflictGraphLockMap().get( + graph); + output.println(); + output.println(" //add memory queue element"); + Set waitingQueueSet = graph + .getWaitingElementSetBySESEID(fsen.getIdentifier(), + seseLockSet); + if (waitingQueueSet.size() > 0) { + output.println(" {"); + output.println(" REntry* rentry=NULL;"); + output.println(" seseToIssue->common.rentryIdx=0;"); + for (Iterator iterator = waitingQueueSet.iterator(); iterator + .hasNext();) { + WaitingElement waitingElement = (WaitingElement) iterator + .next(); + + if( waitingElement.getStatus() >= ConflictNode.COARSE ){ + output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", seseToIssue);"); + }else{ + TempDescriptor td=waitingElement.getTempDesc(); + VariableSourceToken vst=fsen.getStaticInVarSrc(td); + String srcId="SESE_"+vst.getSESE().getPrettyIdentifier()+vst.getSESE().getIdentifier()+"_"+vst.getAge(); + output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", seseToIssue, seseToIssue->"+ waitingElement.getDynID() + ");"); + output.println(" if(seseToIssue->"+ waitingElement.getDynID()+" == NULL) {"); + output.println(" rentry->pointer=(void*)&seseToIssue->"+srcId+"->"+waitingElement.getDynID()+";"); + output.println(" seseToIssue->common.unresolvedRentryArray[seseToIssue->common.unresolvedRentryIdx++]=rentry;"); + output.println(" }"); + } + output.println(" rentry->queue=parentCommon->memoryQueueArray["+ waitingElement.getQueueID()+ "];"); + output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;"); + output + .println(" if(ADDRENTRY(parentCommon->memoryQueueArray[" + + waitingElement.getQueueID() + + "],rentry)==NOTREADY){"); + output.println(" ++(localCount);"); + output.println(" } "); + output.println(); + } + output.println(" }"); + } + output.println(); + } + + //////////////// // dynamic sources might already be accounted for in the static list, // so only add them to forwarding lists if they're not already there @@ -3600,6 +3610,15 @@ public class BuildCode { // decrement dependency count for all SESE's on your forwarding list output.println(" while( !isEmpty( "+com+".forwardList ) ) {"); output.println(" SESEcommon* consumer = (SESEcommon*) getItem( "+com+".forwardList );"); + + output.println(" if(consumer->unresolvedRentryIdx>0){"); + output.println(" // resolved null pointer"); + output.println(" int idx;"); + output.println(" for(idx=0;idxunresolvedRentryIdx;idx++){"); + output.println(" resolvePointer(consumer->unresolvedRentryArray[idx]);"); + output.println(" }"); + output.println(" }"); + // output.println(" pthread_mutex_lock( &(consumer->lock) );"); // output.println(" --(consumer->unresolvedDependencies);"); // output.println(" if( consumer->unresolvedDependencies == 0 ) {"); diff --git a/Robust/src/Runtime/mlp_runtime.c b/Robust/src/Runtime/mlp_runtime.c index a63241cc..766b05cf 100644 --- a/Robust/src/Runtime/mlp_runtime.c +++ b/Robust/src/Runtime/mlp_runtime.c @@ -163,6 +163,7 @@ Hashtable* createHashtable(){ newTable->array[i]->head=NULL; newTable->array[i]->tail=NULL; } + newTable->unresolvedQueue=NULL; return newTable; } @@ -238,6 +239,61 @@ int ADDTABLE(MemoryQueue *q, REntry *r) { //at this point, have table Hashtable* table=(Hashtable*)q->tail; + r->hashtable=table; + if(*(r->pointer)==0 || (*(r->pointer)!=0 && table->unresolvedQueue!=NULL)){ + struct Queue* val; + // grab lock on the queue + do { + val=(struct Queue*)0x1; + val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val); + } while(val==(struct Queue*)0x1); + + if(val==NULL){ + //first case + if(*(r->pointer)!=0){ + // pointer is already resolved. + table->unresolvedQueue=val; //released lock; + return ADDTABLE(q,r); + } + table->unresolvedQueue=(struct Queue*)0x1; + struct Queue* queue=createQueue(); + addNewItem(queue,r); + atomic_inc(&table->item.total); + table->unresolvedQueue=queue; // expose new queue + }else{ + if(val==NULL){ + // someone else has already cleared all queue stuff + table->unresolvedQueue=val; // released lock + return ADDTABLE(q,r); + } + addNewItemBack(val,r); + atomic_inc(&table->item.total); + table->unresolvedQueue=val; // released lock + } + return NOTREADY; + } + + r->dynID=(void*)*(r->pointer); // interim fix. + BinItem * val; + int key=generateKey((unsigned int)(unsigned INTPTR)r->dynID); + do { + val=(BinItem*)0x1; + BinElement* bin=table->array[key]; + val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);//note...talk to me about optimizations here. + } while(val==(BinItem*)0x1); + //at this point have locked bin + if (val==NULL) { + return EMPTYBINCASE(table, table->array[key], r, TRUE); + } else { + if (isFineWrite(r)) { + return WRITEBINCASE(table, r, val, key, TRUE); + } else if (isFineRead(r)) { + return READBINCASE(table, r, val, key, TRUE); + } + } +} + +int ADDTABLEITEM(Hashtable* table, REntry* r){ BinItem * val; int key=generateKey((unsigned int)(unsigned INTPTR)r->dynID); do { @@ -247,17 +303,17 @@ int ADDTABLE(MemoryQueue *q, REntry *r) { } while(val==(BinItem*)0x1); //at this point have locked bin if (val==NULL) { - return EMPTYBINCASE(table, table->array[key], r); + return EMPTYBINCASE(table, table->array[key], r, FALSE); } else { if (isFineWrite(r)) { - return WRITEBINCASE(table, r, val, key); + return WRITEBINCASE(table, r, val, key, FALSE); } else if (isFineRead(r)) { - return READBINCASE(table, r, val, key); + return READBINCASE(table, r, val, key, FALSE); } } } -int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r) { +int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r, int inc) { int retval; BinItem* b; if (isFineWrite(r)) { @@ -283,7 +339,9 @@ int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r) { retval=NOTREADY; } - atomic_inc(&T->item.total); + if(inc){ + atomic_inc(&T->item.total); + } r->hashtable=T; r->binitem=b; be->tail=b; @@ -291,7 +349,7 @@ int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r) { return retval; } -int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val, int key) { +int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) { //chain of bins exists => tail is valid //if there is something in front of us, then we are not ready @@ -313,7 +371,9 @@ int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val, int key) { b->item.status=retval; // b->item.status=NOTREADY; - atomic_inc(&T->item.total); + if(inc){ + atomic_inc(&T->item.total); + } r->hashtable=T; r->binitem=(BinItem*)b; @@ -324,7 +384,7 @@ int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val, int key) { return retval; } -READBINCASE(Hashtable *T, REntry *r, BinItem *val, int key) { +READBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) { BinItem * bintail=T->array[key]->tail; if (isReadBinItem(bintail)) { return TAILREADCASE(T, r, val, bintail, key); @@ -334,7 +394,7 @@ READBINCASE(Hashtable *T, REntry *r, BinItem *val, int key) { } } -int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key) { +int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) { ReadBinItem * readbintail=(ReadBinItem*)T->array[key]->tail; int status, retval; if (readbintail->item.status=READY) { @@ -363,13 +423,15 @@ int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int ke r->binitem=(BinItem*)readbintail; //printf("grouping with %d\n",readbintail->index); } - atomic_inc(&T->item.total); + if(inc){ + atomic_inc(&T->item.total); + } r->hashtable=T; T->array[key]->head=val;//released lock return retval; } -TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key) { +TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) { // WriteBinItem* wb=createWriteBinItem(); //wb->val=r; //wb->item.total=1;//safe because item could not have started @@ -378,7 +440,9 @@ TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key) rb->array[rb->index++]=r; rb->item.total=1;//safe because item could not have started rb->item.status=NOTREADY; - atomic_inc(&T->item.total); + if(inc){ + atomic_inc(&T->item.total); + } r->hashtable=T; r->binitem=(BinItem*)rb; T->array[key]->tail->next=(BinItem*)rb; @@ -701,7 +765,7 @@ RESOLVESCC(SCC *S) { resolveDependencies(REntry* rentry){ SESEcommon* seseCommon=(SESEcommon*)rentry->seseRec; - if(rentry->type==READ || rentry->type==WRITE || rentry->type==COARSE || rentry->type==SCCITEM){ + if(rentry->type==READ || rentry->type==WRITE || rentry->type==COARSE || rentry->type==SCCITEM){ if( atomic_sub_and_test(1, &(seseCommon->unresolvedDependencies)) ){ workScheduleSubmit(seseCommon); } @@ -710,3 +774,38 @@ resolveDependencies(REntry* rentry){ } } +resolvePointer(REntry* rentry){ + rentry->dynID=(void*)*(rentry->pointer); // interim. + Hashtable* table=rentry->hashtable; + struct Queue* val; + do { + val=(struct Queue*)0x1; + val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val); + } while(val==(struct Queue*)0x1); + if(val!=NULL && getHead(val)->objectptr==rentry){ + // handling pointer is the first item of the queue + // start to resolve until it reaches unresolved pointer or end of queue + do{ + struct QueueItem* head=getHead(val); + if(head!=NULL){ + REntry* rentry=(REntry*)head->objectptr; + if(*(rentry->pointer)==0){ + // encounters following unresolved pointer + table->unresolvedQueue=val;//released lock + break; + } + removeItem(val,head); + if(ADDTABLEITEM(table, rentry)==READY){ + SESEcommon* seseCommon=(SESEcommon*)rentry->seseRec; + atomic_sub_and_test(1, &(seseCommon->unresolvedDependencies)); + } + }else{ + table->unresolvedQueue=NULL; // set hashtable as normal-mode. + break; + } + }while(TRUE); + }else{ + table->unresolvedQueue=val;//released lock; + } +} + diff --git a/Robust/src/Runtime/mlp_runtime.h b/Robust/src/Runtime/mlp_runtime.h index abf5b747..489d388f 100644 --- a/Robust/src/Runtime/mlp_runtime.h +++ b/Robust/src/Runtime/mlp_runtime.h @@ -58,6 +58,7 @@ typedef struct REntry_t{ psemaphore parentStallSem; void* seseRec; void* dynID; + INTPTR* pointer; } REntry; typedef struct MemoryQueueItem_t { @@ -82,6 +83,7 @@ typedef struct BinItem_t { typedef struct Hashtable_t { MemoryQueueItem item; struct BinElement_t* array[NUMBINS]; + struct Queue* unresolvedQueue; } Hashtable; typedef struct BinElement_t { @@ -153,8 +155,10 @@ typedef struct SESEcommon_t { int numMemoryQueue; int rentryIdx; + int unresolvedRentryIdx; struct MemoryQueue_t** memoryQueueArray; struct REntry_t* rentryArray[NUMRENTRY]; + struct REntry_t* unresolvedRentryArray[NUMRENTRY]; } SESEcommon;