changes for handling unresolved in-var pointer.
authoryeom <yeom>
Tue, 6 Apr 2010 02:11:40 +0000 (02:11 +0000)
committeryeom <yeom>
Tue, 6 Apr 2010 02:11:40 +0000 (02:11 +0000)
Robust/src/Analysis/MLP/WaitingElement.java
Robust/src/IR/Flat/BuildCode.java
Robust/src/Runtime/mlp_runtime.c
Robust/src/Runtime/mlp_runtime.h

index 979270467ce353fdb3483e87e7302e05676824ce..1fa6c15c543fcc888637df2af8a8a05b273d8ecd 100644 (file)
@@ -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;
index 8832a0bcbb5f13ab85cd3535c67dceefd968d3a8..a38b7a109d0514494b5375716ab44268f043f6c1 100644 (file)
@@ -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<SESELock> seseLockSet = mlpa.getConflictGraphLockMap().get(
-                               graph);
-               output.println();
-               output.println("     //add memory queue element");
-               Set<WaitingElement> 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<SESEandAgePair> 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<SESELock> seseLockSet = mlpa.getConflictGraphLockMap().get(
+                               graph);
+               output.println();
+               output.println("     //add memory queue element");
+               Set<WaitingElement> 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;idx<consumer->unresolvedRentryIdx;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 ) {");
index a63241ccbf599e28f5fa5bf53a110ce74632c97f..766b05cf0951f79eef097fbd5dcf3f9c2a342007 100644 (file)
@@ -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;
+  }  
+}
+
index abf5b74785ac06339901af3804acf888511e7e9d..489d388f83003ddbfcc08eb448136407d4febdfa 100644 (file)
@@ -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;