// create it's lock and take it immediately
output.println(" pthread_mutex_init( &(seseToIssue->common.lock), NULL );");
// output.println(" pthread_mutex_lock( &(seseToIssue->common.lock) );");
-
- // count up memory conflict dependencies,
- // eom
- ConflictGraph graph = null;
- FlatSESEEnterNode parent = fsen.getParent();
- if (parent != null) {
- if (parent.isCallerSESEplaceholder) {
- graph = mlpa.getConflictGraphResults().get(parent.getfmEnclosing());
- } else {
- graph = mlpa.getConflictGraphResults().get(parent);
- }
- }
- if (graph != null && graph.hasConflictEdge()) {
- HashSet<SESELock> seseLockSet = mlpa.getConflictGraphLockMap().get(
- graph);
- output.println();
- output.println(" //add memory queue element");
- Set<WaitingElement> waitingQueueSet = graph
- .getWaitingElementSetBySESEID(fsen.getIdentifier(),
- seseLockSet);
- if (waitingQueueSet.size() > 0) {
- output.println(" {");
- output.println(" REntry* rentry=NULL;");
- output.println(" seseToIssue->common.rentryIdx=0;");
- for (Iterator iterator = waitingQueueSet.iterator(); iterator
- .hasNext();) {
- WaitingElement waitingElement = (WaitingElement) iterator
- .next();
-
- if( waitingElement.getStatus() >= ConflictNode.COARSE ){
- output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", seseToIssue);");
- }else{
- output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", seseToIssue, seseToIssue->"+ waitingElement.getDynID() + ");");
- }
- output.println(" rentry->queue=parentCommon->memoryQueueArray["+ waitingElement.getQueueID()+ "];");
- output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;");
- output
- .println(" if(ADDRENTRY(parentCommon->memoryQueueArray["
- + waitingElement.getQueueID()
- + "],rentry)==NOTREADY){");
- output.println(" ++(localCount);");
- output.println(" } ");
- output.println();
- }
- output.println(" }");
- }
- output.println();
- }
-
+
if( fsen != mlpa.getMainSESE() ) {
// count up outstanding dependencies, static first, then dynamic
Iterator<SESEandAgePair> staticSrcsItr = fsen.getStaticInVarSrcs().iterator();
// to pass the static name to the child's record
output.println(" seseToIssue->"+srcPair+" = "+srcPair+";");
}
+
+ ////////////////
+ // count up memory conflict dependencies,
+ // eom
+ ConflictGraph graph = null;
+ FlatSESEEnterNode parent = fsen.getParent();
+ if (parent != null) {
+ if (parent.isCallerSESEplaceholder) {
+ graph = mlpa.getConflictGraphResults().get(parent.getfmEnclosing());
+ } else {
+ graph = mlpa.getConflictGraphResults().get(parent);
+ }
+ }
+ if (graph != null && graph.hasConflictEdge()) {
+ HashSet<SESELock> seseLockSet = mlpa.getConflictGraphLockMap().get(
+ graph);
+ output.println();
+ output.println(" //add memory queue element");
+ Set<WaitingElement> waitingQueueSet = graph
+ .getWaitingElementSetBySESEID(fsen.getIdentifier(),
+ seseLockSet);
+ if (waitingQueueSet.size() > 0) {
+ output.println(" {");
+ output.println(" REntry* rentry=NULL;");
+ output.println(" seseToIssue->common.rentryIdx=0;");
+ for (Iterator iterator = waitingQueueSet.iterator(); iterator
+ .hasNext();) {
+ WaitingElement waitingElement = (WaitingElement) iterator
+ .next();
+
+ if( waitingElement.getStatus() >= ConflictNode.COARSE ){
+ output.println(" rentry=mlpCreateREntry("+ waitingElement.getStatus()+ ", seseToIssue);");
+ }else{
+ TempDescriptor td=waitingElement.getTempDesc();
+ VariableSourceToken vst=fsen.getStaticInVarSrc(td);
+ String srcId="SESE_"+vst.getSESE().getPrettyIdentifier()+vst.getSESE().getIdentifier()+"_"+vst.getAge();
+ output.println(" rentry=mlpCreateFineREntry("+ waitingElement.getStatus()+ ", seseToIssue, seseToIssue->"+ waitingElement.getDynID() + ");");
+ output.println(" if(seseToIssue->"+ waitingElement.getDynID()+" == NULL) {");
+ output.println(" rentry->pointer=(void*)&seseToIssue->"+srcId+"->"+waitingElement.getDynID()+";");
+ output.println(" seseToIssue->common.unresolvedRentryArray[seseToIssue->common.unresolvedRentryIdx++]=rentry;");
+ output.println(" }");
+ }
+ output.println(" rentry->queue=parentCommon->memoryQueueArray["+ waitingElement.getQueueID()+ "];");
+ output.println(" seseToIssue->common.rentryArray[seseToIssue->common.rentryIdx++]=rentry;");
+ output
+ .println(" if(ADDRENTRY(parentCommon->memoryQueueArray["
+ + waitingElement.getQueueID()
+ + "],rentry)==NOTREADY){");
+ output.println(" ++(localCount);");
+ output.println(" } ");
+ output.println();
+ }
+ output.println(" }");
+ }
+ output.println();
+ }
+
+ ////////////////
// dynamic sources might already be accounted for in the static list,
// so only add them to forwarding lists if they're not already there
// decrement dependency count for all SESE's on your forwarding list
output.println(" while( !isEmpty( "+com+".forwardList ) ) {");
output.println(" SESEcommon* consumer = (SESEcommon*) getItem( "+com+".forwardList );");
+
+ output.println(" if(consumer->unresolvedRentryIdx>0){");
+ output.println(" // resolved null pointer");
+ output.println(" int idx;");
+ output.println(" for(idx=0;idx<consumer->unresolvedRentryIdx;idx++){");
+ output.println(" resolvePointer(consumer->unresolvedRentryArray[idx]);");
+ output.println(" }");
+ output.println(" }");
+
// output.println(" pthread_mutex_lock( &(consumer->lock) );");
// output.println(" --(consumer->unresolvedDependencies);");
// output.println(" if( consumer->unresolvedDependencies == 0 ) {");
newTable->array[i]->head=NULL;
newTable->array[i]->tail=NULL;
}
+ newTable->unresolvedQueue=NULL;
return newTable;
}
//at this point, have table
Hashtable* table=(Hashtable*)q->tail;
+ r->hashtable=table;
+ if(*(r->pointer)==0 || (*(r->pointer)!=0 && table->unresolvedQueue!=NULL)){
+ struct Queue* val;
+ // grab lock on the queue
+ do {
+ val=(struct Queue*)0x1;
+ val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
+ } while(val==(struct Queue*)0x1);
+
+ if(val==NULL){
+ //first case
+ if(*(r->pointer)!=0){
+ // pointer is already resolved.
+ table->unresolvedQueue=val; //released lock;
+ return ADDTABLE(q,r);
+ }
+ table->unresolvedQueue=(struct Queue*)0x1;
+ struct Queue* queue=createQueue();
+ addNewItem(queue,r);
+ atomic_inc(&table->item.total);
+ table->unresolvedQueue=queue; // expose new queue
+ }else{
+ if(val==NULL){
+ // someone else has already cleared all queue stuff
+ table->unresolvedQueue=val; // released lock
+ return ADDTABLE(q,r);
+ }
+ addNewItemBack(val,r);
+ atomic_inc(&table->item.total);
+ table->unresolvedQueue=val; // released lock
+ }
+ return NOTREADY;
+ }
+
+ r->dynID=(void*)*(r->pointer); // interim fix.
+ BinItem * val;
+ int key=generateKey((unsigned int)(unsigned INTPTR)r->dynID);
+ do {
+ val=(BinItem*)0x1;
+ BinElement* bin=table->array[key];
+ val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);//note...talk to me about optimizations here.
+ } while(val==(BinItem*)0x1);
+ //at this point have locked bin
+ if (val==NULL) {
+ return EMPTYBINCASE(table, table->array[key], r, TRUE);
+ } else {
+ if (isFineWrite(r)) {
+ return WRITEBINCASE(table, r, val, key, TRUE);
+ } else if (isFineRead(r)) {
+ return READBINCASE(table, r, val, key, TRUE);
+ }
+ }
+}
+
+int ADDTABLEITEM(Hashtable* table, REntry* r){
BinItem * val;
int key=generateKey((unsigned int)(unsigned INTPTR)r->dynID);
do {
} while(val==(BinItem*)0x1);
//at this point have locked bin
if (val==NULL) {
- return EMPTYBINCASE(table, table->array[key], r);
+ return EMPTYBINCASE(table, table->array[key], r, FALSE);
} else {
if (isFineWrite(r)) {
- return WRITEBINCASE(table, r, val, key);
+ return WRITEBINCASE(table, r, val, key, FALSE);
} else if (isFineRead(r)) {
- return READBINCASE(table, r, val, key);
+ return READBINCASE(table, r, val, key, FALSE);
}
}
}
-int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r) {
+int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r, int inc) {
int retval;
BinItem* b;
if (isFineWrite(r)) {
retval=NOTREADY;
}
- atomic_inc(&T->item.total);
+ if(inc){
+ atomic_inc(&T->item.total);
+ }
r->hashtable=T;
r->binitem=b;
be->tail=b;
return retval;
}
-int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val, int key) {
+int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) {
//chain of bins exists => tail is valid
//if there is something in front of us, then we are not ready
b->item.status=retval;
// b->item.status=NOTREADY;
- atomic_inc(&T->item.total);
+ if(inc){
+ atomic_inc(&T->item.total);
+ }
r->hashtable=T;
r->binitem=(BinItem*)b;
return retval;
}
-READBINCASE(Hashtable *T, REntry *r, BinItem *val, int key) {
+READBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) {
BinItem * bintail=T->array[key]->tail;
if (isReadBinItem(bintail)) {
return TAILREADCASE(T, r, val, bintail, key);
}
}
-int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key) {
+int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
ReadBinItem * readbintail=(ReadBinItem*)T->array[key]->tail;
int status, retval;
if (readbintail->item.status=READY) {
r->binitem=(BinItem*)readbintail;
//printf("grouping with %d\n",readbintail->index);
}
- atomic_inc(&T->item.total);
+ if(inc){
+ atomic_inc(&T->item.total);
+ }
r->hashtable=T;
T->array[key]->head=val;//released lock
return retval;
}
-TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key) {
+TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
// WriteBinItem* wb=createWriteBinItem();
//wb->val=r;
//wb->item.total=1;//safe because item could not have started
rb->array[rb->index++]=r;
rb->item.total=1;//safe because item could not have started
rb->item.status=NOTREADY;
- atomic_inc(&T->item.total);
+ if(inc){
+ atomic_inc(&T->item.total);
+ }
r->hashtable=T;
r->binitem=(BinItem*)rb;
T->array[key]->tail->next=(BinItem*)rb;
resolveDependencies(REntry* rentry){
SESEcommon* seseCommon=(SESEcommon*)rentry->seseRec;
- if(rentry->type==READ || rentry->type==WRITE || rentry->type==COARSE || rentry->type==SCCITEM){
+ if(rentry->type==READ || rentry->type==WRITE || rentry->type==COARSE || rentry->type==SCCITEM){
if( atomic_sub_and_test(1, &(seseCommon->unresolvedDependencies)) ){
workScheduleSubmit(seseCommon);
}
}
}
+resolvePointer(REntry* rentry){
+ rentry->dynID=(void*)*(rentry->pointer); // interim.
+ Hashtable* table=rentry->hashtable;
+ struct Queue* val;
+ do {
+ val=(struct Queue*)0x1;
+ val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
+ } while(val==(struct Queue*)0x1);
+ if(val!=NULL && getHead(val)->objectptr==rentry){
+ // handling pointer is the first item of the queue
+ // start to resolve until it reaches unresolved pointer or end of queue
+ do{
+ struct QueueItem* head=getHead(val);
+ if(head!=NULL){
+ REntry* rentry=(REntry*)head->objectptr;
+ if(*(rentry->pointer)==0){
+ // encounters following unresolved pointer
+ table->unresolvedQueue=val;//released lock
+ break;
+ }
+ removeItem(val,head);
+ if(ADDTABLEITEM(table, rentry)==READY){
+ SESEcommon* seseCommon=(SESEcommon*)rentry->seseRec;
+ atomic_sub_and_test(1, &(seseCommon->unresolvedDependencies));
+ }
+ }else{
+ table->unresolvedQueue=NULL; // set hashtable as normal-mode.
+ break;
+ }
+ }while(TRUE);
+ }else{
+ table->unresolvedQueue=val;//released lock;
+ }
+}
+