From 19660149087b316369a79493f091ba4d1b01db6e Mon Sep 17 00:00:00 2001 From: yeom Date: Thu, 4 Mar 2010 23:15:33 +0000 Subject: [PATCH] initial commit of new memory queue. still just working with fine-grain cases. --- Robust/src/Analysis/MLP/ConflictGraph.java | 13 +- Robust/src/Analysis/MLP/WaitingElement.java | 4 +- Robust/src/IR/Flat/BuildCode.java | 337 +++------ Robust/src/Runtime/mlp_lock.h | 46 ++ Robust/src/Runtime/mlp_runtime.c | 760 +++++++++++++++----- Robust/src/Runtime/mlp_runtime.h | 130 +++- 6 files changed, 854 insertions(+), 436 deletions(-) diff --git a/Robust/src/Analysis/MLP/ConflictGraph.java b/Robust/src/Analysis/MLP/ConflictGraph.java index f9e06beb..b6bce626 100644 --- a/Robust/src/Analysis/MLP/ConflictGraph.java +++ b/Robust/src/Analysis/MLP/ConflictGraph.java @@ -718,6 +718,8 @@ public class ConflictGraph { HashSet waitingElementSet = new HashSet(); Set> s = id2cn.entrySet(); Collection 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()); diff --git a/Robust/src/Analysis/MLP/WaitingElement.java b/Robust/src/Analysis/MLP/WaitingElement.java index 7524285a..76e07e0f 100644 --- a/Robust/src/Analysis/MLP/WaitingElement.java +++ b/Robust/src/Analysis/MLP/WaitingElement.java @@ -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 { diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index 182a9aa2..d47d5c79 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -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 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 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 lockSet=mlpa.getConflictGraphLockMap().get(graph); - + output + .println(" SESEcommon* parentCommon = &(___params___->common);"); + HashSet 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 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 allocSet = conflictsMap - .getAllocationSiteIDSetofStallSite(); - + Set 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 seseLockSet=mlpa.getConflictGraphLockMap().get(graph); Set 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 seseLockSet=mlpa.getConflictGraphLockMap().get(graph); - - output.println(); - output.println(" /*add waiting queue element*/"); - Set 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 seseLockSet = mlpa.getConflictGraphLockMap().get( + graph); + output.println(); + output.println(" //add memory queue element"); + Set waitingQueueSet = graph + .getWaitingElementSetBySESEID(fsen.getIdentifier(), + seseLockSet); + if (waitingQueueSet.size() > 0) { + output.println(" {"); + output.println(" REntry* rentry=NULL;"); + output.println(" seseToIssue->common.rentryIdx=0;"); + 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 diff --git a/Robust/src/Runtime/mlp_lock.h b/Robust/src/Runtime/mlp_lock.h index 18bcf4d5..6086ffc4 100644 --- a/Robust/src/Runtime/mlp_lock.h +++ b/Robust/src/Runtime/mlp_lock.h @@ -1,3 +1,12 @@ +#include "runtime.h" + +#include +#include +#include + + +#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; +} diff --git a/Robust/src/Runtime/mlp_runtime.c b/Robust/src/Runtime/mlp_runtime.c index fb52b534..69581bf3 100644 --- a/Robust/src/Runtime/mlp_runtime.c +++ b/Robust/src/Runtime/mlp_runtime.c @@ -5,7 +5,6 @@ #include #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; iid=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;iclassID,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;iresolved=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;iclassID,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;itype==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;iarray[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;iindex;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;binidxarray[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;iindex;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;iarray[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)); + } } diff --git a/Robust/src/Runtime/mlp_runtime.h b/Robust/src/Runtime/mlp_runtime.h index 9e58418d..7087408d 100644 --- a/Robust/src/Runtime/mlp_runtime.h +++ b/Robust/src/Runtime/mlp_runtime.h @@ -15,16 +15,106 @@ #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__ */ -- 2.34.1