initial commit of new memory queue. still just working with fine-grain cases.
authoryeom <yeom>
Thu, 4 Mar 2010 23:15:33 +0000 (23:15 +0000)
committeryeom <yeom>
Thu, 4 Mar 2010 23:15:33 +0000 (23:15 +0000)
Robust/src/Analysis/MLP/ConflictGraph.java
Robust/src/Analysis/MLP/WaitingElement.java
Robust/src/IR/Flat/BuildCode.java
Robust/src/Runtime/mlp_lock.h
Robust/src/Runtime/mlp_runtime.c
Robust/src/Runtime/mlp_runtime.h

index f9e06beb9bbfe6d24ecddf8ea496bc1871a4a904..b6bce6265d5bd2d01c749e124ead5a11a4eaca88 100644 (file)
@@ -718,6 +718,8 @@ public class ConflictGraph {
                HashSet<WaitingElement> waitingElementSet = new HashSet<WaitingElement>();
                Set<Entry<String, ConflictNode>> s = id2cn.entrySet();
                Collection<StallSite> stallSites = conflictsMap.getStallMap().values();
+               
+               String dynID="";
 
                for (Iterator iterator = stallSites.iterator(); iterator.hasNext();) {
 
@@ -758,11 +760,13 @@ public class ConflictGraph {
                                                                                                                                                                                                // edge
                                                                allocSet.addAll(getAllocSet(node));
                                                                if (isReadOnly(node)) {
-                                                                       // fine-grain read
-                                                                       type = 0;
+                                                                       // parent fine-grain read
+                                                                       type = 2;
+                                                                       dynID=node.getTempDescriptor().toString();
                                                                } else {
-                                                                       // fine-grain write
-                                                                       type = 1;
+                                                                       // parent fine-grain write
+                                                                       type = 3;
+                                                                       dynID=node.getTempDescriptor().toString();
                                                                }
                                                        }
 
@@ -773,6 +777,7 @@ public class ConflictGraph {
                                                                        if (seseLock
                                                                                        .containsConflictNode(stallSiteNode)) {
                                                                                WaitingElement newElement = new WaitingElement();
+                                                                               newElement.setDynID(dynID);
                                                                                newElement.setAllocList(allocSet);
                                                                                newElement.setWaitingID(seseLock
                                                                                                .getID());
index 7524285af2dc14d89f3127d8ad8738964528ed07..76e07e0fcbbb276fb2ac75862e468d949fe5891b 100644 (file)
@@ -36,7 +36,7 @@ public class WaitingElement {
                this.dynID=dynID;
        }
        
-       public int getWaitingID() {
+       public int getQueueID() {
                return waitingID;
        }
 
@@ -68,7 +68,7 @@ public class WaitingElement {
 
                WaitingElement in = (WaitingElement) o;
 
-               if (waitingID == in.getWaitingID() && status == in.getStatus()
+               if (waitingID == in.getQueueID() && status == in.getStatus()
                                && allocList.equals(in.getAllocList())) {
                        return true;
                } else {
index 182a9aa24e91b9984e57c5f4724fae24e7afe61e..d47d5c79196fae33163d916f3768fd3168d7e7fd 100644 (file)
@@ -1772,28 +1772,24 @@ public class BuildCode {
       
       // set up related allocation sites's waiting queues
       // eom
-      output.println("   /* set up waiting queues */");
-      output.println("   int numRelatedWaitingQueue=0;");
-      output.println("   int waitingQueueItemID=0;");
-      ConflictGraph graph=null;
-      graph=mlpa.getConflictGraphResults().get(fm);
-      if(graph!=null){
-         HashSet<SESELock> lockSet=mlpa.getConflictGraphLockMap().get(graph);
-         
-         if(lockSet.size()>0){
-                 output.println("   numRelatedWaitingQueue="+lockSet.size()+";");      
-                 output.println("   seseCaller->numRelatedWaitingQueue=numRelatedWaitingQueue;");
-                 output.println("   seseCaller->allocSiteArray=mlpCreateAllocSiteArray(numRelatedWaitingQueue);");
-                 int idx=0;
-                 for (Iterator iterator = lockSet.iterator(); iterator.hasNext();) {
-                       SESELock seseLock = (SESELock) iterator.next();
-                       output.println("   seseCaller->allocSiteArray["+idx+"].id="+seseLock.getID()+";");
-                       idx++;
-                 }
-                 output.println();
-         }
-      }
-      
+               output.println("   /* set up waiting queues */");
+               output.println("   int numMemoryQueue=0;");
+               output.println("   int memoryQueueItemID=0;");
+               ConflictGraph graph = null;
+               graph = mlpa.getConflictGraphResults().get(fm);
+               if (graph != null) {
+                       HashSet<SESELock> lockSet = mlpa.getConflictGraphLockMap().get(
+                                       graph);
+       
+                       if (lockSet.size() > 0) {
+                               output.println("   numMemoryQueue=" + lockSet.size() + ";");
+                               output
+                                               .println("   seseCaller->numMemoryQueue=numMemoryQueue;");
+                               output
+                                               .println("   seseCaller->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);");
+                               output.println();
+                       }
+               }
     }
 
 
@@ -2071,37 +2067,32 @@ public class BuildCode {
       }
     }    
     
-    // set up related allocation sites's waiting queues
+    // setup memory queue
     // eom
-    output.println("   /* set up waiting queues */");
-    output.println("   int numRelatedWaitingQueue=0;");
-    output.println("   int waitingQueueItemID=0;");
-    ConflictGraph graph=null;
-    graph=mlpa.getConflictGraphResults().get(fsen);
+    output.println("   // set up memory queues ");
+       output.println("   int numMemoryQueue=0;");
+       output.println("   int memoryQueueItemID=0;");
+       ConflictGraph graph = null;
+       graph = mlpa.getConflictGraphResults().get(fsen);
        if (graph != null) {
                output.println("   {");
-               output.println("   SESEcommon* parentCommon = &(___params___->common);");
-               HashSet<SESELock> lockSet=mlpa.getConflictGraphLockMap().get(graph);
-                 
+               output
+                               .println("   SESEcommon* parentCommon = &(___params___->common);");
+               HashSet<SESELock> lockSet = mlpa.getConflictGraphLockMap().get(
+                               graph);
+
                if (lockSet.size() > 0) {
-                       output.println("   numRelatedWaitingQueue=" + lockSet.size()
-                                       + ";");
+                       output.println("   numMemoryQueue=" + lockSet.size() + ";");
                        output
-                                       .println("   parentCommon->numRelatedWaitingQueue=numRelatedWaitingQueue;");
+                                       .println("   parentCommon->numMemoryQueue=numMemoryQueue;");
                        output
-                                       .println("   parentCommon->allocSiteArray=mlpCreateAllocSiteArray(numRelatedWaitingQueue);");
-                       int idx = 0;
-                       for (Iterator iterator = lockSet.iterator(); iterator.hasNext();) {
-                               SESELock seseLock = (SESELock) iterator.next();
-                               output.println("   parentCommon->allocSiteArray[" + idx
-                                               + "].id=" + seseLock.getID() + ";");
-                               idx++;
-                       }
+                                       .println("   parentCommon->memoryQueueArray=mlpCreateMemoryQueueArray(numMemoryQueue);");
                        output.println();
                }
                output.println("   }");
        }
 
+
     // copy in-set into place, ready vars were already 
     // copied when the SESE was issued
     Iterator<TempDescriptor> tempItr;
@@ -2713,72 +2704,46 @@ public class BuildCode {
           output.println("   "+dynVar+"_srcSESE = NULL;");
        }
        
-        // eom
+       // eom
     // handling stall site
-    
-    ParentChildConflictsMap conflictsMap=mlpa.getConflictsResults().get(fn);
-    
+       ParentChildConflictsMap conflictsMap = mlpa.getConflictsResults().get(fn);
        if (conflictsMap != null) {
-
-               Set<Long> allocSet = conflictsMap
-                               .getAllocationSiteIDSetofStallSite();
-               
+               Set<Long> allocSet = conflictsMap.getAllocationSiteIDSetofStallSite();
                if (allocSet.size() > 0) {
-                       
                        FlatNode enclosingFlatNode=null;
                        if( currentSESE.getIsCallerSESEplaceholder() && currentSESE.getParent()==null){
                                enclosingFlatNode=currentSESE.getfmEnclosing();
                        }else{
                                enclosingFlatNode=currentSESE;
-                       }
-                       
+                       }                                               
                        ConflictGraph graph=mlpa.getConflictGraphResults().get(enclosingFlatNode);
                        HashSet<SESELock> seseLockSet=mlpa.getConflictGraphLockMap().get(graph);
                        Set<WaitingElement> waitingElementSet=graph.getStallSiteWaitingElementSet(conflictsMap, seseLockSet);
-
+                       
                        if(waitingElementSet.size()>0){
-                               output.println("   /*  stall on parent's stall sites */");
-                               output.println("  {");
+                               output.println("// stall on parent's stall sites ");
+                               output.println("   {");
+                               output.println("     REntry* rentry;");
                                output.println("     pthread_mutex_lock( &(seseCaller->lock) );");
-                               output.println("     ConflictNode* node;");
-                               output.println("     struct Queue* list=NULL;");
-                               output.println("     WaitingElement* newElement=NULL;");
-                               output.println("     struct QueueItem* newQItem=NULL;");
-                               output.println("     waitingQueueItemID++;");
-//                             output.println("     psem_init( &(seseCaller->memoryStallSiteSem) );");
-                           output.println("     pthread_cond_init( &(seseCaller->stallDone), NULL );");
-//                             output.println("     psem_init( &(seseCaller->memoryStallSiteSem) );");
-                               output.println("     int qIdx;");
-                               output.println("     int takeCount=0;");
+                               
                                for (Iterator iterator = waitingElementSet.iterator(); iterator.hasNext();) {
                                        WaitingElement waitingElement = (WaitingElement) iterator.next();
                                        
-                                       output.println("     qIdx=getQueueIdx(seseCaller->allocSiteArray,numRelatedWaitingQueue,"
-                                                                       + waitingElement.getWaitingID() + ");");
-                                       output.println("     if(qIdx!=-1 && !isEmpty(seseCaller->allocSiteArray[qIdx].waitingQueue)){");
-                                       output.println("     list=createQueue();");
-                                       for (Iterator iterator2 = waitingElement.getAllocList().iterator(); iterator2.hasNext();) {
-                                               Integer allocID = (Integer) iterator2   .next();
-                                               output.println("     node=mlpCreateConflictNode( "+ allocID + " );");
-                                               output.println("     addNewItem(list,node);");
-                                       }
-                                       output.println("     newElement=mlpCreateWaitingElement( "+ waitingElement.getStatus()
-                                                       + ", seseCaller, list, waitingQueueItemID );");
-                                       output.println("        addNewItemBack(seseCaller->allocSiteArray[qIdx].waitingQueue,newElement);");
-                                       output.println("        takeCount++;");
-                                       output.println("     }");
+                                       output.println("     rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", seseCaller,  ___locals___."+ waitingElement.getDynID() + ");");
+                                       output.println("     pthread_cond_init( &(rentry->stallDone), NULL );");
+                                       output.println("     rentry->queue=seseCaller->memoryQueueArray["+ waitingElement.getQueueID()+ "];");
+                                       output
+                                                       .println("     if(ADDRENTRY(seseCaller->memoryQueueArray["+ waitingElement.getQueueID()
+                                                                       + "],rentry)==NOTREADY){");
+                                       output.println("        pthread_cond_wait( &(rentry->stallDone), &(seseCaller->lock) );");                                                              
+                                       output.println("     }  ");
                                }
-                               output.println("     if( takeCount>0 ){");
-//                             output.println("        psem_take( &(seseCaller->memoryStallSiteSem) );");
-                           output.println("        pthread_cond_wait( &(seseCaller->stallDone), &(seseCaller->lock) );");
-                               output.println("     }");
-                               
                                output.println("     pthread_mutex_unlock( &(seseCaller->lock) );");
-                               output.println("  }");
+                               output.println("   }");
                        }
-
                }
-       } // end of if (conflictsMap != null) {         
+       }       
+
       }     
     }
 
@@ -3383,64 +3348,50 @@ public class BuildCode {
     
     // 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) {
-                       
-                       HashSet<SESELock> seseLockSet=mlpa.getConflictGraphLockMap().get(graph);
-                       
-                       output.println();
-                       output.println("     /*add waiting queue element*/");
-                       Set<WaitingElement> waitingQueueSet=graph.getWaitingElementSetBySESEID(fsen
-                                       .getIdentifier(),seseLockSet);
-                       if (waitingQueueSet.size() > 0) {
-                               output.println("     {");
-                               output.println("     waitingQueueItemID++;");
-                               output.println("     ConflictNode* node;");
-                               output.println("     WaitingElement* newElement=NULL;");
-                               output.println("     struct Queue* list=NULL;");
-                               output.println("     struct QueueItem* newQItem=NULL;");
-                               output.println("     pthread_mutex_lock( &(parentCommon->lock) );");
-                               for (Iterator iterator = waitingQueueSet.iterator(); iterator
-                                               .hasNext();) {
-                                       WaitingElement waitingElement = (WaitingElement) iterator.next();
-                                       output.println("     list=createQueue();");
-                                       for (Iterator iterator2 = waitingElement.getAllocList().iterator(); iterator2
-                                                       .hasNext();) {
-                                               Integer allocID = (Integer) iterator2
-                                                               .next();
-                                               output.println("     node=mlpCreateConflictNode( "+allocID+" );");
-                                               output.println("     addNewItem(list,node);");
-                                       }
-                                       output.println("     seseToIssue->common.waitingQueueItemID=waitingQueueItemID;");
-                                       output.println("     newElement=mlpCreateWaitingElement( "+waitingElement.getStatus()+", seseToIssue, list, waitingQueueItemID );");
-                                       
-                                       output
-                                                       .println("     if(addWaitingQueueElement(parentCommon->allocSiteArray,numRelatedWaitingQueue,"
-                                                                       + waitingElement.getWaitingID() + ",newElement)){");
-                                       output.println("     ++(localCount);");
-                                       output.println("     } ");
-
-                                       output
-                                       .println();
-                               }
-                               output.println("     pthread_mutex_unlock( &(parentCommon->lock) );");
-                               output.println("     }");
+       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) {
+               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;");
+                       output
+                                       .println("     pthread_mutex_lock( &(parentCommon->lock) );");
+                       for (Iterator iterator = waitingQueueSet.iterator(); iterator
+                                       .hasNext();) {
+                               WaitingElement waitingElement = (WaitingElement) iterator
+                                               .next();
+                               output.println("     rentry=mlpCreateREntry("+ 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("     pthread_mutex_unlock( &(parentCommon->lock) );");
+                       output.println("     }");
                }
-
-    // eom
-//    output.println("     pthread_mutex_init( &(seseToIssue->common.waitingQueueLock), NULL );");
-    //
+               output.println();
+       }    
     
     if( fsen != mlpa.getMainSESE() ) {
       // count up outstanding dependencies, static first, then dynamic
@@ -3648,90 +3599,20 @@ public class BuildCode {
     // clean up its lock element from waiting queue, and decrement dependency count for next SESE block
     if( fsen != mlpa.getMainSESE() ) {
        
-       output.println();    
-        output.println("   /* check memory dependency*/");
-       output.println("  {");
-       output.println("   pthread_mutex_lock( &(___params___->common.parent->lock) );");
-//     output.println("   pthread_mutex_lock( &(___params___->common.parent->waitingQueueLock) );");
-       output.println("   int idx;");
-       output.println("   int giveCount=0;");
-       output.println("   struct Queue* launchQueue=createQueue();");
-       output.println("   struct QueueItem* nextQueueItem;");
-       output.println("   for(idx = 0 ; idx < ___params___->common.parent->numRelatedWaitingQueue ; idx++){");
-       output.println("     if(!isEmpty(___params___->common.parent->allocSiteArray[idx].waitingQueue)){");
-       output.println("        struct QueueItem* qItem=getHead(___params___->common.parent->allocSiteArray[idx].waitingQueue);");
-       output.println("        int removed=0;");
-       output.println("        while(qItem!=NULL){");
-       output.println("           WaitingElement* item=qItem->objectptr;");
-       output.println("           SESEcommon* seseItem=(SESEcommon*)item->seseRec;");
-       output.println("           if(seseItem->classID==___params___->common.classID && item->id==___params___->common.waitingQueueItemID){");
-       output.println("              struct QueueItem* nItem=getNextQueueItem(qItem);");
-       output.println("              removeItem(___params___->common.parent->allocSiteArray[idx].waitingQueue,qItem);");
-       output.println("              removed=1;");
-               output.println("              qItem=nItem;");
-       output.println("           }else if(removed){");
-       output.println("              qItem=NULL;");
-       output.println("           }else{");
-       output.println("              qItem=getNextQueueItem(qItem);");
-       output.println("           }");
-       output.println("        }");
-       output.println("        if( !isEmpty(___params___->common.parent->allocSiteArray[idx].waitingQueue) ){");
-       
-       output.println("           struct QueueItem* nextQItem=getHead(___params___->common.parent->allocSiteArray[idx].waitingQueue);");
-       output.println("           while(nextQItem!=NULL){");
-       output.println("              WaitingElement* nextItem=nextQItem->objectptr;");
-       output.println("              SESEcommon* seseNextItem=(SESEcommon*)nextItem->seseRec;");
-       output.println("              if(nextItem->resolved==0){");
-       
-       output.println("              int isResolved=isRunnable(___params___->common.parent->allocSiteArray[idx].waitingQueue,nextQItem);");
-       output.println("              if(seseNextItem->classID==___params___->common.parent->classID){"); // stall site
-       output.println("                 if(isResolved){");
-       output.println("                    struct QueueItem* stallItem=findItem(___params___->common.parent->allocSiteArray[idx].waitingQueue,nextItem);");
-       output.println("                    removeItem(___params___->common.parent->allocSiteArray[idx].waitingQueue,stallItem);");
-       output.println("                    giveCount++;");
-       output.println("                 }");
-       output.println("                 if(!isEmpty(___params___->common.parent->allocSiteArray[idx].waitingQueue)){");
-       output.println("                    nextQItem=getNextQueueItem(nextQItem);");
-       output.println("                 }else{");
-       output.println("                    nextQItem=NULL;");
-       output.println("                 }");
-       output.println("              }else{");
-       output.println("                 if(isResolved){");
-       //output.println("                    struct QueueItem* currentItem=findItem(___params___->common.parent->allocSiteArray[idx].waitingQueue,nextItem);");
-       //output.println("                    nextQItem=getNextQueueItem(currentItem);");
-       //output.println("                    removeItem(___params___->common.parent->allocSiteArray[idx].waitingQueue,currentItem);");
-       output.println("                       nextItem->resolved=1;");
-       output.println("                       if( atomic_sub_and_test(1, &(seseNextItem->unresolvedDependencies)) ){");
-       output.println("                            addNewItem(launchQueue,(void*)seseNextItem);");
-       output.println("                       }");
-       output.println("                 }else{");
-       output.println("                    nextQItem=getNextQueueItem(nextQItem);");
-       output.println("                 }");
-       output.println("               }");
-       
-       output.println("              }else{");
-       output.println("                 nextQItem=getNextQueueItem(nextQItem);");
-       output.println("              }");
-       
-       output.println("           } "); // end of while(nextQItem!=NULL)
-       output.println("        }");
-       output.println("     }");
-//     output.println("  }");
-       output.println("  }");
-       output.println("  pthread_mutex_unlock( &(___params___->common.parent->lock)  );");
-       output.println("  if(!isEmpty(launchQueue)){");
-       output.println("     struct QueueItem* qItem=getHead(launchQueue);");
-       output.println("     while(qItem!=NULL){");
-       output.println("        workScheduleSubmit(qItem->objectptr);");
-       output.println("        qItem=getNextQueueItem(qItem);");
-       output.println("     }");
-       output.println("  }");
-       output.println("  if(giveCount>0){");
-//             output.println("    psem_give(&(___params___->common.parent->memoryStallSiteSem));");
-       output.println("    pthread_cond_signal(&(___params___->common.parent->stallDone));");
-       output.println("  }");
-       output.println("  }");
-       
+               output.println();
+               output.println("   /* check memory dependency*/");
+               output.println("  {");                  
+               output
+                               .println("      pthread_mutex_lock( &(___params___->common.parent->lock) );");
+               output.println("      int idx;");
+               output.println("      for(idx=0;idx<___params___->common.rentryIdx;idx++){");
+               output.println("           REntry* re=___params___->common.rentryArray[idx];");
+               output.println("           RETIRERENTRY(re->queue,re);");
+               output.println("      }");
+               output
+                               .println("      pthread_mutex_unlock( &(___params___->common.parent->lock)  );");
+               output.println("   }");
+               
     }
     
     // if parent is stalling on you, let them know you're done
index 18bcf4d5b18126ad5e3afe8d05c06dc068bacb33..6086ffc4a965b04620d27a1b9ae75f0438654d8c 100644 (file)
@@ -1,3 +1,12 @@
+#include "runtime.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+
+#define CFENCE   asm volatile("":::"memory");
+
 #define LOCK_PREFIX \
   ".section .smp_locks,\"a\"\n"   \
   "  .align 4\n"                  \
@@ -24,3 +33,40 @@ static inline int atomic_sub_and_test(int i, volatile int *v) {
                         : "ir" (i) : "memory");
   return c;
 }
+
+static inline int LOCKXCHG(volatile int* ptr, int val){
+  
+  int retval;
+  //note: xchgl always implies lock 
+  __asm__ __volatile__("xchgl %0,%1"
+                      : "=r"(retval)
+                      : "m"(*ptr), "0"(val)
+                      : "memory");
+  return retval;
+}
+
+/*
+static inline int write_trylock(volatile int *lock) {
+  int retval=0;
+  __asm__ __volatile__("xchgl %0,%1"
+                      : "=r"(retval)
+                      : "m"(*lock), "0"(retval)
+                      : "memory");
+  return retval;
+}
+*/
+
+static inline int CAS(volatile int* mem, int cmp, int val){
+  int prev;
+  asm volatile ("lock; cmpxchgl %1, %2"             
+               : "=a" (prev)               
+               : "r" (val), "m" (*(mem)), "0"(cmp) 
+               : "memory", "cc");
+  return prev;
+}
+
+static inline int BARRIER(){
+  CFENCE;
+  return 1;
+}
index fb52b53405d1efa6f2fc73090c1172a61b68000f..69581bf3d451379112b3d5e6206c8aaa4c715a54 100644 (file)
@@ -5,7 +5,6 @@
 #include <assert.h>
 
 #include "mem.h"
-#include "Queue.h"
 #include "mlp_runtime.h"
 #include "workschedule.h"
 
@@ -34,257 +33,654 @@ void mlpFreeSESErecord( void* seseRecord ) {
   RUNFREE( seseRecord );
 }
 
-AllocSite* mlpCreateAllocSiteArray(int numAllocSites){
+MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue){
   int i;
-  AllocSite* newAllocSite=(AllocSite*)RUNMALLOC( sizeof( AllocSite ) * numAllocSites );
-  for(i=0; i<numAllocSites; i++){
-    newAllocSite[i].waitingQueue=createQueue();
+  MemoryQueue** newMemoryQueue=(MemoryQueue**)RUNMALLOC( sizeof( MemoryQueue* ) * numMemoryQueue );
+  for(i=0; i<numMemoryQueue; i++){
+    newMemoryQueue[i]=createMemoryQueue();
   }
-  return newAllocSite;
+  return newMemoryQueue;
 }
 
-ConflictNode* mlpCreateConflictNode(int id){
-  ConflictNode* newConflictNode=(ConflictNode*)RUNMALLOC( sizeof( ConflictNode ) );
-  newConflictNode->id=id;
-  return newConflictNode;
+REntry* mlpCreateREntryArray(){
+  REntry* newREntryArray=(REntry*)RUNMALLOC(sizeof(REntry)*NUMRENTRY);
+  return newREntryArray;
 }
 
-WaitingElement* mlpCreateWaitingElement(int status, void* seseToIssue, struct Queue* queue, int id){
-  WaitingElement* newElement=(WaitingElement*)RUNMALLOC(sizeof(WaitingElement));
-  newElement->status=status;
-  newElement->seseRec=seseToIssue;
-  newElement->list=queue;
-  newElement->id=id;
-  return newElement;
+REntry* mlpCreateREntry(int type, void* seseToIssue, void* dynID){
+  REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry));
+  newREntry->type=type;
+  newREntry->seseRec=seseToIssue;
+  newREntry->dynID=dynID; 
+  return newREntry;
 }
 
-struct QueueItem* addWaitingQueueElement2(AllocSite* waitingQueueArray, int numWaitingQueue, int waitingID, WaitingElement* element){
+int isParent(REntry *r) {
+  if (r->type==PARENTREAD || r->type==PARENTWRITE) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
 
-  int i;
-  struct QueueItem* newItem=NULL;
-  for(i=0;i<numWaitingQueue;i++){
-    if(waitingQueueArray[i].id==waitingID){
-      newItem=addNewItemBack(waitingQueueArray[i].waitingQueue,element);
-      return newItem;
-      //printf("add new item %d into waiting queue:%d\n",((SESEcommon*)seseRec)->classID,allocID);
-    }
+int isParentCoarse(REntry *r){
+  if (r->type==PARENTCOARSE){
+    return TRUE;
+  }else{
+    return FALSE;
   }
-  return newItem;  
-  
 }
 
-int addWaitingQueueElement(AllocSite* allocSiteArray, int numAllocSites, long allocID, WaitingElement* wElement){
+int isFineRead(REntry *r) {
+  if (r->type==READ || r->type==PARENTREAD) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
 
-  int i;
-  struct QueueItem* newItem=NULL;
-  for(i=0;i<numAllocSites;i++){
-    if(allocSiteArray[i].id==allocID){
-      
-      if(isRunnableNewElement(allocSiteArray[i].waitingQueue,wElement)){
-       wElement->resolved=1;
-       addNewItemBack(allocSiteArray[i].waitingQueue,wElement);
-       return 0;
-      }else{
-       wElement->resolved=0;
-       addNewItemBack(allocSiteArray[i].waitingQueue,wElement);
-       return 1;
-      }
-    
-    }
+int isFineWrite(REntry *r) {
+  if (r->type==WRITE || r->type==PARENTWRITE) {
+    return TRUE;
+  } else {
+    return FALSE;
   }
-  return 0;
 }
 
-struct QueueItem* addWaitingQueueElement_backup(AllocSite* allocSiteArray, int numAllocSites, long allocID, void *seseRec){
+int isCoarse(REntry *r){
+  if(r->type==COARSE || r->type==PARENTCOARSE){
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
 
-  int i;
-  struct QueueItem* newItem=NULL;
-  for(i=0;i<numAllocSites;i++){
-    if(allocSiteArray[i].id==allocID){
-      newItem=addNewItemBack(allocSiteArray[i].waitingQueue,seseRec);
-      return newItem;
-      //printf("add new item %d into waiting queue:%d\n",((SESEcommon*)seseRec)->classID,allocID);
-    }
+int isSCC(REntry *r){
+  if(r->type==SCCITEM){
+    return TRUE;
+  } else {
+    return FALSE;
   }
-  return newItem;
 }
 
-int getQueueIdx(AllocSite* allocSiteArray, int numAllocSites, long  allocID){
+int isSingleItem(MemoryQueueItem *qItem){
+  if(qItem->type==SINGLEITEM){
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
 
-  int i;
-  for(i=0;i<numAllocSites;i++){
-    if(allocSiteArray[i].id==allocID){
-      return i;      
-    }
+int isHashtable(MemoryQueueItem *qItem){
+  if(qItem->type==HASHTABLE){
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+int isVector(MemoryQueueItem *qItem){
+  if(qItem->type==VECTOR){
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+int isReadBinItem(BinItem* b){
+  if(b->type==READBIN){
+    return TRUE;
+  }else{
+    return FALSE;
+  }
+}
+
+int isWriteBinItem(BinItem* b){
+  if(b->type==WRITEBIN){
+    return TRUE;
+  }else{
+    return FALSE;
   }
-  return -1;
 }
 
-int isRunnableNewElement(struct Queue* waitingQueue, WaitingElement* wItem){
+int generateKey(unsigned int data){
+  return (data&H_MASK)>> 4;
+}
+
+Hashtable* createHashtable(){
+  int i=0;
+  Hashtable* newTable=(Hashtable*)RUNMALLOC(sizeof(Hashtable));
+  //newTable->array=(BinElement*)RUNMALLOC(sizeof(BinElement)*NUMBINS);
+  for(i=0;i<NUMBINS;i++){
+    newTable->array[i]=(BinElement*)RUNMALLOC(sizeof(BinElement));
+    newTable->array[i]->head=NULL;
+    newTable->array[i]->tail=NULL;
+  }
+  return newTable;
+}
+
+WriteBinItem* createWriteBinItem(){
+  WriteBinItem* binitem=(WriteBinItem*)RUNMALLOC(sizeof(WriteBinItem));
+  binitem->item.type=WRITEBIN;
+  return binitem;
+}
+
+ReadBinItem* createReadBinItem(){
+  ReadBinItem* binitem=(ReadBinItem*)RUNMALLOC(sizeof(ReadBinItem));
+  binitem->array=(REntry*)RUNMALLOC(sizeof(REntry*)*NUMREAD);
+  binitem->index=0;
+  binitem->item.type=READBIN;
+  return binitem;
+}
+
+Vector* createVector(){
+  Vector* vector=(Vector*)RUNMALLOC(sizeof(Vector));
+  vector->array=(REntry*)RUNMALLOC(sizeof(REntry*)*NUMITEMS);
+  vector->index=0;
+  return vector;
+}
 
-  if(!isEmpty(waitingQueue)){
+SCC* createSCC(){
+  SCC* scc=(SCC*)RUNMALLOC(sizeof(SCC));
+  return scc;
+}
+
+MemoryQueue* createMemoryQueue(){
+  MemoryQueue* queue = (MemoryQueue*)RUNMALLOC(sizeof(MemoryQueue));
+
+  MemoryQueueItem* dummy=(MemoryQueueItem*)RUNMALLOC(sizeof(MemoryQueueItem));
+  dummy->type=3;
+  dummy->total=0;
+  dummy->status=READY;
+  queue->head = dummy;
+  queue->tail = dummy;
+  return queue;
+}
 
-    struct QueueItem* current=getHead(waitingQueue);
-    while(current!=NULL){
-        if(isConflicted(current,wItem)){
-          return 0;
-        }
-                current=getNextQueueItem(current);
+int ADDRENTRY(MemoryQueue * q, REntry * r) {
+  if (isFineRead(r) || isFineWrite(r)) { 
+    return ADDTABLE(q, r);
+  } else if (isCoarse(r)) {
+    return ADDVECTOR(q, r);
+  } else if (isSCC(r)) {
+    return ADDSCC(q, r);
+  }
+}
+
+int ADDTABLE(MemoryQueue *q, REntry *r) {
+  if(!isHashtable(q->tail)) {
+    //Fast Case
+    MemoryQueueItem* tail=q->tail;
+    if (isParent(r) && tail->total==0 && q->tail==q->head) {
+      return READY;
+    }
+
+    //Add table
+    Hashtable* h=createHashtable();
+    tail->next=(MemoryQueueItem*)h;
+    //************NEED memory barrier here to ensure compiler does not cache Q.tail.status********
+    if (BARRIER() && tail->status==READY && tail->total==0 && q->tail==q->head) { 
+      //previous Q item is finished
+      h->item.status=READY;
+    }
+    q->tail=(MemoryQueueItem*)h;
+  }
+
+  //at this point, have table
+  Hashtable* table=(Hashtable*)q->tail;
+  BinItem * val;
+  int key=generateKey((unsigned int)r->dynID);
+  do {  
+    val=(BinItem*)0x1;       
+    BinElement* bin=table->array[key];
+    val=(BinItem*)LOCKXCHG((unsigned int*)&(bin->head), (unsigned int)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);
+  } else {
+    if (isFineWrite(r)) {
+      WRITEBINCASE(table, r, val);
+      return NOTREADY;
+    } else if (isFineRead(r)) {
+      return READBINCASE(table, r, val);
     }
   }
-  return 1;
 }
 
-int isRunnable(struct Queue* waitingQueue, struct QueueItem* qItem){
+int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r) {
+  int retval;
+  BinItem* b;
+  if (isFineWrite(r)) {
+    b=(BinItem*)createWriteBinItem();
+    ((WriteBinItem*)b)->val=r;//<-only different statement
+  } else if (isFineRead(r)) {
+    b=(BinItem*)createReadBinItem();
+    ReadBinItem* readbin=(ReadBinItem*)b;
+    readbin->array[readbin->index++]=*r;
+  }
+  b->total=1;
+
+  if (T->item.status==READY) { 
+    //current entry is ready
+    b->status=READY;
+    retval=READY;
+    if (isParent(r)) {
+      be->head=NULL; // released lock
+      return retval;
+    }
+  } else {
+    b->status=NOTREADY;
+    retval=NOTREADY;
+  }
+
+  atomic_inc(&T->item.total);
+  r->hashtable=T;
+  r->binitem=b;
+  be->tail=b;
+  be->head=b;//released lock
+  return retval;
+}
 
-  if(!isEmpty(waitingQueue)){
+int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val) {
+  //chain of bins exists => tail is valid
+  //if there is something in front of us, then we are not ready
 
-    struct QueueItem* current=getHead(waitingQueue);
-    while(current!=NULL){
-         if(current!=qItem){
-          if(isConflicted(current,(WaitingElement*)qItem->objectptr)){
-            return 0;
-          }
-        }else{
-          return 1;
-        }
-        current=getNextQueueItem(current);
+  int key=generateKey((unsigned int)r->dynID);
+  BinElement* be=T->array[key];
+
+  BinItem *bintail=be->tail;
+  WriteBinItem *b=createWriteBinItem();
+  b->val=r;
+  b->item.total=1;
+  
+  atomic_inc(&T->item.total);
+
+  r->hashtable=T;
+  r->binitem=(BinItem*)b;
+
+  be->tail->next=(BinItem*)b;
+  be->tail=(BinItem*)b;
+  be->head=val;
+}
+
+READBINCASE(Hashtable *T, REntry *r, BinItem *val) {
+  int key=generateKey((unsigned int)r->dynID);
+  BinItem * bintail=T->array[key]->tail;
+  if (isReadBinItem(bintail)) {
+    return TAILREADCASE(T, r, val, bintail);
+  } else if (!isReadBinItem(bintail)) {
+    TAILWRITECASE(T, r, val, bintail);
+    return NOTREADY;
+  }
+}
+
+int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail) {
+  int key=generateKey((unsigned int)r->dynID);
+  ReadBinItem * readbintail=(ReadBinItem*)T->array[key]->tail;
+  int status, retval;
+  if (readbintail->item.status=READY) { 
+    status=READY;
+    retval=READY;
+    if (isParent(r)) {
+      T->array[key]->head=val;//released lock
+      return READY;
     }
+  } else {
+    status=NOTREADY;
+    retval=NOTREADY;
+  }
+
+  if (readbintail->index==NUMREAD) { // create new read group
+    ReadBinItem* rb=createReadBinItem();
+    rb->array[rb->index++]=*r;
+    rb->item.total=1;//safe only because item could not have started
+    rb->item.status=status;
+    T->array[key]->tail->next=(BinItem*)rb;
+    T->array[key]->tail=(BinItem*)rb;
+    r->binitem=(BinItem*)rb;
+  } else { // group into old tail
+    readbintail->array[readbintail->index++]=*r;
+    atomic_inc(&readbintail->item.total);
+    r->binitem=(BinItem*)readbintail;
   }
-  return 1;
+  atomic_inc(&T->item.total);
+  r->hashtable=T;
+  T->array[key]->head=val;//released lock
+  return retval;
 }
 
-int isConflicted(struct QueueItem* prevItem, WaitingElement* element){
+TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail) {
+  int key=generateKey((unsigned int)r->dynID);
+  WriteBinItem* wb=createWriteBinItem();
+  wb->val=r;
+  wb->item.total=1;
+  wb->item.status=NOTREADY;
+  //  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);
+  r->hashtable=T;
+  r->binitem=(BinItem*)wb;
+  T->array[key]->tail->next=(BinItem*)wb;
+  T->array[key]->tail=(BinItem*)wb;
+  T->array[key]->head=val;//released lock
+}
 
-  WaitingElement* prevElement=prevItem->objectptr;
+ADDVECTOR(MemoryQueue *Q, REntry *r) {
+  if(!isVector(Q->tail)) {
+    //Fast Case
+    if (isParentCoarse(r) && Q->tail->total==0 && Q->tail==Q->head) { 
+      return READY;
+    }
 
-  if(prevElement->id!=element->id){
+    //added vector
+    Vector* V=createVector();
+    Q->tail->next=(MemoryQueueItem*)V;     
+    //************NEED memory barrier here to ensure compiler does not cache Q.tail.status******
+    if (BARRIER() && Q->tail->status==READY&&Q->tail->total==0) { 
+      //previous Q item is finished
+      V->item.status=READY;
+    }
+    Q->tail=(MemoryQueueItem*)V;
+  }
+  //at this point, have vector
+  Vector* V=(Vector*)Q->tail;
+  if (V->index==NUMITEMS) {
+    //vector is full
+    //added vector
+    V=createVector();
+    V->item.status=NOTREADY;
+    Q->tail->next=(MemoryQueueItem*)V;
+    //***NEED memory barrier here to ensure compiler does not cache Q.tail.status******
+    if (BARRIER() && Q->tail->status==READY) { 
+      V->item.status=READY;
+    }
+    Q->tail=(MemoryQueueItem*)V;
+  }
 
-    if(element->status==0){ // fine read
-    
-      if(prevElement->status==1 || prevElement->status==3){
-      
-       if(isOverlapped(prevElement->list,element->list)){
-         return 1;
-       }
-      
-      }else{
-       return 0;
-      }
-        
-    }else if(element->status==1){ // fine write
-      if(isOverlapped(prevElement->list,element->list)){
-       return 1;
-      }
-    }else if(element->status==2){// coarse read
-      
-      if(prevElement->status==1 || prevElement->status==3){
-       if(isOverlapped(prevElement->list,element->list)){
-         return 1;
-       }
+  atomic_inc(&V->item.total);
+  //expose entry
+  int index=V->index;
+  V->array[index]=*r;
+  //*****NEED memory barrier here to ensure compiler does not reorder writes to V.array and V.index
+  BARRIER();
+  V->index++;
+  //*****NEED memory barrier here to ensure compiler does not cache V.status*********
+  if (BARRIER() && V->item.status==READY) {
+    void* flag=NULL;
+    LOCKXCHG((unsigned int*)&(V->array[index]), (unsigned int)flag); 
+    if (flag!=NULL) {
+      if (isParent(r)) { //parent's retire immediately
+        atomic_dec(&V->item.total);
       }
+      return READY;
+    } else {
+      return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
+    }
+  } else {
+    return NOTREADY;
+  }
+}
 
-    }else if(element->status==3){// coarse write
-      return 1;
+
+//SCC's don't come in parent variety
+ADDSCC(MemoryQueue *Q, REntry *r) {
+  //added SCC
+  SCC* S=createSCC();
+  S->item.total=1; 
+  S->val=r;
+  Q->tail->next=(MemoryQueueItem*)S;
+  //*** NEED BARRIER HERE
+  if (BARRIER() && Q->tail->status==READY && Q->tail->total==0 && Q->tail==Q->head) {
+    //previous Q item is finished
+    S->item.status=READY;
+    Q->tail=(MemoryQueueItem*)S;
+    void* flag=NULL;
+    LOCKXCHG((int*)S->val, (int)flag);
+    if (flag!=NULL) {
+      return READY;
+    } else {
+      return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
     }
+  } else {
+    Q->tail=(MemoryQueueItem*)S;
+    return NOTREADY;
+  }
+}
 
+
+void RETIRERENTRY(MemoryQueue* Q, REntry * r) {
+  if (isFineWrite(r)||isFineRead(r)) {
+    RETIREHASHTABLE(Q, r);
+  } else if (isCoarse(r)) {
+    RETIREVECTOR(Q, r);
+  } else if (isSCC(r)) {
+    RETIRESCC(Q, r);
   }
+}
 
-  return 0;
+RETIRESCC(MemoryQueue *Q, REntry *r) {
+  SCC* s=r->scc;
+  s->item.total=0;//don't need atomicdec
+  RESOLVECHAIN(Q);
 }
 
-int isOverlapped(struct Queue* prevList, struct Queue* itemList){
 
-  if(!isEmpty(prevList)){
-    struct QueueItem* queueItemA=getHead(prevList); 
-    
-    while(queueItemA!=NULL){
-      ConflictNode* nodeA=queueItemA->objectptr;
+RETIREHASHTABLE(MemoryQueue *q, REntry *r) {
+  Hashtable *T=r->hashtable;
+  BinItem *b=r->binitem;
+  RETIREBIN(T,r,b);
+  atomic_dec(&T->item.total);
+  if (T->item.next!=NULL && T->item.total==0) { 
+    RESOLVECHAIN(q);
+  }
+}
 
-      if(!isEmpty(itemList)){
-       struct QueueItem* queueItemB=getHead(itemList);
-       while(queueItemB!=NULL){
-         ConflictNode* nodeB=queueItemB->objectptr;
-         if(nodeA->id==nodeB->id){
-           return 1;
-         }
-         queueItemB=getNextQueueItem(queueItemB);
+RETIREBIN(Hashtable *T, REntry *r, BinItem *b) {
+  int key=generateKey((unsigned int)r->dynID);
+  if(isFineRead(r)) {
+    atomic_dec(&b->total);
+  }
+  if (isFineWrite(r) || (isFineRead(r) && b->next!=NULL && b->total==0)) {
+    // CHECK FIRST IF next is nonnull to guarantee that b.total cannot change
+    BinItem * val;
+    do {  
+      val=(BinItem*)1;
+      val=(BinItem*)LOCKXCHG((unsigned int*)&(T->array[key]->head), (unsigned int)val);
+    } while(val==(BinItem*)1);
+    // at this point have locked bin
+    BinItem *ptr=val;
+    int haveread=FALSE;
+
+    int i;
+    while (ptr!=NULL) {
+      if (isReadBinItem(ptr)) {
+       ReadBinItem* rptr=(ReadBinItem*)ptr;
+        if (rptr->item.status==NOTREADY) {
+          for (i=0;i<rptr->index;i++) {            
+           resolveDependencies(rptr->array[i]);
+            // XXXXX atomicdec(rptr->array[i].dependenciesCount);
+            if (isParent(&rptr->array[i])) {
+              //parents go immediately
+              atomic_dec(&rptr->item.total);
+              atomic_dec(&T->item.total);
+            }
+          }
+        }
+        rptr->item.status=READY; 
+        if (rptr->item.next==NULL) {
+          break;
+        }
+        if (rptr->item.total!=0) {
+          haveread=TRUE; 
+        } else if ((BinItem*)rptr==val) {
+          val=val->next;
+        }
+      } else if(isWriteBinItem(ptr)) {
+        if (haveread)  
+          break;
+       if(ptr->status==NOTREADY){
+         resolveDependencies(((WriteBinItem*)ptr)->val);
+         ptr->status=READY;
+         if(isParent(((WriteBinItem*)ptr)->val)){
+           atomic_dec(&T->item.total);
+           val=val->next;        
+         }else
+           break;
+       }else{ // write bin is already resolved
+         val=val->next;
        }
-      }
-      queueItemA=getNextQueueItem(queueItemA);      
+       /*
+        if(ptr->status==NOTREADY) {           
+         ptr->status=READY; 
+         resolveDependencies(((WriteBinItem*)ptr)->val);
+         if (isParent(((WriteBinItem*)ptr)->val)) {  
+           atomic_dec(&T->item.total);
+           //val=val->next;
+           val=ptr->next;
+         } else
+           break;
+        } 
+       */
+      } 
+      ptr=ptr->next;
     }
+    T->array[key]->head=val; // release lock
   }
-  return 0;
-  
 }
 
-int resolveWaitingQueue(struct Queue* waitingQueue,struct QueueItem* qItem){
 
-  if(!isEmpty(waitingQueue)){
+RETIREVECTOR(MemoryQueue *Q, REntry *r) {
+  Vector* V=r->vector;
+  atomic_dec(&V->item.total);
+
+  if (V->item.next!=NULL && V->item.total==0) { //NOTE: ORDERING CRUCIAL HERE
+    RESOLVECHAIN(Q);
+  }
+}
 
-    SESEcommon* qCommon=qItem->objectptr;
-    
-    struct QueueItem* current=getHead(waitingQueue);
-    while(current!=NULL){
-         if(current!=qItem){
-          SESEcommon* currentCommon=current->objectptr;
-          if(hasConflicts(currentCommon->classID,qCommon->connectedList)){
-            return 0;
-          }
-        }else{
-          return 1;
-        }
-        current=getNextQueueItem(current);
+RESOLVECHAIN(MemoryQueue *Q) {
+  while(TRUE) {
+    MemoryQueueItem* head=Q->head;
+    if (head->next==NULL||head->total!=0) { 
+      //item is not finished
+      if (head->status!=READY) {  
+        //need to update status
+        head->status=READY;
+        if (isHashtable(head)) {
+          RESOLVEHASHTABLE(Q, head);
+        } else if (isVector(head)) {
+          RESOLVEVECTOR(Q, head);
+        } else if (isSingleItem(head)) {
+          RESOLVESCC(head);
+        }
+        if (head->next==NULL)
+          break;
+        if (head->total!=0)
+          break;
+      } else
+        break;
     }
+    MemoryQueueItem* nextitem=head->next;
+    CAS((int*)Q->head, (int)head, (int)nextitem);
+    //oldvalue not needed...  if we fail we just repeat
   }
-  return 1;
 }
 
-int hasConflicts(int classID, struct Queue* connectedList){
-  
-  if(!isEmpty(connectedList)){
-    struct QueueItem* queueItem=getHead(connectedList); 
-    
-    while(queueItem!=NULL){
-      ConflictNode* node=queueItem->objectptr;
-      if(node->id==classID){
-       return 1;
-      }
-      queueItem=getNextQueueItem(queueItem);      
+
+RESOLVEHASHTABLE(MemoryQueue *Q, Hashtable *T) {  
+  int binidx;
+  for (binidx=0;binidx<NUMBINS;binidx++) {    
+    BinElement* bin=T->array[binidx];
+    BinItem* val;
+    do {
+      val=(BinItem*)1;
+      LOCKXCHG((int*)bin->head, (int)val);
+    } while (val==(BinItem*)1);
+    //at this point have locked bin    
+    int haveread=FALSE; 
+    BinItem* ptr=val;
+    if(ptr!=NULL&&ptr->status==NOTREADY) {
+      do {
+        if (isWriteBinItem(ptr)) {
+          if (haveread)
+           break;        
+         resolveDependencies(((WriteBinItem*)ptr)->val);
+          // XXXXX atomic_dec(ptr.val.dependenciesCount);
+          ptr->status=READY;  
+          if (isParent(((WriteBinItem*)ptr)->val)) {
+            atomic_dec(&T->item.total);
+            val=val->next;
+          } else
+           break;
+        } else if (isReadBinItem(ptr)) {
+         int i;
+         ReadBinItem* rptr=(ReadBinItem*)ptr;
+          for(i=0;i<rptr->index;i++) {
+           resolveDependencies(rptr->array[i]);
+            // XXXXX atomicdec(ptr.array[i].dependenciesCount);
+            if (isParent(&rptr->array[i])) {
+              atomic_dec(&rptr->item.total);
+              atomic_dec(&T->item.total);
+            }
+          }
+          if (rptr->item.next==NULL||rptr->item.total!=0) {
+            haveread=TRUE;
+          } else if((BinItem*)rptr==val) {
+            val=val->next;
+          }
+          rptr->item.status=READY; { 
+         }
+         ptr=ptr->next;
+       } 
+      }while(ptr!=NULL);   
     }
+    bin->head=val; // released lock;
   }
-  return 0;
 }
 
-void addNewConflictNode(ConflictNode* node, struct Queue* connectedList){
-  
-  if(!isEmpty(connectedList)){
-    struct QueueItem* qItem=getHead(connectedList);
-    while(qItem!=NULL){
-      ConflictNode* qNode=qItem->objectptr;
-      if(qNode->id==node->id){
-       return;
+RESOLVEVECTOR(MemoryQueue *q, Vector *V) {
+  int i;
+  Vector* tmp=V;
+  //handle ready cases
+  while(TRUE) {
+    //enqueue everything
+    for (i=0;i<NUMITEMS;i++) {
+      void* val=NULL;
+      LOCKXCHG((int*)&tmp->array[i], (int)val); 
+      if (val!=NULL) { 
+        // XXXXX atomicdec(val.dependenciesCount);
+        if (isParent(val)) {
+          atomic_dec(&tmp->item.total);
+        }
       }
-      qItem=getNextQueueItem(qItem);
+    }
+    if (tmp->item.next!=NULL&&isVector(tmp->item.next)) {
+      tmp=(Vector*)tmp->item.next;
+    } else {
+      break;
     }
   }
-
-  addNewItem(connectedList,node);
-
 }
 
-int contains(struct Queue* queue, struct QueueItem* qItem){
-
-  if(!isEmpty(queue)){
-    struct QueueItem* nextQItem=getHead(queue);
-    while(nextQItem!=NULL){
-      if((nextQItem->objectptr)==qItem){
-       return 1;
-      } 
-      nextQItem=getNextQueueItem(nextQItem);
-    }
+RESOLVESCC(SCC *S) {
+  //precondition: SCC's state is READY
+  void* flag=NULL;
+  LOCKXCHG((int*)S->val, (int)flag); 
+  if (flag!=NULL) {
+    // XXXXX atomicdec(flag.dependenciesCount);
   }
+}
 
-  return 0;
 
+resolveDependencies(REntry* rentry){
+  SESEcommon* seseCommon=(SESEcommon*)rentry->seseRec;
+  if(rentry->type==0 || rentry->type==1){    
+    if( atomic_sub_and_test(1, &(seseCommon->unresolvedDependencies)) ){
+      workScheduleSubmit(seseCommon);
+    }   
+  }else if(rentry->type==2 || rentry->type==3){
+    pthread_cond_signal(&(rentry->stallDone));
+  }
 }
index 9e58418d3aa227c87043bc803977f4dc8fd7b3ba..7087408d836d1e0753e945967108368fe03490a4 100644 (file)
 #define TRUE 1
 #endif
 
-// each allocation site needs the following
-typedef struct AllocSite_t{
-  long id;
-  struct Queue* waitingQueue;
-} AllocSite;
+#define NUMBINS 64
+#define NUMREAD 64
+#define NUMITEMS 64
+#define NUMRENTRY 256
 
-typedef struct ConflictNode_t{
-  int id;
-} ConflictNode;
+#define READY 1
+#define NOTREADY 0
+
+#define READ 0
+#define WRITE 1
+#define PARENTREAD 2
+#define PARENTWRITE 3
+#define COARSE 4
+#define PARENTCOARSE 5
+#define SCCITEM 6
+
+#define HASHTABLE 0
+#define VECTOR 1
+#define SINGLEITEM 2
+
+#define READBIN 0
+#define WRITEBIN 1
+
+#define H_MASK (NUMBINS<<4)-1
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
 
+typedef struct REntry_t{
+  int type; // fine read:0, fine write:1, parent read:2, parent write:3 coarse: 4, parent coarse:5, scc: 6
+  struct Hashtable_t* hashtable;
+  struct BinItem_t* binitem;
+  struct Vector_t* vector;
+  struct SCC_t* scc;
+  struct MemoryQueue_t* queue;
+  pthread_cond_t stallDone;
+  void* seseRec;
+  void* dynID;
+} 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;
+} MemoryQueueItem;
+
+typedef struct MemoryQueue_t {
+  MemoryQueueItem * head;
+  MemoryQueueItem * tail;  
+} MemoryQueue;
+
+typedef struct BinItem_t {
+  int total;
+  int status;       //NOTREADY, READY
+  int type;         //READBIN:0, WRITEBIN:1
+  struct BinItem_t * next;
+} BinItem;
+
+typedef struct Hashtable_t {
+  MemoryQueueItem item;
+  struct BinElement_t* array[NUMBINS];
+} Hashtable;
+
+typedef struct BinElement_t {
+  BinItem * head;
+  BinItem * tail;
+} BinElement;
+
+typedef struct WriteBinItem_t {
+  BinItem item;
+  REntry * val;
+} WriteBinItem;
+
+typedef struct ReadBinItem_t {
+  BinItem item;
+  REntry * array;
+  int index;
+} ReadBinItem;
+
+typedef struct Vector_t {
+  MemoryQueueItem item;
+  REntry * array;
+  int index;
+} Vector;
+
+typedef struct SCC_t {
+  MemoryQueueItem item;
+  REntry * val;
+} SCC;
+
+int ADDRENTRY(MemoryQueue* q, REntry * r);
+void RETIRERENTRY(MemoryQueue* Q, REntry * r);
+
+////////////////////////////////////////
 
 // forward declaration of pointer type
 typedef struct SESEcommon_t* SESEcommon_p;
@@ -59,17 +149,15 @@ typedef struct SESEcommon_t {
 
   SESEcommon_p    parent;
 
-  AllocSite* allocSiteArray;
-  int numRelatedAllocSites;
   psemaphore memoryStallSiteSem;
-  struct Queue* connectedList;
-  int numRelatedWaitingQueue;
-  int waitingQueueItemID;
-
   pthread_cond_t stallDone;
 
-} SESEcommon;
+  int numMemoryQueue;
+  int rentryIdx;
+  struct MemoryQueue_t** memoryQueueArray;
+  struct REntry_t* rentryArray[NUMRENTRY];
 
+} SESEcommon;
 
 typedef struct WaitingElement_t{
   void* seseRec;
@@ -93,12 +181,14 @@ extern __thread SESEcommon_p seseCaller;
 // deallocation of SESE records
 void* mlpCreateSESErecord( int size );
 void  mlpDestroySESErecord( void* seseRecord );
-
-AllocSite* mlpCreateAllocSiteArray(int numAllocSites);
-ConflictNode* mlpCreateConflictNode(int id);
-int addWaitingQueueElement(AllocSite* allocSiteArray, int numAllocSites, long allocID, WaitingElement* wElement);
-WaitingElement* mlpCreateWaitingElement(int status, void* seseToIssue, struct Queue* queue, int id);
 void* mlpAllocSESErecord( int size );
 
+MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue);
+REntry* mlpCreateREntry(int type, void* seseToIssue, void* dynID);
+MemoryQueue* createMemoryQueue();
+
+//////////////////////////////
+
+
 
 #endif /* __MLP_RUNTIME__ */