changes for using unique ID instead of obj address for the memory queue
[IRC.git] / Robust / src / Runtime / mlp_runtime.c
1 #include "runtime.h"
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <assert.h>
6
7 #include "mem.h"
8 #include "mlp_runtime.h"
9 #include "workschedule.h"
10 #include "methodheaders.h"
11
12
13
14 /*
15 __thread struct Queue* seseCallStack;
16 __thread pthread_once_t mlpOnceObj = PTHREAD_ONCE_INIT;
17 void mlpInitOncePerThread() {
18   seseCallStack = createQueue();
19 }
20 */
21 __thread SESEcommon_p seseCaller;
22
23
24 void* mlpAllocSESErecord( int size ) {
25   void* newrec = RUNMALLOC( size );  
26   if( newrec == 0 ) {
27     printf( "mlpAllocSESErecord did not obtain memory!\n" );
28     exit( -1 );
29   }
30   return newrec;
31 }
32
33
34 void mlpFreeSESErecord( void* seseRecord ) {
35   RUNFREE( seseRecord );
36 }
37
38 MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue){
39   int i;
40   MemoryQueue** newMemoryQueue=(MemoryQueue**)RUNMALLOC( sizeof( MemoryQueue* ) * numMemoryQueue );
41   for(i=0; i<numMemoryQueue; i++){
42     newMemoryQueue[i]=createMemoryQueue();
43   }
44   return newMemoryQueue;
45 }
46
47 REntry* mlpCreateREntryArray(){
48   REntry* newREntryArray=(REntry*)RUNMALLOC(sizeof(REntry)*NUMRENTRY);
49   return newREntryArray;
50 }
51
52 REntry* mlpCreateFineREntry(int type, void* seseToIssue, void* dynID){
53   REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry));
54   newREntry->type=type;
55   newREntry->seseRec=seseToIssue;
56   newREntry->pointer=dynID;
57   if((*newREntry->pointer)!=0){// make sure it is not unresolved address.
58     struct ___Object___ * obj=(struct ___Object___*)((unsigned INTPTR)*newREntry->pointer);
59     newREntry->oid=obj->oid;
60   }
61   return newREntry;
62 }
63
64 REntry* mlpCreateREntry(int type, void* seseToIssue){
65   REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry));
66   newREntry->type=type;
67   newREntry->seseRec=seseToIssue;
68   return newREntry;
69 }
70
71 int isParent(REntry *r) {
72   if (r->type==PARENTREAD || r->type==PARENTWRITE) {
73     return TRUE;
74   } else {
75     return FALSE;
76   }
77 }
78
79 int isParentCoarse(REntry *r){
80   if (r->type==PARENTCOARSE){
81     return TRUE;
82   }else{
83     return FALSE;
84   }
85 }
86
87 int isFineRead(REntry *r) {
88   if (r->type==READ || r->type==PARENTREAD) {
89     return TRUE;
90   } else {
91     return FALSE;
92   }
93 }
94
95 int isFineWrite(REntry *r) {
96   if (r->type==WRITE || r->type==PARENTWRITE) {
97     return TRUE;
98   } else {
99     return FALSE;
100   }
101 }
102
103 int isCoarse(REntry *r){
104   if(r->type==COARSE || r->type==PARENTCOARSE){
105     return TRUE;
106   } else {
107     return FALSE;
108   }
109 }
110
111 int isSCC(REntry *r){
112   if(r->type==SCCITEM){
113     return TRUE;
114   } else {
115     return FALSE;
116   }
117 }
118
119 int isSingleItem(MemoryQueueItem *qItem){
120   if(qItem->type==SINGLEITEM){
121     return TRUE;
122   } else {
123     return FALSE;
124   }
125 }
126
127 int isHashtable(MemoryQueueItem *qItem){
128   if(qItem->type==HASHTABLE){
129     return TRUE;
130   } else {
131     return FALSE;
132   }
133 }
134
135 int isVector(MemoryQueueItem *qItem){
136   if(qItem->type==VECTOR){
137     return TRUE;
138   } else {
139     return FALSE;
140   }
141 }
142
143 int isReadBinItem(BinItem* b){
144   if(b->type==READBIN){
145     return TRUE;
146   }else{
147     return FALSE;
148   }
149 }
150
151 int isWriteBinItem(BinItem* b){
152   if(b->type==WRITEBIN){
153     return TRUE;
154   }else{
155     return FALSE;
156   }
157 }
158
159 int generateKey(unsigned int data){
160   return (data&H_MASK)>> 4;
161 }
162
163 Hashtable* createHashtable(){
164   int i=0;
165   Hashtable* newTable=(Hashtable*)RUNMALLOC(sizeof(Hashtable));
166   newTable->item.type=HASHTABLE;
167   for(i=0;i<NUMBINS;i++){
168     newTable->array[i]=(BinElement*)RUNMALLOC(sizeof(BinElement));
169     newTable->array[i]->head=NULL;
170     newTable->array[i]->tail=NULL;
171   }
172   newTable->unresolvedQueue=NULL;
173   return newTable;
174 }
175
176 WriteBinItem* createWriteBinItem(){
177   WriteBinItem* binitem=(WriteBinItem*)RUNMALLOC(sizeof(WriteBinItem));
178   binitem->item.type=WRITEBIN;
179   return binitem;
180 }
181
182 ReadBinItem* createReadBinItem(){
183   ReadBinItem* binitem=(ReadBinItem*)RUNMALLOC(sizeof(ReadBinItem));
184   binitem->index=0;
185   binitem->item.type=READBIN;
186   return binitem;
187 }
188
189 Vector* createVector(){
190   Vector* vector=(Vector*)RUNMALLOC(sizeof(Vector));
191   vector->index=0;
192   vector->item.type=VECTOR;
193   return vector;
194 }
195
196 SCC* createSCC(){
197   SCC* scc=(SCC*)RUNMALLOC(sizeof(SCC));
198   scc->item.type=SINGLEITEM;
199   return scc;
200 }
201
202 MemoryQueue* createMemoryQueue(){
203   MemoryQueue* queue = (MemoryQueue*)RUNMALLOC(sizeof(MemoryQueue));
204   MemoryQueueItem* dummy=(MemoryQueueItem*)RUNMALLOC(sizeof(MemoryQueueItem));
205   dummy->type=3; // dummy type
206   dummy->total=0;
207   dummy->status=READY;
208   queue->head = dummy;
209   queue->tail = dummy;
210   return queue;
211 }
212
213 int ADDRENTRY(MemoryQueue * q, REntry * r) {
214   if (isFineRead(r) || isFineWrite(r)) { 
215     return ADDTABLE(q, r);
216   } else if (isCoarse(r)) {
217     return ADDVECTOR(q, r);
218   } else if (isSCC(r)) {
219     return ADDSCC(q, r);
220   }
221 }
222
223 int ADDTABLE(MemoryQueue *q, REntry *r) {
224   if(!isHashtable(q->tail)) {
225     //Fast Case
226     MemoryQueueItem* tail=q->tail;
227     if (isParent(r) && tail->total==0 && q->tail==q->head) {
228       return READY;
229     }
230
231     //Add table
232     Hashtable* h=createHashtable();
233     tail->next=(MemoryQueueItem*)h;
234     //************NEED memory barrier here to ensure compiler does not cache Q.tail.status********
235     if (BARRIER() && tail->status==READY && tail->total==0 && q->tail==q->head) { 
236       //previous Q item is finished
237       h->item.status=READY;
238     }
239     q->tail=(MemoryQueueItem*)h;
240     // handle the the queue item case
241     if(q->head->type==3){
242       q->head=(MemoryQueueItem*)h;
243     }
244   }
245
246   //at this point, have table
247   Hashtable* table=(Hashtable*)q->tail;
248   r->hashtable=table; // set rentry's hashtable
249   if((*(r->pointer)==0 || (*(r->pointer)!=0 && BARRIER() && table->unresolvedQueue!=NULL))){
250     struct Queue* val;
251     // grab lock on the queue    
252     do {  
253       val=(struct Queue*)0x1;       
254       val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
255     } while(val==(struct Queue*)0x1);     
256     if(val==NULL){
257       //queue is null, first case
258       if(*(r->pointer)!=0){
259         // check whether pointer is already resolved, or not.
260         table->unresolvedQueue=NULL; //released lock;
261         return ADDTABLEITEM(table,r,TRUE);
262       }
263       struct Queue* queue=createQueue();
264       addNewItemBack(queue,r);
265       atomic_inc(&table->item.total); 
266       table->unresolvedQueue=queue; // expose new queue     
267     }else{ 
268       // add unresolved rentry at the end of the queue.
269       addNewItemBack(val,r);
270       atomic_inc(&table->item.total);    
271       table->unresolvedQueue=val; // released lock
272     }   
273     return NOTREADY;
274   }
275   BinItem * val;
276   //int key=generateKey((unsigned int)(unsigned INTPTR)*(r->pointer));  
277   int key=generateKey(r->oid);
278   do {  
279     val=(BinItem*)0x1;       
280     BinElement* bin=table->array[key];
281     val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);//note...talk to me about optimizations here. 
282   } while(val==(BinItem*)0x1);
283   //at this point have locked bin
284   if (val==NULL) {
285     return EMPTYBINCASE(table, table->array[key], r, TRUE);
286   } else {
287     if (isFineWrite(r)) {
288       return WRITEBINCASE(table, r, val, key, TRUE);
289     } else if (isFineRead(r)) {
290       return READBINCASE(table, r, val, key, TRUE);
291     }
292   }
293 }
294
295 int ADDTABLEITEM(Hashtable* table, REntry* r, int inc){
296  
297   BinItem * val;
298   //  int key=generateKey((unsigned int)(unsigned INTPTR)*(r->pointer));
299   int key=generateKey(r->oid);
300   do {  
301     val=(BinItem*)0x1;       
302     BinElement* bin=table->array[key];
303     val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val); 
304   } while(val==(BinItem*)0x1);
305   //at this point have locked bin
306   if (val==NULL) {
307     return EMPTYBINCASE(table, table->array[key], r, inc);
308   } else {
309     if (isFineWrite(r)) {
310       return WRITEBINCASE(table, r, val, key, inc);
311     } else if (isFineRead(r)) {
312       return READBINCASE(table, r, val, key, inc);
313     }
314   }
315 }
316
317 int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r, int inc) {
318   int retval;
319   BinItem* b;
320   if (isFineWrite(r)) {
321     b=(BinItem*)createWriteBinItem();
322     ((WriteBinItem*)b)->val=r;//<-only different statement
323   } else if (isFineRead(r)) {
324     b=(BinItem*)createReadBinItem();
325     ReadBinItem* readbin=(ReadBinItem*)b;
326     readbin->array[readbin->index++]=r;
327   }
328   b->total=1;
329
330   if (T->item.status==READY) { 
331     //current entry is ready
332     b->status=READY;
333     retval=READY;
334     if (isParent(r)) {
335       be->head=NULL; // released lock
336       return retval;
337     }
338   } else {
339     b->status=NOTREADY;
340     retval=NOTREADY;
341   }
342
343   if(inc){
344     atomic_inc(&T->item.total);
345   }
346   r->hashtable=T;
347   r->binitem=b;
348   be->tail=b;
349   be->head=b;//released lock
350   return retval;
351 }
352
353 int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) {
354   //chain of bins exists => tail is valid
355   //if there is something in front of us, then we are not ready
356
357   int retval;
358   BinElement* be=T->array[key];
359
360   BinItem *bintail=be->tail;
361
362   WriteBinItem *b=createWriteBinItem();
363   b->val=r;
364   b->item.total=1;
365
366   // note: If current table clears all dependencies, then write bin is ready
367   if (T->item.total==0){
368     retval=READY;    
369   }else{
370     retval=NOTREADY;
371   }
372   b->item.status=retval;
373   //  b->item.status=NOTREADY;
374   
375   if(inc){
376     atomic_inc(&T->item.total);
377   }
378
379   r->hashtable=T;
380   r->binitem=(BinItem*)b;
381
382   be->tail->next=(BinItem*)b;
383   be->tail=(BinItem*)b;
384   be->head=val;
385   return retval;
386 }
387
388 READBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) {
389   BinItem * bintail=T->array[key]->tail;
390   if (isReadBinItem(bintail)) {
391     return TAILREADCASE(T, r, val, bintail, key, inc);
392   } else if (!isReadBinItem(bintail)) {
393     TAILWRITECASE(T, r, val, bintail, key, inc);
394     return NOTREADY;
395   }
396 }
397
398 int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
399   ReadBinItem * readbintail=(ReadBinItem*)T->array[key]->tail;
400   int status, retval;
401   if (readbintail->item.status=READY) { 
402     status=READY;
403     retval=READY;
404     if (isParent(r)) {
405       T->array[key]->head=val;//released lock
406       return READY;
407     }
408   } else {
409     status=NOTREADY;
410     retval=NOTREADY;
411   }
412
413   if (readbintail->index==NUMREAD) { // create new read group
414     ReadBinItem* rb=createReadBinItem();
415     rb->array[rb->index++]=r;
416     rb->item.total=1;//safe only because item could not have started
417     rb->item.status=status;
418     T->array[key]->tail->next=(BinItem*)rb;
419     T->array[key]->tail=(BinItem*)rb;
420     r->binitem=(BinItem*)rb;
421   } else { // group into old tail
422     readbintail->array[readbintail->index++]=r;
423     atomic_inc(&readbintail->item.total);
424     r->binitem=(BinItem*)readbintail;
425     //printf("grouping with %d\n",readbintail->index);
426   }
427   if(inc){
428     atomic_inc(&T->item.total);
429   }
430   r->hashtable=T;
431   T->array[key]->head=val;//released lock
432   return retval;
433 }
434
435 TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
436   //  WriteBinItem* wb=createWriteBinItem();
437   //wb->val=r;
438   //wb->item.total=1;//safe because item could not have started
439   //wb->item.status=NOTREADY;
440   ReadBinItem* rb=createReadBinItem();
441   rb->array[rb->index++]=r;
442   rb->item.total=1;//safe because item could not have started
443   rb->item.status=NOTREADY;
444   if(inc){
445     atomic_inc(&T->item.total);
446   }
447   r->hashtable=T;
448   r->binitem=(BinItem*)rb;
449   T->array[key]->tail->next=(BinItem*)rb;
450   T->array[key]->tail=(BinItem*)rb;
451   T->array[key]->head=val;//released lock
452 }
453
454 ADDVECTOR(MemoryQueue *Q, REntry *r) {
455   if(!isVector(Q->tail)) {
456     //Fast Case
457     if (isParentCoarse(r) && Q->tail->total==0 && Q->tail==Q->head) { 
458       return READY;
459     }
460
461     //added vector
462     Vector* V=createVector();
463     Q->tail->next=(MemoryQueueItem*)V;     
464     //************NEED memory barrier here to ensure compiler does not cache Q.tail.status******
465     if (BARRIER() && Q->tail->status==READY&&Q->tail->total==0) { 
466       //previous Q item is finished
467       V->item.status=READY;
468     }
469     Q->tail=(MemoryQueueItem*)V;
470     // handle the the queue item case
471     if(Q->head->type==3){
472       Q->head=(MemoryQueueItem*)V;
473     }
474   }
475   //at this point, have vector
476   Vector* V=(Vector*)Q->tail;
477   if (V->index==NUMITEMS) {
478     //vector is full
479     //added vector
480     V=createVector();
481     V->item.status=NOTREADY;
482     Q->tail->next=(MemoryQueueItem*)V;
483     //***NEED memory barrier here to ensure compiler does not cache Q.tail.status******
484     if (BARRIER() && Q->tail->status==READY) { 
485       V->item.status=READY;
486     }
487     Q->tail=(MemoryQueueItem*)V;
488   }
489
490   atomic_inc(&V->item.total);
491   //expose entry
492   int index=V->index;
493   V->array[index]=r;
494   //*****NEED memory barrier here to ensure compiler does not reorder writes to V.array and V.index
495   BARRIER();
496   V->index++;
497   //*****NEED memory barrier here to ensure compiler does not cache V.status*********
498   r->vector=V;
499   if (BARRIER() && V->item.status==READY) {
500     void* flag=NULL;
501     flag=(void*)LOCKXCHG((unsigned INTPTR*)&(V->array[index]), (unsigned INTPTR)flag); 
502     if (flag!=NULL) {
503       if (isParent(r)) { //parent's retire immediately
504         atomic_dec(&V->item.total);
505       }
506       return READY;
507     } else {
508       return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
509     }
510   } else {
511     return NOTREADY;
512   }
513 }
514
515
516 //SCC's don't come in parent variety
517 ADDSCC(MemoryQueue *Q, REntry *r) {
518   //added SCC
519   SCC* S=createSCC();
520   S->item.total=1; 
521   S->val=r;
522   r->scc=S;
523   Q->tail->next=(MemoryQueueItem*)S;
524   //*** NEED BARRIER HERE
525   if (BARRIER() && Q->tail->status==READY && Q->tail->total==0 && Q->tail==Q->head) {
526     //previous Q item is finished
527     S->item.status=READY;
528     Q->tail=(MemoryQueueItem*)S;
529     // handle the the queue item case
530     if(Q->head->type==3){
531       Q->head=(MemoryQueueItem*)S;
532     }
533     void* flag=NULL;
534     flag=(void*)LOCKXCHG((unsigned INTPTR*)&(S->val), (unsigned INTPTR)flag);
535     if (flag!=NULL) {
536       return READY;
537     } else {
538       return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
539     }
540   } else {
541     Q->tail=(MemoryQueueItem*)S;
542     return NOTREADY;
543   }
544 }
545
546
547 void RETIRERENTRY(MemoryQueue* Q, REntry * r) {
548   if (isFineWrite(r)||isFineRead(r)) {
549     RETIREHASHTABLE(Q, r);
550   } else if (isCoarse(r)) {
551     RETIREVECTOR(Q, r);
552   } else if (isSCC(r)) {
553     RETIRESCC(Q, r);
554   }
555 }
556
557 RETIRESCC(MemoryQueue *Q, REntry *r) {
558   SCC* s=r->scc;
559   s->item.total=0;//don't need atomicdec
560   RESOLVECHAIN(Q);
561 }
562
563
564 RETIREHASHTABLE(MemoryQueue *q, REntry *r) {
565   Hashtable *T=r->hashtable;
566   BinItem *b=r->binitem;
567   RETIREBIN(T,r,b);
568   atomic_dec(&T->item.total);
569   if (T->item.next!=NULL && T->item.total==0) { 
570     RESOLVECHAIN(q);
571   }
572 }
573
574 RETIREBIN(Hashtable *T, REntry *r, BinItem *b) {
575   //  int key=generateKey((unsigned int)(unsigned INTPTR)*(r->pointer));
576   int key=generateKey(r->oid);
577   if(isFineRead(r)) {
578     atomic_dec(&b->total);
579   }
580   if (isFineWrite(r) || (isFineRead(r) && b->next!=NULL && b->total==0)) {
581       // CHECK FIRST IF next is nonnull to guarantee that b.total cannot change
582     BinItem * val;
583     do {  
584       val=(BinItem*)0x1;
585       val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(T->array[key]->head), (unsigned INTPTR)val);
586     } while(val==(BinItem*)0x1);
587     // at this point have locked bin
588     BinItem *ptr=val;
589     int haveread=FALSE;
590     int i;
591     while (ptr!=NULL) {
592        if (isReadBinItem(ptr)) {
593         ReadBinItem* rptr=(ReadBinItem*)ptr;
594         if (rptr->item.status==NOTREADY) {
595           for (i=0;i<rptr->index;i++) {     
596             resolveDependencies(rptr->array[i]);
597             if (isParent(rptr->array[i])) {
598               //parents go immediately
599               atomic_dec(&rptr->item.total);
600               atomic_dec(&T->item.total);
601             }
602           }
603         }
604         rptr->item.status=READY; 
605         if (rptr->item.next==NULL) {
606           break;
607         }
608         if (rptr->item.total!=0) {
609           haveread=TRUE; 
610         } else if ((BinItem*)rptr==val) {
611           val=val->next;
612         }
613       } else if(isWriteBinItem(ptr)) {
614         if (haveread)  
615           break;
616         if(ptr->status==NOTREADY){
617           resolveDependencies(((WriteBinItem*)ptr)->val);
618           ptr->status=READY;
619           if(isParent(((WriteBinItem*)ptr)->val)){
620             atomic_dec(&T->item.total);
621             val=val->next;        
622           }else
623             break;
624         }else{ // write bin is already resolved
625           val=val->next;
626         }
627         /*
628         if(ptr->status==NOTREADY) {   
629           resolveDependencies(((WriteBinItem*)ptr)->val);
630         }        
631           ptr->status=READY;      
632           if (isParent(((WriteBinItem*)ptr)->val)) {  
633             atomic_dec(&T->item.total);
634             //val=val->next;
635             val=ptr->next;
636           } else
637             break;
638         } 
639         */
640       } 
641       ptr=ptr->next;
642     }
643     T->array[key]->head=val; // release lock
644   }
645 }
646
647
648 RETIREVECTOR(MemoryQueue *Q, REntry *r) {
649   Vector* V=r->vector;
650   atomic_dec(&V->item.total);
651   if (V->item.next!=NULL && V->item.total==0) { //NOTE: ORDERING CRUCIAL HERE
652     RESOLVECHAIN(Q);
653   }
654 }
655
656 RESOLVECHAIN(MemoryQueue *Q) {
657   while(TRUE) {
658     MemoryQueueItem* head=Q->head;
659     if (head->next==NULL||head->total!=0) { 
660       //item is not finished
661       if (head->status!=READY) {  
662         //need to update status
663         head->status=READY;
664         if (isHashtable(head)) {
665           RESOLVEHASHTABLE(Q, head);
666         } else if (isVector(head)) {
667           RESOLVEVECTOR(Q, head);
668         } else if (isSingleItem(head)) {
669           RESOLVESCC(head);
670         }
671         if (head->next==NULL)
672           break;
673         if (head->total!=0)
674           break;
675       } else
676         break;
677     }
678     MemoryQueueItem* nextitem=head->next;
679     CAS((unsigned INTPTR*)&(Q->head), (unsigned INTPTR)head, (unsigned INTPTR)nextitem);
680     //oldvalue not needed...  if we fail we just repeat
681   }
682 }
683
684
685 RESOLVEHASHTABLE(MemoryQueue *Q, Hashtable *T) {  
686   int binidx;
687   for (binidx=0;binidx<NUMBINS;binidx++) {    
688     BinElement* bin=T->array[binidx];
689     BinItem* val;
690     do {
691       val=(BinItem*)1;
692       val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);
693     } while (val==(BinItem*)1);
694     //at this point have locked bin    
695     int haveread=FALSE; 
696     BinItem* ptr=val;
697     if(ptr!=NULL&&ptr->status==NOTREADY) {
698       do {
699         if (isWriteBinItem(ptr)) {
700           if (haveread)
701             break;        
702           resolveDependencies(((WriteBinItem*)ptr)->val);
703           ptr->status=READY;  
704           if (isParent(((WriteBinItem*)ptr)->val)) {
705             atomic_dec(&T->item.total);
706             val=val->next;
707           } else
708             break;
709         } else if (isReadBinItem(ptr)) {
710           int i;
711           ReadBinItem* rptr=(ReadBinItem*)ptr;
712           for(i=0;i<rptr->index;i++) {
713             resolveDependencies(rptr->array[i]);
714             if (isParent(rptr->array[i])) {
715               atomic_dec(&rptr->item.total);
716               atomic_dec(&T->item.total);
717             }
718           }
719           if (rptr->item.next==NULL||rptr->item.total!=0) {
720             haveread=TRUE;
721           } else if((BinItem*)rptr==val) {
722             val=val->next;
723           }
724           rptr->item.status=READY; { 
725           }
726           ptr=ptr->next;
727         } 
728       }while(ptr!=NULL);   
729     }
730     bin->head=val; // released lock;
731   }
732 }
733
734 RESOLVEVECTOR(MemoryQueue *q, Vector *V) {
735   int i;
736   Vector* tmp=V;
737   //handle ready cases
738   while(TRUE) {
739     //enqueue everything
740     for (i=0;i<NUMITEMS;i++) {
741       REntry* val=NULL;
742       val=(REntry*)LOCKXCHG((unsigned INTPTR*)&(tmp->array[i]), (unsigned INTPTR)val); 
743       if (val!=NULL) { 
744         resolveDependencies(val);
745         if (isParent(val)) {
746           atomic_dec(&tmp->item.total);
747         }
748       }
749     }
750     if (tmp->item.next!=NULL&&isVector(tmp->item.next)) {
751       tmp=(Vector*)tmp->item.next;
752     } else {
753       break;
754     }
755   }
756 }
757
758 RESOLVESCC(SCC *S) {
759   //precondition: SCC's state is READY
760   void* flag=NULL;
761   flag=(void*)LOCKXCHG((unsigned INTPTR*)&(S->val), (unsigned INTPTR)flag); 
762   if (flag!=NULL) {
763     resolveDependencies(flag);
764   }
765 }
766
767
768 resolveDependencies(REntry* rentry){
769   SESEcommon* seseCommon=(SESEcommon*)rentry->seseRec;
770   if(rentry->type==READ || rentry->type==WRITE || rentry->type==COARSE || rentry->type==SCCITEM){   
771     if( atomic_sub_and_test(1, &(seseCommon->unresolvedDependencies)) ){
772       workScheduleSubmit(seseCommon);
773     }   
774   }else if(rentry->type==PARENTREAD || rentry->type==PARENTWRITE ||rentry->type==PARENTCOARSE){
775      psem_give(&(rentry->parentStallSem));
776   }
777 }
778
779 resolvePointer(REntry* rentry){  
780  
781   Hashtable* table=rentry->hashtable;
782   if(table==NULL){
783     //resolved already before related rentry is enqueued to the waiting queue
784     return;
785   }
786   struct Queue* val;
787   do {  
788     val=(struct Queue*)0x1;       
789     val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
790   } while(val==(struct Queue*)0x1); 
791   if(val!=NULL && getHead(val)->objectptr==rentry){
792     // handling pointer is the first item of the queue
793     // start to resolve until it reaches unresolved pointer or end of queue
794     do{
795       struct QueueItem* head=getHead(val);
796       if(head!=NULL){
797         REntry* rentry=(REntry*)head->objectptr;  
798         if(*(rentry->pointer)==0){
799           // encounters following unresolved pointer
800           table->unresolvedQueue=val;//released lock
801           break;
802         }
803         removeItem(val,head);
804         //now, address is resolved. update OID field.
805         struct ___Object___ * obj=(struct ___Object___*)((unsigned INTPTR)*rentry->pointer);
806         rentry->oid=obj->oid;
807         if(ADDTABLEITEM(table, rentry, FALSE)==READY){
808           resolveDependencies(rentry);
809         }
810       }else{
811         table->unresolvedQueue=NULL; // set hashtable as normal-mode.
812         break;
813       }
814     }while(TRUE);
815   }else{
816     // resolved rentry is not head of queue
817     table->unresolvedQueue=val;//released lock;
818   }  
819 }
820
821 void rehashMemoryQueue(SESEcommon_p seseParent){    
822   // update memory queue
823   int i,binidx;
824   for(i=0; i<seseParent->numMemoryQueue; i++){
825     MemoryQueue *memoryQueue=seseParent->memoryQueueArray[i];
826     MemoryQueueItem *memoryItem=memoryQueue->head;
827     MemoryQueueItem *prevItem=NULL;
828     while(memoryItem!=NULL){
829       if(memoryItem->type==HASHTABLE){
830         //do re-hash!
831         Hashtable* ht=(Hashtable*)memoryItem;
832         Hashtable* newht=createHashtable();     
833         int binidx;
834         for(binidx=0; binidx<NUMBINS; binidx++){
835           BinElement *bin=ht->array[binidx];
836           BinItem *binItem=bin->head;
837           //traverse over the list of each bin
838           while(binItem!=NULL){
839             if(binItem->type==READBIN){
840               ReadBinItem* readBinItem=(ReadBinItem*)binItem;
841               int ridx;
842               for(ridx=0; ridx<readBinItem->index; ridx++){
843                 REntry *rentry=readBinItem->array[ridx];
844                 int newkey=generateKey((unsigned int)(unsigned INTPTR)*(rentry->pointer));      
845                 int status=rentry->binitem->status;           
846                 ADDTABLEITEM(newht,rentry,TRUE);
847                 rentry->binitem->status=status; // update bin status as before rehash
848               }
849             }else{//write bin
850               REntry *rentry=((WriteBinItem*)binItem)->val;
851               int newkey=generateKey((unsigned int)(unsigned INTPTR)*(rentry->pointer));        
852               int status=rentry->binitem->status;             
853               ADDTABLEITEM(newht,rentry,TRUE);                
854               int newstatus=rentry->binitem->status;
855               //printf("[%d]old status=%d new status=%d\n",i,status,newstatus);
856               rentry->binitem->status=status; // update bin status as before rehash
857             }
858             binItem=binItem->next;
859           }
860         }
861         newht->item.status=ht->item.status; // update hashtable status
862         if(prevItem!=NULL){
863           prevItem->next=(MemoryQueueItem*)newht;
864         }else{
865           if(memoryQueue->head==memoryQueue->tail){
866             memoryQueue->tail=(MemoryQueueItem*)newht;
867           }
868           memoryQueue->head=(MemoryQueueItem*)newht;
869         }
870         newht->item.next=ht->item.next; 
871       }
872       prevItem=memoryItem;
873       memoryItem=memoryItem->next;
874     }
875   }
876
877 }