8 #include "mlp_runtime.h"
9 #include "workschedule.h"
10 #include "methodheaders.h"
15 __thread struct Queue* seseCallStack;
16 __thread pthread_once_t mlpOnceObj = PTHREAD_ONCE_INIT;
17 void mlpInitOncePerThread() {
18 seseCallStack = createQueue();
21 __thread SESEcommon_p seseCaller;
24 void* mlpAllocSESErecord( int size ) {
25 void* newrec = RUNMALLOC( size );
27 printf( "mlpAllocSESErecord did not obtain memory!\n" );
34 void mlpFreeSESErecord( void* seseRecord ) {
35 RUNFREE( seseRecord );
38 MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue){
40 MemoryQueue** newMemoryQueue=(MemoryQueue**)RUNMALLOC( sizeof( MemoryQueue* ) * numMemoryQueue );
41 for(i=0; i<numMemoryQueue; i++){
42 newMemoryQueue[i]=createMemoryQueue();
44 return newMemoryQueue;
47 REntry* mlpCreateREntryArray(){
48 REntry* newREntryArray=(REntry*)RUNMALLOC(sizeof(REntry)*NUMRENTRY);
49 return newREntryArray;
52 REntry* mlpCreateFineREntry(int type, void* seseToIssue, void* dynID){
53 REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry));
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;
64 REntry* mlpCreateREntry(int type, void* seseToIssue){
65 REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry));
67 newREntry->seseRec=seseToIssue;
71 int isParent(REntry *r) {
72 if (r->type==PARENTREAD || r->type==PARENTWRITE || r->type==PARENTCOARSE) {
79 int isParentCoarse(REntry *r){
80 if (r->type==PARENTCOARSE){
87 int isFineRead(REntry *r) {
88 if (r->type==READ || r->type==PARENTREAD) {
95 int isFineWrite(REntry *r) {
96 if (r->type==WRITE || r->type==PARENTWRITE) {
103 int isCoarse(REntry *r){
104 if(r->type==COARSE || r->type==PARENTCOARSE){
111 int isSCC(REntry *r){
112 if(r->type==SCCITEM){
119 int isSingleItem(MemoryQueueItem *qItem){
120 if(qItem->type==SINGLEITEM){
127 int isHashtable(MemoryQueueItem *qItem){
128 if(qItem->type==HASHTABLE){
135 int isVector(MemoryQueueItem *qItem){
136 if(qItem->type==VECTOR){
143 int isReadBinItem(BinItem* b){
144 if(b->type==READBIN){
151 int isWriteBinItem(BinItem* b){
152 if(b->type==WRITEBIN){
159 int generateKey(unsigned int data){
160 return (data&H_MASK)>> 4;
163 Hashtable* createHashtable(){
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;
172 newTable->unresolvedQueue=NULL;
176 WriteBinItem* createWriteBinItem(){
177 WriteBinItem* binitem=(WriteBinItem*)RUNMALLOC(sizeof(WriteBinItem));
178 binitem->item.type=WRITEBIN;
182 ReadBinItem* createReadBinItem(){
183 ReadBinItem* binitem=(ReadBinItem*)RUNMALLOC(sizeof(ReadBinItem));
185 binitem->item.type=READBIN;
189 Vector* createVector(){
190 Vector* vector=(Vector*)RUNMALLOC(sizeof(Vector));
192 vector->item.type=VECTOR;
197 SCC* scc=(SCC*)RUNMALLOC(sizeof(SCC));
198 scc->item.type=SINGLEITEM;
202 MemoryQueue* createMemoryQueue(){
203 MemoryQueue* queue = (MemoryQueue*)RUNMALLOC(sizeof(MemoryQueue));
204 MemoryQueueItem* dummy=(MemoryQueueItem*)RUNMALLOC(sizeof(MemoryQueueItem));
205 dummy->type=3; // dummy type
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)) {
223 int ADDTABLE(MemoryQueue *q, REntry *r) {
224 if(!isHashtable(q->tail)) {
226 MemoryQueueItem* tail=q->tail;
227 if (isParent(r) && tail->total==0 && q->tail==q->head) {
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;
239 q->tail=(MemoryQueueItem*)h;
240 // handle the the queue item case
241 if(q->head->type==3){
242 q->head=(MemoryQueueItem*)h;
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))){
251 // grab lock on the queue
253 val=(struct Queue*)0x1;
254 val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
255 } while(val==(struct Queue*)0x1);
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);
263 struct Queue* queue=createQueue();
264 addNewItemBack(queue,r);
265 atomic_inc(&table->item.total);
266 table->unresolvedQueue=queue; // expose new queue
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
276 //int key=generateKey((unsigned int)(unsigned INTPTR)*(r->pointer));
277 int key=generateKey(r->oid);
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
285 return EMPTYBINCASE(table, table->array[key], r, TRUE);
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);
295 int ADDTABLEITEM(Hashtable* table, REntry* r, int inc){
298 // int key=generateKey((unsigned int)(unsigned INTPTR)*(r->pointer));
299 int key=generateKey(r->oid);
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
307 return EMPTYBINCASE(table, table->array[key], r, inc);
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);
317 int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r, int inc) {
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;
330 if (T->item.status==READY) {
331 //current entry is ready
335 be->head=NULL; // released lock
344 atomic_inc(&T->item.total);
349 be->head=b;//released lock
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
358 BinElement* be=T->array[key];
360 BinItem *bintail=be->tail;
362 WriteBinItem *b=createWriteBinItem();
366 // note: If current table clears all dependencies, then write bin is ready
370 atomic_inc(&T->item.total);
374 r->binitem=(BinItem*)b;
376 be->tail->next=(BinItem*)b;
377 //need to check if we can go...
379 if (T->item.status==READY) {
380 for(;val!=NULL;val=val->next) {
381 if (val==((BinItem *)b)) {
385 b->item.status=retval;//unsure if really needed at this point..
386 be->head=NULL; // released lock
390 } else if (val->total!=0) {
396 b->item.status=retval;
397 be->tail=(BinItem*)b;
402 READBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) {
403 BinItem * bintail=T->array[key]->tail;
404 if (isReadBinItem(bintail)) {
405 return TAILREADCASE(T, r, val, bintail, key, inc);
406 } else if (!isReadBinItem(bintail)) {
407 TAILWRITECASE(T, r, val, bintail, key, inc);
412 int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
413 ReadBinItem * readbintail=(ReadBinItem*)T->array[key]->tail;
415 if (readbintail->item.status==READY) {
419 T->array[key]->head=val;//released lock
427 if (readbintail->index==NUMREAD) { // create new read group
428 ReadBinItem* rb=createReadBinItem();
429 rb->array[rb->index++]=r;
430 rb->item.total=1;//safe only because item could not have started
431 rb->item.status=status;
432 T->array[key]->tail->next=(BinItem*)rb;
433 T->array[key]->tail=(BinItem*)rb;
434 r->binitem=(BinItem*)rb;
435 } else { // group into old tail
436 readbintail->array[readbintail->index++]=r;
437 atomic_inc(&readbintail->item.total);
438 r->binitem=(BinItem*)readbintail;
439 //printf("grouping with %d\n",readbintail->index);
442 atomic_inc(&T->item.total);
445 T->array[key]->head=val;//released lock
449 TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
450 // WriteBinItem* wb=createWriteBinItem();
452 //wb->item.total=1;//safe because item could not have started
453 //wb->item.status=NOTREADY;
454 ReadBinItem* rb=createReadBinItem();
455 rb->array[rb->index++]=r;
456 rb->item.total=1;//safe because item could not have started
457 rb->item.status=NOTREADY;
459 atomic_inc(&T->item.total);
462 r->binitem=(BinItem*)rb;
463 T->array[key]->tail->next=(BinItem*)rb;
464 T->array[key]->tail=(BinItem*)rb;
465 T->array[key]->head=val;//released lock
468 ADDVECTOR(MemoryQueue *Q, REntry *r) {
469 if(!isVector(Q->tail)) {
471 if (isParentCoarse(r) && Q->tail->total==0 && Q->tail==Q->head) {
476 Vector* V=createVector();
477 Q->tail->next=(MemoryQueueItem*)V;
478 //************NEED memory barrier here to ensure compiler does not cache Q.tail.status******
479 if (BARRIER() && Q->tail->status==READY&&Q->tail->total==0) {
480 //previous Q item is finished
481 V->item.status=READY;
483 Q->tail=(MemoryQueueItem*)V;
484 // handle the the queue item case
485 if(Q->head->type==3){
486 Q->head=(MemoryQueueItem*)V;
489 //at this point, have vector
490 Vector* V=(Vector*)Q->tail;
491 if (V->index==NUMITEMS) {
495 V->item.status=NOTREADY;
496 Q->tail->next=(MemoryQueueItem*)V;
497 //***NEED memory barrier here to ensure compiler does not cache Q.tail.status******
498 if (BARRIER() && Q->tail->status==READY) {
499 V->item.status=READY;
501 Q->tail=(MemoryQueueItem*)V;
504 atomic_inc(&V->item.total);
508 //*****NEED memory barrier here to ensure compiler does not reorder writes to V.array and V.index
511 //*****NEED memory barrier here to ensure compiler does not cache V.status*********
513 if (BARRIER() && V->item.status==READY) {
515 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(V->array[index]), (unsigned INTPTR)flag);
517 if (isParentCoarse(r)) { //parent's retire immediately
518 atomic_dec(&V->item.total);
523 return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
531 //SCC's don't come in parent variety
532 ADDSCC(MemoryQueue *Q, REntry *r) {
538 Q->tail->next=(MemoryQueueItem*)S;
539 //*** NEED BARRIER HERE
540 if (BARRIER() && Q->tail->status==READY && Q->tail->total==0 && Q->tail==Q->head) {
541 //previous Q item is finished
542 S->item.status=READY;
543 Q->tail=(MemoryQueueItem*)S;
544 // handle the the queue item case
545 if(Q->head->type==3){
546 Q->head=(MemoryQueueItem*)S;
549 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(S->val), (unsigned INTPTR)flag);
553 return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
556 Q->tail=(MemoryQueueItem*)S;
562 void RETIRERENTRY(MemoryQueue* Q, REntry * r) {
563 if (isFineWrite(r)||isFineRead(r)) {
564 RETIREHASHTABLE(Q, r);
565 } else if (isCoarse(r)) {
567 } else if (isSCC(r)) {
572 RETIRESCC(MemoryQueue *Q, REntry *r) {
574 s->item.total=0;//don't need atomicdec
579 RETIREHASHTABLE(MemoryQueue *q, REntry *r) {
580 Hashtable *T=r->hashtable;
581 BinItem *b=r->binitem;
583 atomic_dec(&T->item.total);
584 if (T->item.next!=NULL && T->item.total==0) {
589 RETIREBIN(Hashtable *T, REntry *r, BinItem *b) {
590 // int key=generateKey((unsigned int)(unsigned INTPTR)*(r->pointer));
591 int key=generateKey(r->oid);
593 atomic_dec(&b->total);
595 if (isFineWrite(r) || (isFineRead(r) && b->next!=NULL && b->total==0)) {
596 // CHECK FIRST IF next is nonnull to guarantee that b.total cannot change
600 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(T->array[key]->head), (unsigned INTPTR)val);
601 } while(val==(BinItem*)0x1);
602 // at this point have locked bin
607 if (isReadBinItem(ptr)) {
608 ReadBinItem* rptr=(ReadBinItem*)ptr;
609 if (rptr->item.status==NOTREADY) {
610 for (i=0;i<rptr->index;i++) {
611 resolveDependencies(rptr->array[i]);
612 if (isParent(rptr->array[i])) {
613 //parents go immediately
614 atomic_dec(&rptr->item.total);
615 atomic_dec(&T->item.total);
619 rptr->item.status=READY;
620 if (rptr->item.next==NULL) {
623 if (rptr->item.total!=0) {
625 } else if ((BinItem*)rptr==val) {
628 } else if(isWriteBinItem(ptr)) {
631 if(ptr->status==NOTREADY){
632 resolveDependencies(((WriteBinItem*)ptr)->val);
634 if(isParent(((WriteBinItem*)ptr)->val)){
635 atomic_dec(&T->item.total);
639 }else{ // write bin is already resolved
643 if(ptr->status==NOTREADY) {
644 resolveDependencies(((WriteBinItem*)ptr)->val);
647 if (isParent(((WriteBinItem*)ptr)->val)) {
648 atomic_dec(&T->item.total);
658 T->array[key]->head=val; // release lock
663 RETIREVECTOR(MemoryQueue *Q, REntry *r) {
665 atomic_dec(&V->item.total);
666 if (V->item.next!=NULL && V->item.total==0) { //NOTE: ORDERING CRUCIAL HERE
671 RESOLVECHAIN(MemoryQueue *Q) {
673 MemoryQueueItem* head=Q->head;
674 if (head->next==NULL||head->total!=0) {
675 //item is not finished
676 if (head->status!=READY) {
677 //need to update status
679 if (isHashtable(head)) {
680 RESOLVEHASHTABLE(Q, head);
681 } else if (isVector(head)) {
682 RESOLVEVECTOR(Q, head);
683 } else if (isSingleItem(head)) {
686 if (head->next==NULL)
693 MemoryQueueItem* nextitem=head->next;
694 CAS((unsigned INTPTR*)&(Q->head), (unsigned INTPTR)head, (unsigned INTPTR)nextitem);
695 //oldvalue not needed... if we fail we just repeat
700 RESOLVEHASHTABLE(MemoryQueue *Q, Hashtable *T) {
702 for (binidx=0;binidx<NUMBINS;binidx++) {
703 BinElement* bin=T->array[binidx];
707 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);
708 } while (val==(BinItem*)1);
709 //at this point have locked bin
712 if(ptr!=NULL&&ptr->status==NOTREADY) {
714 if (isWriteBinItem(ptr)) {
717 resolveDependencies(((WriteBinItem*)ptr)->val);
719 if (isParent(((WriteBinItem*)ptr)->val)) {
720 atomic_dec(&T->item.total);
724 } else if (isReadBinItem(ptr)) {
726 ReadBinItem* rptr=(ReadBinItem*)ptr;
727 for(i=0;i<rptr->index;i++) {
728 resolveDependencies(rptr->array[i]);
729 if (isParent(rptr->array[i])) {
730 atomic_dec(&rptr->item.total);
731 atomic_dec(&T->item.total);
734 if (rptr->item.next==NULL||rptr->item.total!=0) {
736 } else if((BinItem*)rptr==val) {
739 rptr->item.status=READY;
744 bin->head=val; // released lock;
748 RESOLVEVECTOR(MemoryQueue *q, Vector *V) {
754 for (i=0;i<NUMITEMS;i++) {
756 val=(REntry*)LOCKXCHG((unsigned INTPTR*)&(tmp->array[i]), (unsigned INTPTR)val);
758 resolveDependencies(val);
760 atomic_dec(&tmp->item.total);
764 if (tmp->item.next!=NULL&&isVector(tmp->item.next)) {
765 tmp=(Vector*)tmp->item.next;
773 //precondition: SCC's state is READY
775 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(S->val), (unsigned INTPTR)flag);
777 resolveDependencies(flag);
782 resolveDependencies(REntry* rentry){
783 SESEcommon* seseCommon=(SESEcommon*)rentry->seseRec;
784 if(rentry->type==READ || rentry->type==WRITE || rentry->type==COARSE || rentry->type==SCCITEM){
785 if( atomic_sub_and_test(1, &(seseCommon->unresolvedDependencies)) ){
786 workScheduleSubmit(seseCommon);
788 }else if(rentry->type==PARENTREAD || rentry->type==PARENTWRITE ||rentry->type==PARENTCOARSE){
789 psem_give(&(rentry->parentStallSem));
793 void INITIALIZEBUF(MemoryQueue * q){
795 for(i=0; i<NUMBINS; i++){
801 void ADDRENTRYTOBUF(MemoryQueue * q, REntry * r){
802 q->buf[q->bufcount]=r;
806 int RESOLVEBUFFORHASHTABLE(MemoryQueue * q, Hashtable* table, SESEcommon *seseCommon){
808 // first phase: only consider write rentry
809 for(i=0; i<q->bufcount;i++){
812 int key=generateKey(r->oid);
813 if(q->binbuf[key]==NULL){
814 // for multiple writes, add only the first write that hashes to the same bin
821 // second phase: enqueue read items if it is eligible
822 for(i=0; i<q->bufcount;i++){
824 if(r!=NULL && r->type==READ){
825 int key=generateKey(r->oid);
826 if(q->binbuf[key]==NULL){
827 // read item that hashes to the bin which doen't contain any write
828 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
829 if(ADDTABLEITEM(table, r, FALSE)==READY){
830 resolveDependencies(r);
837 // then, add only one of write items that hashes to the same bin
838 for(i=0; i<q->bufcount;i++){
841 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
842 if(ADDTABLEITEM(table, r, FALSE)==READY){
843 resolveDependencies(r);
849 int RESOLVEBUF(MemoryQueue * q, SESEcommon *seseCommon){
852 // check if every waiting entry is resolved
853 // if not, defer every items for hashtable until it is resolved.
854 int unresolved=FALSE;
855 for(i=0; i<q->bufcount;i++){
857 if(*(r->pointer)==0){
861 if(unresolved==TRUE){
862 for(i=0; i<q->bufcount;i++){
866 if(ADDRENTRY(q,r)==NOTREADY){
873 // first phase: only consider write rentry
874 for(i=0; i<q->bufcount;i++){
877 int key=generateKey(r->oid);
878 if(q->binbuf[key]==NULL){
879 // for multiple writes, add only the first write that hashes to the same bin
886 // second phase: enqueue read items if it is eligible
887 for(i=0; i<q->bufcount;i++){
889 if(r!=NULL && r->type==READ){
890 int key=generateKey(r->oid);
891 if(q->binbuf[key]==NULL){
892 // read item that hashes to the bin which doen't contain any write
893 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
894 if(ADDRENTRY(q,r)==NOTREADY){
902 // then, add only one of write items that hashes to the same bin
903 for(i=0; i<q->bufcount;i++){
906 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
907 if(ADDRENTRY(q,r)==NOTREADY){
916 resolvePointer(REntry* rentry){
918 Hashtable* table=rentry->hashtable;
921 //resolved already before related rentry is enqueued to the waiting queue
926 val=(struct Queue*)0x1;
927 val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
928 } while(val==(struct Queue*)0x1);
929 if(val!=NULL && getHead(val)->objectptr==rentry){
930 // handling pointer is the first item of the queue
931 // start to resolve until it reaches unresolved pointer or end of queue
932 INTPTR currentSESE=0;
934 struct QueueItem* head=getHead(val);
936 REntry* rentry=(REntry*)head->objectptr;
937 if(*(rentry->pointer)==0){
938 // encounters following unresolved pointer
939 table->unresolvedQueue=val;//released lock
942 removeItem(val,head);
943 //now, address is resolved. update OID field.
944 struct ___Object___ * obj=(struct ___Object___*)((unsigned INTPTR)*rentry->pointer);
945 rentry->oid=obj->oid;
947 //check if rentry is buffer mode
948 if(rentry->isBufMode==TRUE){
951 INITIALIZEBUF(queue);
952 currentSESE=(INTPTR)rentry;
953 ADDRENTRYTOBUF(queue,rentry);
954 } else if(currentSESE==(INTPTR)rentry){
955 ADDRENTRYTOBUF(queue,rentry);
956 } else if(currentSESE!=(INTPTR)rentry){
957 RESOLVEBUFFORHASHTABLE(queue,table,(SESEcommon*)rentry->seseRec);
958 currentSESE=(INTPTR)rentry;
959 INITIALIZEBUF(queue);
960 ADDRENTRYTOBUF(rentry->queue,rentry);
964 //previous SESE has buf mode, need to invoke resolve buffer
965 RESOLVEBUFFORHASHTABLE(queue,table,(SESEcommon*)rentry->seseRec);
969 if(ADDTABLEITEM(table, rentry, FALSE)==READY){
970 resolveDependencies(rentry);
974 table->unresolvedQueue=NULL; // set hashtable as normal-mode.
979 // resolved rentry is not head of queue
980 table->unresolvedQueue=val;//released lock;
984 void rehashMemoryQueue(SESEcommon_p seseParent){
986 // update memory queue
988 for(i=0; i<seseParent->numMemoryQueue; i++){
989 MemoryQueue *memoryQueue=seseParent->memoryQueueArray[i];
990 MemoryQueueItem *memoryItem=memoryQueue->head;
991 MemoryQueueItem *prevItem=NULL;
992 while(memoryItem!=NULL){
993 if(memoryItem->type==HASHTABLE){
995 Hashtable* ht=(Hashtable*)memoryItem;
996 Hashtable* newht=createHashtable();
998 for(binidx=0; binidx<NUMBINS; binidx++){
999 BinElement *bin=ht->array[binidx];
1000 BinItem *binItem=bin->head;
1001 //traverse over the list of each bin
1002 while(binItem!=NULL){
1003 if(binItem->type==READBIN){
1004 ReadBinItem* readBinItem=(ReadBinItem*)binItem;
1006 for(ridx=0; ridx<readBinItem->index; ridx++){
1007 REntry *rentry=readBinItem->array[ridx];
1008 int newkey=generateKey((unsigned int)(unsigned INTPTR)*(rentry->pointer));
1009 int status=rentry->binitem->status;
1010 ADDTABLEITEM(newht,rentry,TRUE);
1011 rentry->binitem->status=status; // update bin status as before rehash
1014 REntry *rentry=((WriteBinItem*)binItem)->val;
1015 int newkey=generateKey((unsigned int)(unsigned INTPTR)*(rentry->pointer));
1016 int status=rentry->binitem->status;
1017 ADDTABLEITEM(newht,rentry,TRUE);
1018 int newstatus=rentry->binitem->status;
1019 //printf("[%d]old status=%d new status=%d\n",i,status,newstatus);
1020 rentry->binitem->status=status; // update bin status as before rehash
1022 binItem=binItem->next;
1025 newht->item.status=ht->item.status; // update hashtable status
1027 prevItem->next=(MemoryQueueItem*)newht;
1029 if(memoryQueue->head==memoryQueue->tail){
1030 memoryQueue->tail=(MemoryQueueItem*)newht;
1032 memoryQueue->head=(MemoryQueueItem*)newht;
1034 newht->item.next=ht->item.next;
1036 prevItem=memoryItem;
1037 memoryItem=memoryItem->next;