8 #include "mlp_runtime.h"
9 #include "workschedule.h"
10 #include "methodheaders.h"
13 __thread SESEcommon* runningSESE;
15 __thread psemaphore runningSESEstallSem;
19 void* mlpAllocSESErecord( int size ) {
20 void* newrec = RUNMALLOC( size );
22 printf( "mlpAllocSESErecord did not obtain memory!\n" );
28 void mlpFreeSESErecord( SESEcommon* seseRecord ) {
29 RUNFREE( seseRecord );
32 MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue){
34 MemoryQueue** newMemoryQueue=(MemoryQueue**)RUNMALLOC( sizeof( MemoryQueue* ) * numMemoryQueue );
35 for(i=0; i<numMemoryQueue; i++){
36 newMemoryQueue[i]=createMemoryQueue();
38 return newMemoryQueue;
41 REntry* mlpCreateREntryArray(){
42 REntry* newREntryArray=(REntry*)RUNMALLOC(sizeof(REntry)*NUMRENTRY);
43 return newREntryArray;
46 REntry* mlpCreateFineREntry(int type, SESEcommon* seseToIssue, void* dynID){
47 REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry));
49 newREntry->seseRec=seseToIssue;
50 newREntry->pointer=dynID;
54 REntry* mlpCreateREntry(int type, SESEcommon* seseToIssue){
55 REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry));
57 newREntry->seseRec=seseToIssue;
61 int isParent(REntry *r) {
62 if (r->type==PARENTREAD || r->type==PARENTWRITE || r->type==PARENTCOARSE) {
69 int isParentCoarse(REntry *r){
70 if (r->type==PARENTCOARSE){
77 int isFineRead(REntry *r) {
78 if (r->type==READ || r->type==PARENTREAD) {
85 int isFineWrite(REntry *r) {
86 if (r->type==WRITE || r->type==PARENTWRITE) {
93 int isCoarse(REntry *r){
94 if(r->type==COARSE || r->type==PARENTCOARSE){
101 int isSCC(REntry *r){
102 if(r->type==SCCITEM){
109 int isSingleItem(MemoryQueueItem *qItem){
110 if(qItem->type==SINGLEITEM){
117 int isHashtable(MemoryQueueItem *qItem){
118 if(qItem->type==HASHTABLE){
125 int isVector(MemoryQueueItem *qItem){
126 if(qItem->type==VECTOR){
133 int isReadBinItem(BinItem* b){
134 if(b->type==READBIN){
141 int isWriteBinItem(BinItem* b){
142 if(b->type==WRITEBIN){
149 int generateKey(unsigned int data){
150 return (data&H_MASK);
153 Hashtable* createHashtable(){
155 Hashtable* newTable=(Hashtable*)RUNMALLOC(sizeof(Hashtable));
156 newTable->item.type=HASHTABLE;
157 for(i=0;i<NUMBINS;i++){
158 newTable->array[i]=(BinElement*)RUNMALLOC(sizeof(BinElement));
159 newTable->array[i]->head=NULL;
160 newTable->array[i]->tail=NULL;
162 newTable->unresolvedQueue=NULL;
166 WriteBinItem* createWriteBinItem(){
167 WriteBinItem* binitem=(WriteBinItem*)RUNMALLOC(sizeof(WriteBinItem));
168 binitem->item.type=WRITEBIN;
172 ReadBinItem* createReadBinItem(){
173 ReadBinItem* binitem=(ReadBinItem*)RUNMALLOC(sizeof(ReadBinItem));
175 binitem->item.type=READBIN;
179 Vector* createVector(){
180 Vector* vector=(Vector*)RUNMALLOC(sizeof(Vector));
182 vector->item.type=VECTOR;
187 SCC* scc=(SCC*)RUNMALLOC(sizeof(SCC));
188 scc->item.type=SINGLEITEM;
192 MemoryQueue* createMemoryQueue(){
193 MemoryQueue* queue = (MemoryQueue*)RUNMALLOC(sizeof(MemoryQueue));
194 MemoryQueueItem* dummy=(MemoryQueueItem*)RUNMALLOC(sizeof(MemoryQueueItem));
195 dummy->type=3; // dummy type
203 int ADDRENTRY(MemoryQueue * q, REntry * r) {
204 if (isFineRead(r) || isFineWrite(r)) {
205 return ADDTABLE(q, r);
206 } else if (isCoarse(r)) {
207 return ADDVECTOR(q, r);
208 } else if (isSCC(r)) {
213 int ADDTABLE(MemoryQueue *q, REntry *r) {
214 if(!isHashtable(q->tail)) {
216 MemoryQueueItem* tail=q->tail;
217 if (isParent(r) && tail->total==0 && q->tail==q->head) {
222 Hashtable* h=createHashtable();
223 tail->next=(MemoryQueueItem*)h;
224 //************NEED memory barrier here to ensure compiler does not cache Q.tail.status********
225 if (BARRIER() && tail->status==READY && tail->total==0 && q->tail==q->head) {
226 //previous Q item is finished
227 h->item.status=READY;
229 q->tail=(MemoryQueueItem*)h;
230 // handle the the queue item case
231 if(q->head->type==3){
232 q->head=(MemoryQueueItem*)h;
236 //at this point, have table
237 Hashtable* table=(Hashtable*)q->tail;
238 r->hashtable=table; // set rentry's hashtable
239 if( *(r->pointer)==0 ||
240 ( *(r->pointer)!=0 &&
242 table->unresolvedQueue!=NULL
246 // grab lock on the queue
248 val=(struct Queue*)0x1;
249 val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
250 } while(val==(struct Queue*)0x1);
252 //queue is null, first case
253 if(*(r->pointer)!=0){
254 // check whether pointer is already resolved, or not.
255 table->unresolvedQueue=NULL; //released lock;
256 return ADDTABLEITEM(table,r,TRUE);
258 struct Queue* queue=createQueue();
259 addNewItemBack(queue,r);
260 atomic_inc(&table->item.total);
261 table->unresolvedQueue=queue; // expose new queue
263 // add unresolved rentry at the end of the queue.
264 addNewItemBack(val,r);
265 atomic_inc(&table->item.total);
266 table->unresolvedQueue=val; // released lock
272 // leave this--its a helpful test when things are going bonkers
273 //if( OBJPTRPTR_2_OBJOID( r->pointer ) == 0 ) {
274 // // we started numbering object ID's at 1, if we try to
275 // // hash a zero oid, something BAD is about to happen!
276 // printf( "Tried to insert invalid object type=%d into mem Q hashtable!\n",
277 // OBJPTRPTR_2_OBJTYPE( r->pointer ) );
280 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
283 BinElement* bin=table->array[key];
284 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);//note...talk to me about optimizations here.
285 } while(val==(BinItem*)0x1);
286 //at this point have locked bin
288 return EMPTYBINCASE(table, table->array[key], r, TRUE);
290 if (isFineWrite(r)) {
291 return WRITEBINCASE(table, r, val, key, TRUE);
292 } else if (isFineRead(r)) {
293 return READBINCASE(table, r, val, key, TRUE);
298 int ADDTABLEITEM(Hashtable* table, REntry* r, int inc){
301 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
304 BinElement* bin=table->array[key];
305 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);
306 } while(val==(BinItem*)0x1);
307 //at this point have locked bin
309 return EMPTYBINCASE(table, table->array[key], r, inc);
311 if (isFineWrite(r)) {
312 return WRITEBINCASE(table, r, val, key, inc);
313 } else if (isFineRead(r)) {
314 return READBINCASE(table, r, val, key, inc);
319 int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r, int inc) {
322 if (isFineWrite(r)) {
323 b=(BinItem*)createWriteBinItem();
324 ((WriteBinItem*)b)->val=r;//<-only different statement
325 } else if (isFineRead(r)) {
326 b=(BinItem*)createReadBinItem();
327 ReadBinItem* readbin=(ReadBinItem*)b;
328 readbin->array[readbin->index++]=r;
332 if (T->item.status==READY) {
333 //current entry is ready
337 be->head=NULL; // released lock
346 atomic_inc(&T->item.total);
351 be->head=b;//released lock
355 int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) {
356 //chain of bins exists => tail is valid
357 //if there is something in front of us, then we are not ready
360 BinElement* be=T->array[key];
362 BinItem *bintail=be->tail;
364 WriteBinItem *b=createWriteBinItem();
368 // note: If current table clears all dependencies, then write bin is ready
372 atomic_inc(&T->item.total);
376 r->binitem=(BinItem*)b;
378 be->tail->next=(BinItem*)b;
379 //need to check if we can go...
381 if (T->item.status==READY) {
382 for(;val!=NULL;val=val->next) {
383 if (val==((BinItem *)b)) {
387 b->item.status=retval;//unsure if really needed at this point..
388 be->head=NULL; // released lock
392 } else if (val->total!=0) {
398 b->item.status=retval;
399 be->tail=(BinItem*)b;
404 READBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) {
405 BinItem * bintail=T->array[key]->tail;
406 if (isReadBinItem(bintail)) {
407 return TAILREADCASE(T, r, val, bintail, key, inc);
408 } else if (!isReadBinItem(bintail)) {
409 TAILWRITECASE(T, r, val, bintail, key, inc);
414 int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
415 ReadBinItem * readbintail=(ReadBinItem*)T->array[key]->tail;
417 if (readbintail->item.status==READY) {
421 T->array[key]->head=val;//released lock
429 if (readbintail->index==NUMREAD) { // create new read group
430 ReadBinItem* rb=createReadBinItem();
431 rb->array[rb->index++]=r;
432 rb->item.total=1;//safe only because item could not have started
433 rb->item.status=status;
434 T->array[key]->tail->next=(BinItem*)rb;
435 T->array[key]->tail=(BinItem*)rb;
436 r->binitem=(BinItem*)rb;
437 } else { // group into old tail
438 readbintail->array[readbintail->index++]=r;
439 atomic_inc(&readbintail->item.total);
440 r->binitem=(BinItem*)readbintail;
443 atomic_inc(&T->item.total);
446 T->array[key]->head=val;//released lock
450 TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
451 // WriteBinItem* wb=createWriteBinItem();
453 //wb->item.total=1;//safe because item could not have started
454 //wb->item.status=NOTREADY;
455 ReadBinItem* rb=createReadBinItem();
456 rb->array[rb->index++]=r;
457 rb->item.total=1;//safe because item could not have started
458 rb->item.status=NOTREADY;
460 atomic_inc(&T->item.total);
463 r->binitem=(BinItem*)rb;
464 T->array[key]->tail->next=(BinItem*)rb;
465 T->array[key]->tail=(BinItem*)rb;
466 T->array[key]->head=val;//released lock
469 ADDVECTOR(MemoryQueue *Q, REntry *r) {
470 if(!isVector(Q->tail)) {
472 if (isParentCoarse(r) && Q->tail->total==0 && Q->tail==Q->head) {
477 Vector* V=createVector();
478 Q->tail->next=(MemoryQueueItem*)V;
479 //************NEED memory barrier here to ensure compiler does not cache Q.tail.status******
480 if (BARRIER() && Q->tail->status==READY&&Q->tail->total==0) {
481 //previous Q item is finished
482 V->item.status=READY;
484 Q->tail=(MemoryQueueItem*)V;
485 // handle the the queue item case
486 if(Q->head->type==3){
487 Q->head=(MemoryQueueItem*)V;
490 //at this point, have vector
491 Vector* V=(Vector*)Q->tail;
492 if (V->index==NUMITEMS) {
496 V->item.status=NOTREADY;
497 Q->tail->next=(MemoryQueueItem*)V;
498 //***NEED memory barrier here to ensure compiler does not cache Q.tail.status******
499 if (BARRIER() && Q->tail->status==READY) {
500 V->item.status=READY;
502 Q->tail=(MemoryQueueItem*)V;
505 atomic_inc(&V->item.total);
509 //*****NEED memory barrier here to ensure compiler does not reorder writes to V.array and V.index
512 //*****NEED memory barrier here to ensure compiler does not cache V.status*********
514 if (BARRIER() && V->item.status==READY) {
516 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(V->array[index]), (unsigned INTPTR)flag);
518 if (isParentCoarse(r)) { //parent's retire immediately
519 atomic_dec(&V->item.total);
524 return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
532 //SCC's don't come in parent variety
533 ADDSCC(MemoryQueue *Q, REntry *r) {
539 Q->tail->next=(MemoryQueueItem*)S;
540 //*** NEED BARRIER HERE
541 if (BARRIER() && Q->tail->status==READY && Q->tail->total==0 && Q->tail==Q->head) {
542 //previous Q item is finished
543 S->item.status=READY;
544 Q->tail=(MemoryQueueItem*)S;
545 // handle the the queue item case
546 if(Q->head->type==3){
547 Q->head=(MemoryQueueItem*)S;
550 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(S->val), (unsigned INTPTR)flag);
554 return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
557 Q->tail=(MemoryQueueItem*)S;
563 void RETIRERENTRY(MemoryQueue* Q, REntry * r) {
564 if (isFineWrite(r)||isFineRead(r)) {
565 RETIREHASHTABLE(Q, r);
566 } else if (isCoarse(r)) {
568 } else if (isSCC(r)) {
573 RETIRESCC(MemoryQueue *Q, REntry *r) {
575 s->item.total=0;//don't need atomicdec
580 RETIREHASHTABLE(MemoryQueue *q, REntry *r) {
581 Hashtable *T=r->hashtable;
582 BinItem *b=r->binitem;
584 atomic_dec(&T->item.total);
585 if (T->item.next!=NULL && T->item.total==0) {
590 RETIREBIN(Hashtable *T, REntry *r, BinItem *b) {
591 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
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_tag(&(rentry->parentStallSem), rentry->tag);
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( OBJPTRPTR_2_OBJOID( r->pointer ) );
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( OBJPTRPTR_2_OBJOID( r->pointer ) );
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( OBJPTRPTR_2_OBJOID( r->pointer ) );
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( OBJPTRPTR_2_OBJOID( r->pointer ) );
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);
944 //now, address is resolved
946 //check if rentry is buffer mode
947 if(rentry->isBufMode==TRUE){
950 INITIALIZEBUF(queue);
951 currentSESE=(INTPTR)rentry;
952 ADDRENTRYTOBUF(queue,rentry);
953 } else if(currentSESE==(INTPTR)rentry){
954 ADDRENTRYTOBUF(queue,rentry);
955 } else if(currentSESE!=(INTPTR)rentry){
956 RESOLVEBUFFORHASHTABLE(queue,table,(SESEcommon*)rentry->seseRec);
957 currentSESE=(INTPTR)rentry;
958 INITIALIZEBUF(queue);
959 ADDRENTRYTOBUF(rentry->queue,rentry);
963 //previous SESE has buf mode, need to invoke resolve buffer
964 RESOLVEBUFFORHASHTABLE(queue,table,(SESEcommon*)rentry->seseRec);
968 if(ADDTABLEITEM(table, rentry, FALSE)==READY){
969 resolveDependencies(rentry);
973 table->unresolvedQueue=NULL; // set hashtable as normal-mode.
978 // resolved rentry is not head of queue
979 table->unresolvedQueue=val;//released lock;
983 void rehashMemoryQueue(SESEcommon* seseParent){
985 // update memory queue
987 for(i=0; i<seseParent->numMemoryQueue; i++){
988 MemoryQueue *memoryQueue=seseParent->memoryQueueArray[i];
989 MemoryQueueItem *memoryItem=memoryQueue->head;
990 MemoryQueueItem *prevItem=NULL;
991 while(memoryItem!=NULL){
992 if(memoryItem->type==HASHTABLE){
994 Hashtable* ht=(Hashtable*)memoryItem;
995 Hashtable* newht=createHashtable();
997 for(binidx=0; binidx<NUMBINS; binidx++){
998 BinElement *bin=ht->array[binidx];
999 BinItem *binItem=bin->head;
1000 //traverse over the list of each bin
1001 while(binItem!=NULL){
1002 if(binItem->type==READBIN){
1003 ReadBinItem* readBinItem=(ReadBinItem*)binItem;
1005 for(ridx=0; ridx<readBinItem->index; ridx++){
1006 REntry *rentry=readBinItem->array[ridx];
1007 int newkey=generateKey((unsigned int)(unsigned INTPTR)*(rentry->pointer));
1008 int status=rentry->binitem->status;
1009 ADDTABLEITEM(newht,rentry,TRUE);
1010 rentry->binitem->status=status; // update bin status as before rehash
1013 REntry *rentry=((WriteBinItem*)binItem)->val;
1014 int newkey=generateKey((unsigned int)(unsigned INTPTR)*(rentry->pointer));
1015 int status=rentry->binitem->status;
1016 ADDTABLEITEM(newht,rentry,TRUE);
1017 int newstatus=rentry->binitem->status;
1018 //printf("[%d]old status=%d new status=%d\n",i,status,newstatus);
1019 rentry->binitem->status=status; // update bin status as before rehash
1021 binItem=binItem->next;
1024 newht->item.status=ht->item.status; // update hashtable status
1026 prevItem->next=(MemoryQueueItem*)newht;
1028 if(memoryQueue->head==memoryQueue->tail){
1029 memoryQueue->tail=(MemoryQueueItem*)newht;
1031 memoryQueue->head=(MemoryQueueItem*)newht;
1033 newht->item.next=ht->item.next;
1035 prevItem=memoryItem;
1036 memoryItem=memoryItem->next;