changes for the case that an SESE enqueues more than one request into the same queue.
authoryeom <yeom>
Thu, 6 May 2010 23:44:52 +0000 (23:44 +0000)
committeryeom <yeom>
Thu, 6 May 2010 23:44:52 +0000 (23:44 +0000)
Robust/src/Analysis/MLP/ConflictGraph.java
Robust/src/Analysis/MLP/SESEWaitingQueue.java [new file with mode: 0644]
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 3903a2cf66fa485a3b046401a692bd00dae8be60..9d1260453ba667701a6e742fe8a23b8cd8c69d88 100644 (file)
@@ -3,6 +3,7 @@ package Analysis.MLP;
 import java.io.BufferedWriter;
 import java.io.FileWriter;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Iterator;
@@ -56,11 +57,10 @@ public class ConflictGraph {
 
        private boolean compareHRNSet(Set<HeapRegionNode> setA,
                        Set<HeapRegionNode> setB) {
-
+               boolean found = false;
                for (Iterator iterator = setA.iterator(); iterator.hasNext();) {
                        HeapRegionNode heapRegionNode = (HeapRegionNode) iterator.next();
                        String gID = heapRegionNode.getGloballyUniqueIdentifier();
-                       boolean found = false;
                        for (Iterator iterator2 = setB.iterator(); iterator2.hasNext();) {
                                HeapRegionNode heapRegionNode2 = (HeapRegionNode) iterator2
                                                .next();
@@ -68,9 +68,9 @@ public class ConflictGraph {
                                        found = true;
                                }
                        }
-                       if (!found) {
-                               return false;
-                       }
+               }
+               if (!found) {
+                       return false;
                }
                return true;
        }
@@ -184,7 +184,7 @@ public class ConflictGraph {
                                                                                && seseLock
                                                                                                .containsConflictEdge(conflictEdge)) {
                                                                        WaitingElement newElement = new WaitingElement();
-                                                                       newElement.setWaitingID(seseLock.getID());
+                                                                       newElement.setQueueID(seseLock.getID());
                                                                        if (isFineElement(newElement.getStatus())) {
                                                                                newElement
                                                                                                .setDynID(node
@@ -275,7 +275,7 @@ public class ConflictGraph {
 
        }
 
-       public Set<WaitingElement> getWaitingElementSetBySESEID(int seseID,
+       public SESEWaitingQueue getWaitingElementSetBySESEID(int seseID,
                        HashSet<SESELock> seseLockSet) {
                HashSet<WaitingElement> waitingElementSet = new HashSet<WaitingElement>();
 
@@ -304,7 +304,7 @@ public class ConflictGraph {
                                                                        && seseLock
                                                                                        .containsConflictEdge(conflictEdge)) {
                                                                WaitingElement newElement = new WaitingElement();
-                                                               newElement.setWaitingID(seseLock.getID());
+                                                               newElement.setQueueID(seseLock.getID());
                                                                newElement.setStatus(seseLock
                                                                                .getNodeType(liveInNode));
                                                                if (isFineElement(newElement.getStatus())) {
@@ -324,8 +324,96 @@ public class ConflictGraph {
                        }
 
                }
+               
+               //handle the case that multiple enqueues by an SESE for different live-in into the same queue
+               return refineQueue(waitingElementSet);
+//             return waitingElementSet;
+               
+       }
+       
+       public SESEWaitingQueue refineQueue(Set<WaitingElement> waitingElementSet) {
+
+               Set<WaitingElement> refinedSet=new HashSet<WaitingElement>();
+               HashMap<Integer, Set<WaitingElement>> map = new HashMap<Integer, Set<WaitingElement>>();
+               SESEWaitingQueue seseDS=new SESEWaitingQueue();
+
+               for (Iterator iterator = waitingElementSet.iterator(); iterator
+                               .hasNext();) {
+                       WaitingElement waitingElement = (WaitingElement) iterator.next();
+                       Set<WaitingElement> set=map.get(new Integer(waitingElement.getQueueID()));
+                       if(set==null){
+                               set=new HashSet<WaitingElement>();
+                       }
+                       set.add(waitingElement);
+                       map.put(new Integer(waitingElement.getQueueID()), set);
+               }
+               
+               Set<Integer> keySet=map.keySet();
+               for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
+                       Integer queueID = (Integer) iterator.next();
+                       Set<WaitingElement> queueWEset=map.get(queueID);
+                       refineQueue(queueID.intValue(),queueWEset,seseDS);                      
+               }
+               
+               return seseDS;
+       }
+       
+       private void refineQueue(int queueID,
+                       Set<WaitingElement> waitingElementSet, SESEWaitingQueue seseDS) {
 
-               return waitingElementSet;
+               if (waitingElementSet.size() > 1) {
+                       //only consider there is more than one element submitted by same SESE
+                       Set<WaitingElement> refinedSet = new HashSet<WaitingElement>();
+
+                       int numCoarse = 0;
+                       int numRead = 0;
+                       int numWrite = 0;
+                       int total=waitingElementSet.size();
+                       WaitingElement SCCelement = null;
+                       WaitingElement coarseElement = null;
+
+                       for (Iterator iterator = waitingElementSet.iterator(); iterator
+                                       .hasNext();) {
+                               WaitingElement waitingElement = (WaitingElement) iterator
+                                               .next();
+                               if (waitingElement.getStatus() == ConflictNode.FINE_READ) {
+                                       numRead++;
+                               } else if (waitingElement.getStatus() == ConflictNode.FINE_WRITE) {
+                                       numWrite++;
+                               } else if (waitingElement.getStatus() == ConflictNode.COARSE) {
+                                       numCoarse++;
+                                       coarseElement = waitingElement;
+                               } else if (waitingElement.getStatus() == ConflictNode.SCC) {
+                                       SCCelement = waitingElement;
+                               } 
+                       }
+
+                       if (SCCelement != null) {
+                               // if there is at lease one SCC element, just enqueue SCC and
+                               // ignore others.
+                               refinedSet.add(SCCelement);
+                       } else if (numCoarse == 1 && (numRead + numWrite == total)) {
+                               // if one is a coarse, the othere are reads/write, enqueue SCC.
+                               WaitingElement we = new WaitingElement();
+                               we.setQueueID(queueID);
+                               we.setStatus(ConflictNode.SCC);
+                               refinedSet.add(we);
+                       } else if (numCoarse == total) {
+                               // if there are multiple coarses, enqueue just one coarse.
+                               refinedSet.add(coarseElement);
+                       } else if(numWrite==total || (numRead+numWrite)==total){
+                               // code generator is going to handle the case for multiple writes & read/writes.
+                               seseDS.setType(queueID, SESEWaitingQueue.EXCEPTION);
+                               refinedSet.addAll(waitingElementSet);
+                       } else{
+                               // otherwise, enqueue everything.
+                               refinedSet.addAll(waitingElementSet);
+                       }
+                       seseDS.setWaitingElementSet(queueID, refinedSet);
+               } else {
+                       seseDS.setWaitingElementSet(queueID, waitingElementSet);
+               }
+               
        }
 
        public boolean isFineElement(int type) {
@@ -662,7 +750,6 @@ public class ConflictGraph {
                                HeapRegionNode heapRegionNode = (HeapRegionNode) iterator
                                                .next();
                                String gID = heapRegionNode.getGloballyUniqueIdentifier();
-                               boolean found = false;
                                for (Iterator iterator2 = setB.iterator(); iterator2.hasNext();) {
                                        HeapRegionNode heapRegionNode2 = (HeapRegionNode) iterator2
                                                        .next();
@@ -857,7 +944,10 @@ public class ConflictGraph {
                
                Set<HeapRegionNode> entryHRNSet = getSameHeapRoot(liveInHrnSetA,
                                liveInHrnSetB);
-               if (entryHRNSet.size() == 0) {
+               if (entryHRNSet.size() == 0 ) {
+                       return ConflictEdge.COARSE_GRAIN_EDGE;
+               }
+               if(entryHRNSet.size()!=liveInHrnSetA.size() || entryHRNSet.size()!=liveInHrnSetB.size()){
                        return ConflictEdge.COARSE_GRAIN_EDGE;
                }
 
@@ -1107,4 +1197,4 @@ class ConflictEdge {
                return getVertexU() + "-" + getVertexV();
        }
 
-}
\ No newline at end of file
+}
diff --git a/Robust/src/Analysis/MLP/SESEWaitingQueue.java b/Robust/src/Analysis/MLP/SESEWaitingQueue.java
new file mode 100644 (file)
index 0000000..e0457bb
--- /dev/null
@@ -0,0 +1,53 @@
+package Analysis.MLP;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Set;
+
+public class SESEWaitingQueue {
+       public static final int NORMAL= 0; // enqueue all stuff.
+       public static final int EXCEPTION= 1; // dynamically decide whether a waiting element is enqueued or not.
+       
+       private HashMap<Integer, Set<WaitingElement>>mapWaitingElement;
+       private HashMap<Integer, Integer>mapType;
+       
+       public SESEWaitingQueue(){
+               mapWaitingElement=new HashMap<Integer, Set<WaitingElement>>();
+               mapType=new HashMap<Integer, Integer>();
+       }
+       
+       public void setType(int queueID, int type){
+               mapType.put(new Integer(queueID), new Integer(type));
+       }
+       
+       public int getType(int queueID){
+               Integer type=mapType.get(new Integer(queueID));
+               if(type==null){
+                       return SESEWaitingQueue.NORMAL;
+               }else{
+                       return type.intValue();
+               }
+       }
+       
+       public void setWaitingElementSet(int queueID, Set<WaitingElement> set){
+               mapWaitingElement.put(new Integer(queueID), set);
+       }
+       
+       public Set<WaitingElement> getWaitingElementSet(int queueID){
+               return mapWaitingElement.get(new Integer(queueID));
+       }
+       
+       public Set<Integer> getQueueIDSet(){
+               return mapWaitingElement.keySet();
+       }
+       
+       public int getWaitingElementSize(){
+               int size=0;
+               Set<Integer> keySet=mapWaitingElement.keySet();
+               for (Iterator iterator = keySet.iterator(); iterator.hasNext();) {
+                       Integer key = (Integer) iterator.next();
+                       size+=mapWaitingElement.get(key).size();
+               }
+               return size;
+       }
+}
index 1fa6c15c543fcc888637df2af8a8a05b273d8ecd..3e9f39a8d83d4e743154a4dc848094f010339b15 100644 (file)
@@ -7,7 +7,7 @@ import IR.Flat.TempDescriptor;
 
 public class WaitingElement {
 
-       private int waitingID;
+       private int queueID;
        private int status;
        private String dynID="";
        private TempDescriptor tempDesc;
@@ -20,8 +20,8 @@ public class WaitingElement {
                return tempDesc;
        }
 
-       public void setWaitingID(int waitingID) {
-               this.waitingID = waitingID;
+       public void setQueueID(int queueID) {
+               this.queueID = queueID;
        }
        
        public String getDynID(){
@@ -33,7 +33,7 @@ public class WaitingElement {
        }
        
        public int getQueueID() {
-               return waitingID;
+               return queueID;
        }
 
        public void setStatus(int status) {
@@ -56,7 +56,7 @@ public class WaitingElement {
 
                WaitingElement in = (WaitingElement) o;
 
-               if (waitingID == in.getQueueID() && status == in.getStatus() && dynID.equals(in.getDynID()) ) {
+               if (queueID == in.getQueueID() && status == in.getStatus() && dynID.equals(in.getDynID()) ) {
                        return true;
                } else {
                        return false;
@@ -65,7 +65,7 @@ public class WaitingElement {
        }
 
        public String toString() {
-               return "[waitingID=" + waitingID + " status=" + status + " dynID="
+               return "[waitingID=" + queueID + " status=" + status + " dynID="
                                + dynID + "]";
        }
 
@@ -73,7 +73,7 @@ public class WaitingElement {
 
                int hash = 1;
 
-               hash = hash * 31 + waitingID;
+               hash = hash * 31 + queueID;
 
                hash += status;
                
index 496f32937462cd8eaab7210084ca5ff2c89f73e4..8a65dedce4c578d9039de4455953c5b2982b4aa7 100644 (file)
@@ -32,6 +32,7 @@ import Analysis.MLP.ConflictNode;
 import Analysis.MLP.MLPAnalysis;
 import Analysis.MLP.ParentChildConflictsMap;
 import Analysis.MLP.SESELock;
+import Analysis.MLP.SESEWaitingQueue;
 import Analysis.MLP.VariableSourceToken;
 import Analysis.MLP.VSTWrapper;
 import Analysis.MLP.CodePlan;
@@ -3540,94 +3541,117 @@ public class BuildCode {
                                                .get(graph);
                                output.println();
                                output.println("     //add memory queue element");
-                               Set<WaitingElement> waitingQueueSet = graph
-                                               .getWaitingElementSetBySESEID(fsen.getIdentifier(),
-                                                               seseLockSet);
-                               if (waitingQueueSet.size() > 0) {
+                               SESEWaitingQueue seseWaitingQueue=graph.getWaitingElementSetBySESEID(fsen.getIdentifier(),
+                                               seseLockSet);
+                               if(seseWaitingQueue.getWaitingElementSize()>0){
                                        output.println("     {");
                                        output.println("     REntry* rentry=NULL;");
                                        output.println("     INTPTR* pointer=NULL;");
                                        output.println("     seseToIssue->common.rentryIdx=0;");
-                                       for (Iterator iterator = waitingQueueSet.iterator(); iterator
+                                       
+                                       Set<Integer> queueIDSet=seseWaitingQueue.getQueueIDSet();
+                                       for (Iterator iterator = queueIDSet.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();
-                                                       // decide whether waiting element is dynamic or
-                                                       // static
-                                                       if(fsen.getDynamicInVarSet().contains(td)){
-                                                               // dynamic in-var case
-                                                               output.println("     pointer=seseToIssue->"+ waitingElement.getDynID()+"_srcSESE+seseToIssue->"+ waitingElement.getDynID()+"_srcOffset;");
-                                                               output.println("     rentry=mlpCreateFineREntry("
+                                               Integer key = (Integer) iterator.next();
+                                               int queueID=key.intValue();
+                                               Set<WaitingElement> waitingQueueSet =  seseWaitingQueue.getWaitingElementSet(queueID);
+                                               int enqueueType=seseWaitingQueue.getType(queueID);
+                                               if(enqueueType==SESEWaitingQueue.EXCEPTION){
+                                                       output.println("     INITIALIZEBUF(parentCommon->memoryQueueArray["
+                                                                               + queueID+ "]);");
+                                               }
+                                               for (Iterator iterator2 = waitingQueueSet.iterator(); iterator2
+                                                               .hasNext();) {
+                                                       WaitingElement waitingElement = (WaitingElement) iterator2
+                                                                       .next();
+                                                       if (waitingElement.getStatus() >= ConflictNode.COARSE) {
+                                                               output.println("     rentry=mlpCreateREntry("
                                                                                + waitingElement.getStatus()
-                                                                               + ", seseToIssue,  pointer );");
-//                                                             output.println("     rentry=mlpCreateFineREntry("
-//                                                                             + waitingElement.getStatus()
-//                                                                             + ", seseToIssue, seseToIssue->"
-//                                                                             + waitingElement.getDynID() + "->oid);");
-                                                       }else if(fsen.getStaticInVarSet().contains(td)){
-                                                               // static in-var case
-                                                               VariableSourceToken vst = fsen.getStaticInVarSrc(td);
-                                                               if (vst != null) {
-                                                                       
-                                                                       String srcId = "SESE_"
-                                                                                       + vst.getSESE()
-                                                                                                       .getPrettyIdentifier()
-                                                                                       + vst.getSESE().getIdentifier()
-                                                                                       + "_" + vst.getAge();
-                                                                       output
-                                                                       .println("     pointer=(void*)&seseToIssue->"
-                                                                                       + srcId
-                                                                                       + "->"
+                                                                               + ", seseToIssue);");
+                                                       } else {
+                                                               TempDescriptor td = waitingElement
+                                                                               .getTempDesc();
+                                                               // decide whether waiting element is dynamic or
+                                                               // static
+                                                               if (fsen.getDynamicInVarSet().contains(td)) {
+                                                                       // dynamic in-var case
+                                                                       output.println("     pointer=seseToIssue->"
+                                                                                       + waitingElement.getDynID()
+                                                                                       + "_srcSESE+seseToIssue->"
                                                                                        + waitingElement.getDynID()
-                                                                                       + ";");
-                                                                       output.println("     rentry=mlpCreateFineREntry("
-                                                                                       + waitingElement.getStatus()
-                                                                                       + ", seseToIssue,  pointer );");                
-                                                                       
-//                                                                     output.println("     rentry=mlpCreateFineREntry("
-//                                                                                     + waitingElement.getStatus()
-//                                                                                     + ", seseToIssue, seseToIssue->"
-//                                                                                     + waitingElement.getDynID() + "->oid);");
+                                                                                       + "_srcOffset;");
+                                                                       output
+                                                                                       .println("     rentry=mlpCreateFineREntry("
+                                                                                                       + waitingElement
+                                                                                                                       .getStatus()
+                                                                                                       + ", seseToIssue,  pointer );");
+                                                               } else if (fsen.getStaticInVarSet()
+                                                                               .contains(td)) {
+                                                                       // static in-var case
+                                                                       VariableSourceToken vst = fsen
+                                                                                       .getStaticInVarSrc(td);
+                                                                       if (vst != null) {
+
+                                                                               String srcId = "SESE_"
+                                                                                               + vst.getSESE()
+                                                                                                               .getPrettyIdentifier()
+                                                                                               + vst.getSESE().getIdentifier()
+                                                                                               + "_" + vst.getAge();
+                                                                               output
+                                                                                               .println("     pointer=(void*)&seseToIssue->"
+                                                                                                               + srcId
+                                                                                                               + "->"
+                                                                                                               + waitingElement
+                                                                                                                               .getDynID()
+                                                                                                               + ";");
+                                                                               output
+                                                                                               .println("     rentry=mlpCreateFineREntry("
+                                                                                                               + waitingElement
+                                                                                                                               .getStatus()
+                                                                                                               + ", seseToIssue,  pointer );");
+
+                                                                       }
+                                                               } else {
+                                                                       output
+                                                                                       .println("     rentry=mlpCreateFineREntry("
+                                                                                                       + waitingElement
+                                                                                                                       .getStatus()
+                                                                                                       + ", seseToIssue,  (void*)&seseToIssue->"
+                                                                                                       + waitingElement.getDynID()
+                                                                                                       + ");");
                                                                }
-                                                       }else{
-                                                               output.println("     rentry=mlpCreateFineREntry("
-                                                                               + waitingElement.getStatus()
-                                                                               + ", seseToIssue,  (void*)&seseToIssue->"
-                                                                               + waitingElement.getDynID() + ");");
-//                                                             output.println("     rentry=mlpCreateFineREntry("
-//                                                                             + waitingElement.getStatus()
-//                                                                             + ", seseToIssue, seseToIssue->"
-//                                                                             + waitingElement.getDynID() + "->oid);");
                                                        }
-                                               }
-                                               output
-                                                               .println("     rentry->queue=parentCommon->memoryQueueArray["
-                                                                               + waitingElement.getQueueID() + "];");
-                                               output
+                                                       output
+                                                                       .println("     rentry->queue=parentCommon->memoryQueueArray["
+                                                                                       + waitingElement.getQueueID()
+                                                                                       + "];");
+                                                       
+                                                       if(enqueueType==SESEWaitingQueue.NORMAL){
+                                                               output
                                                                .println("     seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;");
-                                               output
-                                                               .println("     if(ADDRENTRY(parentCommon->memoryQueueArray["
+                                                               output
+                                                                               .println("     if(ADDRENTRY(parentCommon->memoryQueueArray["
+                                                                                               + waitingElement.getQueueID()
+                                                                                               + "],rentry)==NOTREADY){");
+                                                               output.println("        ++(localCount);");
+                                                               output.println("     } ");
+                                                       }else{
+                                                               output
+                                                               .println("     ADDRENTRYTOBUF(parentCommon->memoryQueueArray["
                                                                                + waitingElement.getQueueID()
-                                                                               + "],rentry)==NOTREADY){");
-                                               output.println("        ++(localCount);");
-                                               output.println("     } ");
-                                               output.println();
+                                                                               + "],rentry);");
+                                                       }
+                                               }
+                                               if(enqueueType!=SESEWaitingQueue.NORMAL){
+                                                       output.println("     localCount+=RESOLVEBUF(parentCommon->memoryQueueArray["
+                                                                               + queueID+ "],&seseToIssue->common);");
+                                               }                               
                                        }
                                        output.println("     }");
                                }
                                output.println();
                        }
-      
       ////////////////
-                       
     }
     
     // release this SESE for siblings to update its dependencies or,
index 7302fc7bf50597725526ad0dbaf2625d947945f0..0550297d13358a01ef274a54bf6b2f52fabfa57e 100644 (file)
@@ -398,7 +398,7 @@ READBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) {
 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) { 
+  if (readbintail->item.status==READY) { 
     status=READY;
     retval=READY;
     if (isParent(r)) {
@@ -776,9 +776,133 @@ resolveDependencies(REntry* rentry){
   }
 }
 
+void INITIALIZEBUF(MemoryQueue * q){  
+  int i=0;
+  for(i=0; i<NUMBINS; i++){
+    q->binbuf[i]=NULL;
+  }
+  q->bufcount=0;
+}
+
+void ADDRENTRYTOBUF(MemoryQueue * q, REntry * r){
+  q->buf[q->bufcount]=r;
+  q->bufcount++;
+}
+
+int RESOLVEBUFFORHASHTABLE(MemoryQueue * q, Hashtable* table, SESEcommon *seseCommon){  
+  int i;
+ // first phase: only consider write rentry
+  for(i=0; i<q->bufcount;i++){
+    REntry *r=q->buf[i];
+    if(r->type==WRITE){
+      int key=generateKey(r->oid);
+      if(q->binbuf[key]==NULL){
+       // for multiple writes, add only the first write that hashes to the same bin
+       q->binbuf[key]=r;  
+      }else{
+       q->buf[i]=NULL;
+      }
+    }
+  }
+  // second phase: enqueue read items if it is eligible
+  for(i=0; i<q->bufcount;i++){
+    REntry *r=q->buf[i];    
+    if(r!=NULL && r->type==READ){
+      int key=generateKey(r->oid);
+      if(q->binbuf[key]==NULL){
+       // read item that hashes to the bin which doen't contain any write
+       seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
+       if(ADDTABLEITEM(table, r, FALSE)==READY){
+         resolveDependencies(r);
+       }
+      }
+      q->buf[i]=NULL;
+    }
+  }
+  
+  // then, add only one of write items that hashes to the same bin
+  for(i=0; i<q->bufcount;i++){
+    REntry *r=q->buf[i];   
+    if(r!=NULL){
+      seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
+      if(ADDTABLEITEM(table, r, FALSE)==READY){
+       resolveDependencies(r);
+      }      
+    }
+  }
+}
+
+int RESOLVEBUF(MemoryQueue * q, SESEcommon *seseCommon){
+  int localCount=0;
+  int i;
+  // check if every waiting entry is resolved
+  // if not, defer every items for hashtable until it is resolved.
+  int unresolved=FALSE;
+  for(i=0; i<q->bufcount;i++){
+     REntry *r=q->buf[i];
+     if(*(r->pointer)==0){
+       unresolved=TRUE;
+     }
+  }
+  if(unresolved==TRUE){
+    for(i=0; i<q->bufcount;i++){
+      REntry *r=q->buf[i];
+      r->queue=q;
+      r->isBufMode=TRUE;
+      if(ADDRENTRY(q,r)==NOTREADY){
+       localCount++;
+      }
+    }
+    return localCount;
+  }
+
+  // first phase: only consider write rentry
+  for(i=0; i<q->bufcount;i++){
+    REntry *r=q->buf[i];
+    if(r->type==WRITE){
+      int key=generateKey(r->oid);
+      if(q->binbuf[key]==NULL){
+       // for multiple writes, add only the first write that hashes to the same bin
+       q->binbuf[key]=r;  
+      }else{
+       q->buf[i]=NULL;
+      }
+    }
+  }
+  // second phase: enqueue read items if it is eligible
+  for(i=0; i<q->bufcount;i++){
+    REntry *r=q->buf[i];    
+    if(r!=NULL && r->type==READ){
+      int key=generateKey(r->oid);
+      if(q->binbuf[key]==NULL){
+       // read item that hashes to the bin which doen't contain any write
+       seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
+       if(ADDRENTRY(q,r)==NOTREADY){
+         localCount++;
+       }
+      }
+      q->buf[i]=NULL;
+    }
+  }
+  
+  // then, add only one of write items that hashes to the same bin
+  for(i=0; i<q->bufcount;i++){
+    REntry *r=q->buf[i];   
+    if(r!=NULL){
+      seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
+      if(ADDRENTRY(q,r)==NOTREADY){
+       localCount++;
+      }
+    }
+  }
+  return localCount;
+}
+
+
 resolvePointer(REntry* rentry){  
  
   Hashtable* table=rentry->hashtable;
+  MemoryQueue* queue;
   if(table==NULL){
     //resolved already before related rentry is enqueued to the waiting queue
     return;
@@ -791,6 +915,7 @@ resolvePointer(REntry* rentry){
   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
+    INTPTR currentSESE=0;
     do{
       struct QueueItem* head=getHead(val);
       if(head!=NULL){
@@ -804,8 +929,32 @@ resolvePointer(REntry* rentry){
        //now, address is resolved. update OID field.
        struct ___Object___ * obj=(struct ___Object___*)((unsigned INTPTR)*rentry->pointer);
        rentry->oid=obj->oid;
-       if(ADDTABLEITEM(table, rentry, FALSE)==READY){
-         resolveDependencies(rentry);
+       
+       //check if rentry is buffer mode
+       if(rentry->isBufMode==TRUE){
+         if(currentSESE==0){
+           queue=rentry->queue;
+           INITIALIZEBUF(queue);
+           currentSESE=(INTPTR)rentry;
+           ADDRENTRYTOBUF(queue,rentry);
+         } else if(currentSESE==(INTPTR)rentry){
+           ADDRENTRYTOBUF(queue,rentry);
+         } else if(currentSESE!=(INTPTR)rentry){
+           RESOLVEBUFFORHASHTABLE(queue,table,(SESEcommon*)rentry->seseRec);
+           currentSESE=(INTPTR)rentry;
+           INITIALIZEBUF(queue);
+           ADDRENTRYTOBUF(rentry->queue,rentry);
+         }
+       }else{
+         if(currentSESE!=0){ 
+           //previous SESE has buf mode, need to invoke resolve buffer
+           RESOLVEBUFFORHASHTABLE(queue,table,(SESEcommon*)rentry->seseRec);
+           currentSESE=0;
+         }
+         //normal mode
+         if(ADDTABLEITEM(table, rentry, FALSE)==READY){
+           resolveDependencies(rentry);
+         }
        }
       }else{
        table->unresolvedQueue=NULL; // set hashtable as normal-mode.
index e415fce3c6ae331feb121aecf3aa3ae3b7f081d8..148f8594cae05960e5c48015d054917ad5c83e4e 100644 (file)
@@ -59,18 +59,22 @@ typedef struct REntry_t{
   void* seseRec;
   INTPTR* pointer;
   int oid;
+  int isBufMode;
 } REntry;
 
 typedef struct MemoryQueueItem_t {
   int type; // hashtable:0, vector:1, singleitem:2
   int total;        //total non-retired
   int status;       //NOTREADY, READY
-  struct MemoryQueueItem_t *next;
+  struct MemoryQueueItem_t *next; 
 } MemoryQueueItem;
 
 typedef struct MemoryQueue_t {
   MemoryQueueItem * head;
   MemoryQueueItem * tail;  
+  REntry * binbuf[NUMBINS];
+  REntry * buf[NUMRENTRY];
+  int bufcount;
 } MemoryQueue;
 
 typedef struct BinItem_t {