8 #include "mlp_runtime.h"
9 #include "workschedule.h"
10 #include "methodheaders.h"
13 __thread SESEcommon* runningSESE;
16 void* mlpAllocSESErecord( int size ) {
17 void* newrec = RUNMALLOC( size );
19 printf( "mlpAllocSESErecord did not obtain memory!\n" );
26 void mlpFreeSESErecord( void* seseRecord ) {
27 RUNFREE( seseRecord );
30 MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue){
32 MemoryQueue** newMemoryQueue=(MemoryQueue**)RUNMALLOC( sizeof( MemoryQueue* ) * numMemoryQueue );
33 for(i=0; i<numMemoryQueue; i++){
34 newMemoryQueue[i]=createMemoryQueue();
36 return newMemoryQueue;
39 REntry* mlpCreateREntryArray(){
40 REntry* newREntryArray=(REntry*)RUNMALLOC(sizeof(REntry)*NUMRENTRY);
41 return newREntryArray;
44 REntry* mlpCreateFineREntry(int type, void* seseToIssue, void* dynID){
45 REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry));
47 newREntry->seseRec=seseToIssue;
48 newREntry->pointer=dynID;
52 REntry* mlpCreateREntry(int type, void* seseToIssue){
53 REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry));
55 newREntry->seseRec=seseToIssue;
59 int isParent(REntry *r) {
60 if (r->type==PARENTREAD || r->type==PARENTWRITE || r->type==PARENTCOARSE) {
67 int isParentCoarse(REntry *r){
68 if (r->type==PARENTCOARSE){
75 int isFineRead(REntry *r) {
76 if (r->type==READ || r->type==PARENTREAD) {
83 int isFineWrite(REntry *r) {
84 if (r->type==WRITE || r->type==PARENTWRITE) {
91 int isCoarse(REntry *r){
92 if(r->type==COARSE || r->type==PARENTCOARSE){
100 if(r->type==SCCITEM){
107 int isSingleItem(MemoryQueueItem *qItem){
108 if(qItem->type==SINGLEITEM){
115 int isHashtable(MemoryQueueItem *qItem){
116 if(qItem->type==HASHTABLE){
123 int isVector(MemoryQueueItem *qItem){
124 if(qItem->type==VECTOR){
131 int isReadBinItem(BinItem* b){
132 if(b->type==READBIN){
139 int isWriteBinItem(BinItem* b){
140 if(b->type==WRITEBIN){
147 int generateKey(unsigned int data){
148 return (data&H_MASK)>> 4;
151 Hashtable* createHashtable(){
153 Hashtable* newTable=(Hashtable*)RUNMALLOC(sizeof(Hashtable));
154 newTable->item.type=HASHTABLE;
155 for(i=0;i<NUMBINS;i++){
156 newTable->array[i]=(BinElement*)RUNMALLOC(sizeof(BinElement));
157 newTable->array[i]->head=NULL;
158 newTable->array[i]->tail=NULL;
160 newTable->unresolvedQueue=NULL;
164 WriteBinItem* createWriteBinItem(){
165 WriteBinItem* binitem=(WriteBinItem*)RUNMALLOC(sizeof(WriteBinItem));
166 binitem->item.type=WRITEBIN;
170 ReadBinItem* createReadBinItem(){
171 ReadBinItem* binitem=(ReadBinItem*)RUNMALLOC(sizeof(ReadBinItem));
173 binitem->item.type=READBIN;
177 Vector* createVector(){
178 Vector* vector=(Vector*)RUNMALLOC(sizeof(Vector));
180 vector->item.type=VECTOR;
185 SCC* scc=(SCC*)RUNMALLOC(sizeof(SCC));
186 scc->item.type=SINGLEITEM;
190 MemoryQueue* createMemoryQueue(){
191 MemoryQueue* queue = (MemoryQueue*)RUNMALLOC(sizeof(MemoryQueue));
192 MemoryQueueItem* dummy=(MemoryQueueItem*)RUNMALLOC(sizeof(MemoryQueueItem));
193 dummy->type=3; // dummy type
201 int ADDRENTRY(MemoryQueue * q, REntry * r) {
202 if (isFineRead(r) || isFineWrite(r)) {
203 return ADDTABLE(q, r);
204 } else if (isCoarse(r)) {
205 return ADDVECTOR(q, r);
206 } else if (isSCC(r)) {
211 int ADDTABLE(MemoryQueue *q, REntry *r) {
212 if(!isHashtable(q->tail)) {
214 MemoryQueueItem* tail=q->tail;
215 if (isParent(r) && tail->total==0 && q->tail==q->head) {
220 Hashtable* h=createHashtable();
221 tail->next=(MemoryQueueItem*)h;
222 //************NEED memory barrier here to ensure compiler does not cache Q.tail.status********
223 if (BARRIER() && tail->status==READY && tail->total==0 && q->tail==q->head) {
224 //previous Q item is finished
225 h->item.status=READY;
227 q->tail=(MemoryQueueItem*)h;
228 // handle the the queue item case
229 if(q->head->type==3){
230 q->head=(MemoryQueueItem*)h;
234 //at this point, have table
235 Hashtable* table=(Hashtable*)q->tail;
236 r->hashtable=table; // set rentry's hashtable
237 if( *(r->pointer)==0 ||
238 ( *(r->pointer)!=0 &&
240 table->unresolvedQueue!=NULL
244 // grab lock on the queue
246 val=(struct Queue*)0x1;
247 val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
248 } while(val==(struct Queue*)0x1);
250 //queue is null, first case
251 if(*(r->pointer)!=0){
252 // check whether pointer is already resolved, or not.
253 table->unresolvedQueue=NULL; //released lock;
254 return ADDTABLEITEM(table,r,TRUE);
256 struct Queue* queue=createQueue();
257 addNewItemBack(queue,r);
258 atomic_inc(&table->item.total);
259 table->unresolvedQueue=queue; // expose new queue
261 // add unresolved rentry at the end of the queue.
262 addNewItemBack(val,r);
263 atomic_inc(&table->item.total);
264 table->unresolvedQueue=val; // released lock
270 // leave this--its a helpful test when things are going bonkers
271 //if( OBJPTRPTR_2_OBJOID( r->pointer ) == 0 ) {
272 // // we started numbering object ID's at 1, if we try to
273 // // hash a zero oid, something BAD is about to happen!
274 // printf( "Tried to insert invalid object type=%d into mem Q hashtable!\n",
275 // OBJPTRPTR_2_OBJTYPE( r->pointer ) );
278 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
281 BinElement* bin=table->array[key];
282 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);//note...talk to me about optimizations here.
283 } while(val==(BinItem*)0x1);
284 //at this point have locked bin
286 return EMPTYBINCASE(table, table->array[key], r, TRUE);
288 if (isFineWrite(r)) {
289 return WRITEBINCASE(table, r, val, key, TRUE);
290 } else if (isFineRead(r)) {
291 return READBINCASE(table, r, val, key, TRUE);
296 int ADDTABLEITEM(Hashtable* table, REntry* r, int inc){
299 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
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;
441 atomic_inc(&T->item.total);
444 T->array[key]->head=val;//released lock
448 TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
449 // WriteBinItem* wb=createWriteBinItem();
451 //wb->item.total=1;//safe because item could not have started
452 //wb->item.status=NOTREADY;
453 ReadBinItem* rb=createReadBinItem();
454 rb->array[rb->index++]=r;
455 rb->item.total=1;//safe because item could not have started
456 rb->item.status=NOTREADY;
458 atomic_inc(&T->item.total);
461 r->binitem=(BinItem*)rb;
462 T->array[key]->tail->next=(BinItem*)rb;
463 T->array[key]->tail=(BinItem*)rb;
464 T->array[key]->head=val;//released lock
467 ADDVECTOR(MemoryQueue *Q, REntry *r) {
468 if(!isVector(Q->tail)) {
470 if (isParentCoarse(r) && Q->tail->total==0 && Q->tail==Q->head) {
475 Vector* V=createVector();
476 Q->tail->next=(MemoryQueueItem*)V;
477 //************NEED memory barrier here to ensure compiler does not cache Q.tail.status******
478 if (BARRIER() && Q->tail->status==READY&&Q->tail->total==0) {
479 //previous Q item is finished
480 V->item.status=READY;
482 Q->tail=(MemoryQueueItem*)V;
483 // handle the the queue item case
484 if(Q->head->type==3){
485 Q->head=(MemoryQueueItem*)V;
488 //at this point, have vector
489 Vector* V=(Vector*)Q->tail;
490 if (V->index==NUMITEMS) {
494 V->item.status=NOTREADY;
495 Q->tail->next=(MemoryQueueItem*)V;
496 //***NEED memory barrier here to ensure compiler does not cache Q.tail.status******
497 if (BARRIER() && Q->tail->status==READY) {
498 V->item.status=READY;
500 Q->tail=(MemoryQueueItem*)V;
503 atomic_inc(&V->item.total);
507 //*****NEED memory barrier here to ensure compiler does not reorder writes to V.array and V.index
510 //*****NEED memory barrier here to ensure compiler does not cache V.status*********
512 if (BARRIER() && V->item.status==READY) {
514 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(V->array[index]), (unsigned INTPTR)flag);
516 if (isParentCoarse(r)) { //parent's retire immediately
517 atomic_dec(&V->item.total);
522 return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
530 //SCC's don't come in parent variety
531 ADDSCC(MemoryQueue *Q, REntry *r) {
537 Q->tail->next=(MemoryQueueItem*)S;
538 //*** NEED BARRIER HERE
539 if (BARRIER() && Q->tail->status==READY && Q->tail->total==0 && Q->tail==Q->head) {
540 //previous Q item is finished
541 S->item.status=READY;
542 Q->tail=(MemoryQueueItem*)S;
543 // handle the the queue item case
544 if(Q->head->type==3){
545 Q->head=(MemoryQueueItem*)S;
548 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(S->val), (unsigned INTPTR)flag);
552 return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
555 Q->tail=(MemoryQueueItem*)S;
561 void RETIRERENTRY(MemoryQueue* Q, REntry * r) {
562 if (isFineWrite(r)||isFineRead(r)) {
563 RETIREHASHTABLE(Q, r);
564 } else if (isCoarse(r)) {
566 } else if (isSCC(r)) {
571 RETIRESCC(MemoryQueue *Q, REntry *r) {
573 s->item.total=0;//don't need atomicdec
578 RETIREHASHTABLE(MemoryQueue *q, REntry *r) {
579 Hashtable *T=r->hashtable;
580 BinItem *b=r->binitem;
582 atomic_dec(&T->item.total);
583 if (T->item.next!=NULL && T->item.total==0) {
588 RETIREBIN(Hashtable *T, REntry *r, BinItem *b) {
589 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
591 atomic_dec(&b->total);
593 if (isFineWrite(r) || (isFineRead(r) && b->next!=NULL && b->total==0)) {
594 // CHECK FIRST IF next is nonnull to guarantee that b.total cannot change
598 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(T->array[key]->head), (unsigned INTPTR)val);
599 } while(val==(BinItem*)0x1);
600 // at this point have locked bin
605 if (isReadBinItem(ptr)) {
606 ReadBinItem* rptr=(ReadBinItem*)ptr;
607 if (rptr->item.status==NOTREADY) {
608 for (i=0;i<rptr->index;i++) {
609 resolveDependencies(rptr->array[i]);
610 if (isParent(rptr->array[i])) {
611 //parents go immediately
612 atomic_dec(&rptr->item.total);
613 atomic_dec(&T->item.total);
617 rptr->item.status=READY;
618 if (rptr->item.next==NULL) {
621 if (rptr->item.total!=0) {
623 } else if ((BinItem*)rptr==val) {
626 } else if(isWriteBinItem(ptr)) {
629 if(ptr->status==NOTREADY){
630 resolveDependencies(((WriteBinItem*)ptr)->val);
632 if(isParent(((WriteBinItem*)ptr)->val)){
633 atomic_dec(&T->item.total);
637 }else{ // write bin is already resolved
641 if(ptr->status==NOTREADY) {
642 resolveDependencies(((WriteBinItem*)ptr)->val);
645 if (isParent(((WriteBinItem*)ptr)->val)) {
646 atomic_dec(&T->item.total);
656 T->array[key]->head=val; // release lock
661 RETIREVECTOR(MemoryQueue *Q, REntry *r) {
663 atomic_dec(&V->item.total);
664 if (V->item.next!=NULL && V->item.total==0) { //NOTE: ORDERING CRUCIAL HERE
669 RESOLVECHAIN(MemoryQueue *Q) {
671 MemoryQueueItem* head=Q->head;
672 if (head->next==NULL||head->total!=0) {
673 //item is not finished
674 if (head->status!=READY) {
675 //need to update status
677 if (isHashtable(head)) {
678 RESOLVEHASHTABLE(Q, head);
679 } else if (isVector(head)) {
680 RESOLVEVECTOR(Q, head);
681 } else if (isSingleItem(head)) {
684 if (head->next==NULL)
691 MemoryQueueItem* nextitem=head->next;
692 CAS((unsigned INTPTR*)&(Q->head), (unsigned INTPTR)head, (unsigned INTPTR)nextitem);
693 //oldvalue not needed... if we fail we just repeat
698 RESOLVEHASHTABLE(MemoryQueue *Q, Hashtable *T) {
700 for (binidx=0;binidx<NUMBINS;binidx++) {
701 BinElement* bin=T->array[binidx];
705 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);
706 } while (val==(BinItem*)1);
707 //at this point have locked bin
710 if(ptr!=NULL&&ptr->status==NOTREADY) {
712 if (isWriteBinItem(ptr)) {
715 resolveDependencies(((WriteBinItem*)ptr)->val);
717 if (isParent(((WriteBinItem*)ptr)->val)) {
718 atomic_dec(&T->item.total);
722 } else if (isReadBinItem(ptr)) {
724 ReadBinItem* rptr=(ReadBinItem*)ptr;
725 for(i=0;i<rptr->index;i++) {
726 resolveDependencies(rptr->array[i]);
727 if (isParent(rptr->array[i])) {
728 atomic_dec(&rptr->item.total);
729 atomic_dec(&T->item.total);
732 if (rptr->item.next==NULL||rptr->item.total!=0) {
734 } else if((BinItem*)rptr==val) {
737 rptr->item.status=READY;
742 bin->head=val; // released lock;
746 RESOLVEVECTOR(MemoryQueue *q, Vector *V) {
752 for (i=0;i<NUMITEMS;i++) {
754 val=(REntry*)LOCKXCHG((unsigned INTPTR*)&(tmp->array[i]), (unsigned INTPTR)val);
756 resolveDependencies(val);
758 atomic_dec(&tmp->item.total);
762 if (tmp->item.next!=NULL&&isVector(tmp->item.next)) {
763 tmp=(Vector*)tmp->item.next;
771 //precondition: SCC's state is READY
773 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(S->val), (unsigned INTPTR)flag);
775 resolveDependencies(flag);
780 resolveDependencies(REntry* rentry){
781 SESEcommon* seseCommon=(SESEcommon*)rentry->seseRec;
782 if(rentry->type==READ || rentry->type==WRITE || rentry->type==COARSE || rentry->type==SCCITEM){
783 if( atomic_sub_and_test(1, &(seseCommon->unresolvedDependencies)) ){
784 workScheduleSubmit(seseCommon);
786 }else if(rentry->type==PARENTREAD || rentry->type==PARENTWRITE ||rentry->type==PARENTCOARSE){
787 psem_give(&(rentry->parentStallSem));
791 void INITIALIZEBUF(MemoryQueue * q){
793 for(i=0; i<NUMBINS; i++){
799 void ADDRENTRYTOBUF(MemoryQueue * q, REntry * r){
800 q->buf[q->bufcount]=r;
804 int RESOLVEBUFFORHASHTABLE(MemoryQueue * q, Hashtable* table, SESEcommon *seseCommon){
806 // first phase: only consider write rentry
807 for(i=0; i<q->bufcount;i++){
810 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
811 if(q->binbuf[key]==NULL){
812 // for multiple writes, add only the first write that hashes to the same bin
819 // second phase: enqueue read items if it is eligible
820 for(i=0; i<q->bufcount;i++){
822 if(r!=NULL && r->type==READ){
823 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
824 if(q->binbuf[key]==NULL){
825 // read item that hashes to the bin which doen't contain any write
826 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
827 if(ADDTABLEITEM(table, r, FALSE)==READY){
828 resolveDependencies(r);
835 // then, add only one of write items that hashes to the same bin
836 for(i=0; i<q->bufcount;i++){
839 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
840 if(ADDTABLEITEM(table, r, FALSE)==READY){
841 resolveDependencies(r);
847 int RESOLVEBUF(MemoryQueue * q, SESEcommon *seseCommon){
850 // check if every waiting entry is resolved
851 // if not, defer every items for hashtable until it is resolved.
852 int unresolved=FALSE;
853 for(i=0; i<q->bufcount;i++){
855 if(*(r->pointer)==0){
859 if(unresolved==TRUE){
860 for(i=0; i<q->bufcount;i++){
864 if(ADDRENTRY(q,r)==NOTREADY){
871 // first phase: only consider write rentry
872 for(i=0; i<q->bufcount;i++){
875 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
876 if(q->binbuf[key]==NULL){
877 // for multiple writes, add only the first write that hashes to the same bin
884 // second phase: enqueue read items if it is eligible
885 for(i=0; i<q->bufcount;i++){
887 if(r!=NULL && r->type==READ){
888 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
889 if(q->binbuf[key]==NULL){
890 // read item that hashes to the bin which doen't contain any write
891 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
892 if(ADDRENTRY(q,r)==NOTREADY){
900 // then, add only one of write items that hashes to the same bin
901 for(i=0; i<q->bufcount;i++){
904 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
905 if(ADDRENTRY(q,r)==NOTREADY){
914 resolvePointer(REntry* rentry){
916 Hashtable* table=rentry->hashtable;
919 //resolved already before related rentry is enqueued to the waiting queue
924 val=(struct Queue*)0x1;
925 val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
926 } while(val==(struct Queue*)0x1);
927 if(val!=NULL && getHead(val)->objectptr==rentry){
928 // handling pointer is the first item of the queue
929 // start to resolve until it reaches unresolved pointer or end of queue
930 INTPTR currentSESE=0;
932 struct QueueItem* head=getHead(val);
934 REntry* rentry=(REntry*)head->objectptr;
935 if(*(rentry->pointer)==0){
936 // encounters following unresolved pointer
937 table->unresolvedQueue=val;//released lock
940 removeItem(val,head);
942 //now, address is resolved
944 //check if rentry is buffer mode
945 if(rentry->isBufMode==TRUE){
948 INITIALIZEBUF(queue);
949 currentSESE=(INTPTR)rentry;
950 ADDRENTRYTOBUF(queue,rentry);
951 } else if(currentSESE==(INTPTR)rentry){
952 ADDRENTRYTOBUF(queue,rentry);
953 } else if(currentSESE!=(INTPTR)rentry){
954 RESOLVEBUFFORHASHTABLE(queue,table,(SESEcommon*)rentry->seseRec);
955 currentSESE=(INTPTR)rentry;
956 INITIALIZEBUF(queue);
957 ADDRENTRYTOBUF(rentry->queue,rentry);
961 //previous SESE has buf mode, need to invoke resolve buffer
962 RESOLVEBUFFORHASHTABLE(queue,table,(SESEcommon*)rentry->seseRec);
966 if(ADDTABLEITEM(table, rentry, FALSE)==READY){
967 resolveDependencies(rentry);
971 table->unresolvedQueue=NULL; // set hashtable as normal-mode.
976 // resolved rentry is not head of queue
977 table->unresolvedQueue=val;//released lock;
981 void rehashMemoryQueue(SESEcommon* seseParent){
983 // update memory queue
985 for(i=0; i<seseParent->numMemoryQueue; i++){
986 MemoryQueue *memoryQueue=seseParent->memoryQueueArray[i];
987 MemoryQueueItem *memoryItem=memoryQueue->head;
988 MemoryQueueItem *prevItem=NULL;
989 while(memoryItem!=NULL){
990 if(memoryItem->type==HASHTABLE){
992 Hashtable* ht=(Hashtable*)memoryItem;
993 Hashtable* newht=createHashtable();
995 for(binidx=0; binidx<NUMBINS; binidx++){
996 BinElement *bin=ht->array[binidx];
997 BinItem *binItem=bin->head;
998 //traverse over the list of each bin
999 while(binItem!=NULL){
1000 if(binItem->type==READBIN){
1001 ReadBinItem* readBinItem=(ReadBinItem*)binItem;
1003 for(ridx=0; ridx<readBinItem->index; ridx++){
1004 REntry *rentry=readBinItem->array[ridx];
1005 int newkey=generateKey((unsigned int)(unsigned INTPTR)*(rentry->pointer));
1006 int status=rentry->binitem->status;
1007 ADDTABLEITEM(newht,rentry,TRUE);
1008 rentry->binitem->status=status; // update bin status as before rehash
1011 REntry *rentry=((WriteBinItem*)binItem)->val;
1012 int newkey=generateKey((unsigned int)(unsigned INTPTR)*(rentry->pointer));
1013 int status=rentry->binitem->status;
1014 ADDTABLEITEM(newht,rentry,TRUE);
1015 int newstatus=rentry->binitem->status;
1016 //printf("[%d]old status=%d new status=%d\n",i,status,newstatus);
1017 rentry->binitem->status=status; // update bin status as before rehash
1019 binItem=binItem->next;
1022 newht->item.status=ht->item.status; // update hashtable status
1024 prevItem->next=(MemoryQueueItem*)newht;
1026 if(memoryQueue->head==memoryQueue->tail){
1027 memoryQueue->tail=(MemoryQueueItem*)newht;
1029 memoryQueue->head=(MemoryQueueItem*)newht;
1031 newht->item.next=ht->item.next;
1033 prevItem=memoryItem;
1034 memoryItem=memoryItem->next;