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" );
25 void mlpFreeSESErecord( SESEcommon* seseRecord ) {
26 RUNFREE( seseRecord );
29 MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue){
31 MemoryQueue** newMemoryQueue=(MemoryQueue**)RUNMALLOC( sizeof( MemoryQueue* ) * numMemoryQueue );
32 for(i=0; i<numMemoryQueue; i++){
33 newMemoryQueue[i]=createMemoryQueue();
35 return newMemoryQueue;
38 REntry* mlpCreateREntryArray(){
39 REntry* newREntryArray=(REntry*)RUNMALLOC(sizeof(REntry)*NUMRENTRY);
40 return newREntryArray;
43 REntry* mlpCreateFineREntry(int type, SESEcommon* seseToIssue, void* dynID){
44 REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry));
46 newREntry->seseRec=seseToIssue;
47 newREntry->pointer=dynID;
51 REntry* mlpCreateREntry(int type, SESEcommon* seseToIssue){
52 REntry* newREntry=(REntry*)RUNMALLOC(sizeof(REntry));
54 newREntry->seseRec=seseToIssue;
58 int isParent(REntry *r) {
59 if (r->type==PARENTREAD || r->type==PARENTWRITE || r->type==PARENTCOARSE) {
66 int isParentCoarse(REntry *r){
67 if (r->type==PARENTCOARSE){
74 int isFineRead(REntry *r) {
75 if (r->type==READ || r->type==PARENTREAD) {
82 int isFineWrite(REntry *r) {
83 if (r->type==WRITE || r->type==PARENTWRITE) {
90 int isCoarse(REntry *r){
91 if(r->type==COARSE || r->type==PARENTCOARSE){
106 int isSingleItem(MemoryQueueItem *qItem){
107 if(qItem->type==SINGLEITEM){
114 int isHashtable(MemoryQueueItem *qItem){
115 if(qItem->type==HASHTABLE){
122 int isVector(MemoryQueueItem *qItem){
123 if(qItem->type==VECTOR){
130 int isReadBinItem(BinItem* b){
131 if(b->type==READBIN){
138 int isWriteBinItem(BinItem* b){
139 if(b->type==WRITEBIN){
146 int generateKey(unsigned int data){
147 return (data&H_MASK)>> 4;
150 Hashtable* createHashtable(){
152 Hashtable* newTable=(Hashtable*)RUNMALLOC(sizeof(Hashtable));
153 newTable->item.type=HASHTABLE;
154 for(i=0;i<NUMBINS;i++){
155 newTable->array[i]=(BinElement*)RUNMALLOC(sizeof(BinElement));
156 newTable->array[i]->head=NULL;
157 newTable->array[i]->tail=NULL;
159 newTable->unresolvedQueue=NULL;
163 WriteBinItem* createWriteBinItem(){
164 WriteBinItem* binitem=(WriteBinItem*)RUNMALLOC(sizeof(WriteBinItem));
165 binitem->item.type=WRITEBIN;
169 ReadBinItem* createReadBinItem(){
170 ReadBinItem* binitem=(ReadBinItem*)RUNMALLOC(sizeof(ReadBinItem));
172 binitem->item.type=READBIN;
176 Vector* createVector(){
177 Vector* vector=(Vector*)RUNMALLOC(sizeof(Vector));
179 vector->item.type=VECTOR;
184 SCC* scc=(SCC*)RUNMALLOC(sizeof(SCC));
185 scc->item.type=SINGLEITEM;
189 MemoryQueue* createMemoryQueue(){
190 MemoryQueue* queue = (MemoryQueue*)RUNMALLOC(sizeof(MemoryQueue));
191 MemoryQueueItem* dummy=(MemoryQueueItem*)RUNMALLOC(sizeof(MemoryQueueItem));
192 dummy->type=3; // dummy type
200 int ADDRENTRY(MemoryQueue * q, REntry * r) {
201 if (isFineRead(r) || isFineWrite(r)) {
202 return ADDTABLE(q, r);
203 } else if (isCoarse(r)) {
204 return ADDVECTOR(q, r);
205 } else if (isSCC(r)) {
210 int ADDTABLE(MemoryQueue *q, REntry *r) {
211 if(!isHashtable(q->tail)) {
213 MemoryQueueItem* tail=q->tail;
214 if (isParent(r) && tail->total==0 && q->tail==q->head) {
219 Hashtable* h=createHashtable();
220 tail->next=(MemoryQueueItem*)h;
221 //************NEED memory barrier here to ensure compiler does not cache Q.tail.status********
222 if (BARRIER() && tail->status==READY && tail->total==0 && q->tail==q->head) {
223 //previous Q item is finished
224 h->item.status=READY;
226 q->tail=(MemoryQueueItem*)h;
227 // handle the the queue item case
228 if(q->head->type==3){
229 q->head=(MemoryQueueItem*)h;
233 //at this point, have table
234 Hashtable* table=(Hashtable*)q->tail;
235 r->hashtable=table; // set rentry's hashtable
236 if( *(r->pointer)==0 ||
237 ( *(r->pointer)!=0 &&
239 table->unresolvedQueue!=NULL
243 // grab lock on the queue
245 val=(struct Queue*)0x1;
246 val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
247 } while(val==(struct Queue*)0x1);
249 //queue is null, first case
250 if(*(r->pointer)!=0){
251 // check whether pointer is already resolved, or not.
252 table->unresolvedQueue=NULL; //released lock;
253 return ADDTABLEITEM(table,r,TRUE);
255 struct Queue* queue=createQueue();
256 addNewItemBack(queue,r);
257 atomic_inc(&table->item.total);
258 table->unresolvedQueue=queue; // expose new queue
260 // add unresolved rentry at the end of the queue.
261 addNewItemBack(val,r);
262 atomic_inc(&table->item.total);
263 table->unresolvedQueue=val; // released lock
269 // leave this--its a helpful test when things are going bonkers
270 //if( OBJPTRPTR_2_OBJOID( r->pointer ) == 0 ) {
271 // // we started numbering object ID's at 1, if we try to
272 // // hash a zero oid, something BAD is about to happen!
273 // printf( "Tried to insert invalid object type=%d into mem Q hashtable!\n",
274 // OBJPTRPTR_2_OBJTYPE( r->pointer ) );
277 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
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( OBJPTRPTR_2_OBJOID( r->pointer ) );
301 BinElement* bin=table->array[key];
302 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);
303 } while(val==(BinItem*)0x1);
304 //at this point have locked bin
306 return EMPTYBINCASE(table, table->array[key], r, inc);
308 if (isFineWrite(r)) {
309 return WRITEBINCASE(table, r, val, key, inc);
310 } else if (isFineRead(r)) {
311 return READBINCASE(table, r, val, key, inc);
316 int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r, int inc) {
319 if (isFineWrite(r)) {
320 b=(BinItem*)createWriteBinItem();
321 ((WriteBinItem*)b)->val=r;//<-only different statement
322 } else if (isFineRead(r)) {
323 b=(BinItem*)createReadBinItem();
324 ReadBinItem* readbin=(ReadBinItem*)b;
325 readbin->array[readbin->index++]=r;
329 if (T->item.status==READY) {
330 //current entry is ready
334 be->head=NULL; // released lock
343 atomic_inc(&T->item.total);
348 be->head=b;//released lock
352 int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) {
353 //chain of bins exists => tail is valid
354 //if there is something in front of us, then we are not ready
357 BinElement* be=T->array[key];
359 BinItem *bintail=be->tail;
361 WriteBinItem *b=createWriteBinItem();
365 // note: If current table clears all dependencies, then write bin is ready
369 atomic_inc(&T->item.total);
373 r->binitem=(BinItem*)b;
375 be->tail->next=(BinItem*)b;
376 //need to check if we can go...
378 if (T->item.status==READY) {
379 for(;val!=NULL;val=val->next) {
380 if (val==((BinItem *)b)) {
384 b->item.status=retval;//unsure if really needed at this point..
385 be->head=NULL; // released lock
389 } else if (val->total!=0) {
395 b->item.status=retval;
396 be->tail=(BinItem*)b;
401 READBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) {
402 BinItem * bintail=T->array[key]->tail;
403 if (isReadBinItem(bintail)) {
404 return TAILREADCASE(T, r, val, bintail, key, inc);
405 } else if (!isReadBinItem(bintail)) {
406 TAILWRITECASE(T, r, val, bintail, key, inc);
411 int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
412 ReadBinItem * readbintail=(ReadBinItem*)T->array[key]->tail;
414 if (readbintail->item.status==READY) {
418 T->array[key]->head=val;//released lock
426 if (readbintail->index==NUMREAD) { // create new read group
427 ReadBinItem* rb=createReadBinItem();
428 rb->array[rb->index++]=r;
429 rb->item.total=1;//safe only because item could not have started
430 rb->item.status=status;
431 T->array[key]->tail->next=(BinItem*)rb;
432 T->array[key]->tail=(BinItem*)rb;
433 r->binitem=(BinItem*)rb;
434 } else { // group into old tail
435 readbintail->array[readbintail->index++]=r;
436 atomic_inc(&readbintail->item.total);
437 r->binitem=(BinItem*)readbintail;
440 atomic_inc(&T->item.total);
443 T->array[key]->head=val;//released lock
447 TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
448 // WriteBinItem* wb=createWriteBinItem();
450 //wb->item.total=1;//safe because item could not have started
451 //wb->item.status=NOTREADY;
452 ReadBinItem* rb=createReadBinItem();
453 rb->array[rb->index++]=r;
454 rb->item.total=1;//safe because item could not have started
455 rb->item.status=NOTREADY;
457 atomic_inc(&T->item.total);
460 r->binitem=(BinItem*)rb;
461 T->array[key]->tail->next=(BinItem*)rb;
462 T->array[key]->tail=(BinItem*)rb;
463 T->array[key]->head=val;//released lock
466 ADDVECTOR(MemoryQueue *Q, REntry *r) {
467 if(!isVector(Q->tail)) {
469 if (isParentCoarse(r) && Q->tail->total==0 && Q->tail==Q->head) {
474 Vector* V=createVector();
475 Q->tail->next=(MemoryQueueItem*)V;
476 //************NEED memory barrier here to ensure compiler does not cache Q.tail.status******
477 if (BARRIER() && Q->tail->status==READY&&Q->tail->total==0) {
478 //previous Q item is finished
479 V->item.status=READY;
481 Q->tail=(MemoryQueueItem*)V;
482 // handle the the queue item case
483 if(Q->head->type==3){
484 Q->head=(MemoryQueueItem*)V;
487 //at this point, have vector
488 Vector* V=(Vector*)Q->tail;
489 if (V->index==NUMITEMS) {
493 V->item.status=NOTREADY;
494 Q->tail->next=(MemoryQueueItem*)V;
495 //***NEED memory barrier here to ensure compiler does not cache Q.tail.status******
496 if (BARRIER() && Q->tail->status==READY) {
497 V->item.status=READY;
499 Q->tail=(MemoryQueueItem*)V;
502 atomic_inc(&V->item.total);
506 //*****NEED memory barrier here to ensure compiler does not reorder writes to V.array and V.index
509 //*****NEED memory barrier here to ensure compiler does not cache V.status*********
511 if (BARRIER() && V->item.status==READY) {
513 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(V->array[index]), (unsigned INTPTR)flag);
515 if (isParentCoarse(r)) { //parent's retire immediately
516 atomic_dec(&V->item.total);
521 return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
529 //SCC's don't come in parent variety
530 ADDSCC(MemoryQueue *Q, REntry *r) {
536 Q->tail->next=(MemoryQueueItem*)S;
537 //*** NEED BARRIER HERE
538 if (BARRIER() && Q->tail->status==READY && Q->tail->total==0 && Q->tail==Q->head) {
539 //previous Q item is finished
540 S->item.status=READY;
541 Q->tail=(MemoryQueueItem*)S;
542 // handle the the queue item case
543 if(Q->head->type==3){
544 Q->head=(MemoryQueueItem*)S;
547 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(S->val), (unsigned INTPTR)flag);
551 return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
554 Q->tail=(MemoryQueueItem*)S;
560 void RETIRERENTRY(MemoryQueue* Q, REntry * r) {
561 if (isFineWrite(r)||isFineRead(r)) {
562 RETIREHASHTABLE(Q, r);
563 } else if (isCoarse(r)) {
565 } else if (isSCC(r)) {
570 RETIRESCC(MemoryQueue *Q, REntry *r) {
572 s->item.total=0;//don't need atomicdec
577 RETIREHASHTABLE(MemoryQueue *q, REntry *r) {
578 Hashtable *T=r->hashtable;
579 BinItem *b=r->binitem;
581 atomic_dec(&T->item.total);
582 if (T->item.next!=NULL && T->item.total==0) {
587 RETIREBIN(Hashtable *T, REntry *r, BinItem *b) {
588 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
590 atomic_dec(&b->total);
592 if (isFineWrite(r) || (isFineRead(r) && b->next!=NULL && b->total==0)) {
593 // CHECK FIRST IF next is nonnull to guarantee that b.total cannot change
597 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(T->array[key]->head), (unsigned INTPTR)val);
598 } while(val==(BinItem*)0x1);
599 // at this point have locked bin
604 if (isReadBinItem(ptr)) {
605 ReadBinItem* rptr=(ReadBinItem*)ptr;
606 if (rptr->item.status==NOTREADY) {
607 for (i=0;i<rptr->index;i++) {
608 resolveDependencies(rptr->array[i]);
609 if (isParent(rptr->array[i])) {
610 //parents go immediately
611 atomic_dec(&rptr->item.total);
612 atomic_dec(&T->item.total);
616 rptr->item.status=READY;
617 if (rptr->item.next==NULL) {
620 if (rptr->item.total!=0) {
622 } else if ((BinItem*)rptr==val) {
625 } else if(isWriteBinItem(ptr)) {
628 if(ptr->status==NOTREADY){
629 resolveDependencies(((WriteBinItem*)ptr)->val);
631 if(isParent(((WriteBinItem*)ptr)->val)){
632 atomic_dec(&T->item.total);
636 }else{ // write bin is already resolved
640 if(ptr->status==NOTREADY) {
641 resolveDependencies(((WriteBinItem*)ptr)->val);
644 if (isParent(((WriteBinItem*)ptr)->val)) {
645 atomic_dec(&T->item.total);
655 T->array[key]->head=val; // release lock
660 RETIREVECTOR(MemoryQueue *Q, REntry *r) {
662 atomic_dec(&V->item.total);
663 if (V->item.next!=NULL && V->item.total==0) { //NOTE: ORDERING CRUCIAL HERE
668 RESOLVECHAIN(MemoryQueue *Q) {
670 MemoryQueueItem* head=Q->head;
671 if (head->next==NULL||head->total!=0) {
672 //item is not finished
673 if (head->status!=READY) {
674 //need to update status
676 if (isHashtable(head)) {
677 RESOLVEHASHTABLE(Q, head);
678 } else if (isVector(head)) {
679 RESOLVEVECTOR(Q, head);
680 } else if (isSingleItem(head)) {
683 if (head->next==NULL)
690 MemoryQueueItem* nextitem=head->next;
691 CAS((unsigned INTPTR*)&(Q->head), (unsigned INTPTR)head, (unsigned INTPTR)nextitem);
692 //oldvalue not needed... if we fail we just repeat
697 RESOLVEHASHTABLE(MemoryQueue *Q, Hashtable *T) {
699 for (binidx=0;binidx<NUMBINS;binidx++) {
700 BinElement* bin=T->array[binidx];
704 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);
705 } while (val==(BinItem*)1);
706 //at this point have locked bin
709 if(ptr!=NULL&&ptr->status==NOTREADY) {
711 if (isWriteBinItem(ptr)) {
714 resolveDependencies(((WriteBinItem*)ptr)->val);
716 if (isParent(((WriteBinItem*)ptr)->val)) {
717 atomic_dec(&T->item.total);
721 } else if (isReadBinItem(ptr)) {
723 ReadBinItem* rptr=(ReadBinItem*)ptr;
724 for(i=0;i<rptr->index;i++) {
725 resolveDependencies(rptr->array[i]);
726 if (isParent(rptr->array[i])) {
727 atomic_dec(&rptr->item.total);
728 atomic_dec(&T->item.total);
731 if (rptr->item.next==NULL||rptr->item.total!=0) {
733 } else if((BinItem*)rptr==val) {
736 rptr->item.status=READY;
741 bin->head=val; // released lock;
745 RESOLVEVECTOR(MemoryQueue *q, Vector *V) {
751 for (i=0;i<NUMITEMS;i++) {
753 val=(REntry*)LOCKXCHG((unsigned INTPTR*)&(tmp->array[i]), (unsigned INTPTR)val);
755 resolveDependencies(val);
757 atomic_dec(&tmp->item.total);
761 if (tmp->item.next!=NULL&&isVector(tmp->item.next)) {
762 tmp=(Vector*)tmp->item.next;
770 //precondition: SCC's state is READY
772 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(S->val), (unsigned INTPTR)flag);
774 resolveDependencies(flag);
779 resolveDependencies(REntry* rentry){
780 SESEcommon* seseCommon=(SESEcommon*)rentry->seseRec;
781 if(rentry->type==READ || rentry->type==WRITE || rentry->type==COARSE || rentry->type==SCCITEM){
782 if( atomic_sub_and_test(1, &(seseCommon->unresolvedDependencies)) ){
783 workScheduleSubmit(seseCommon);
785 }else if(rentry->type==PARENTREAD || rentry->type==PARENTWRITE ||rentry->type==PARENTCOARSE){
786 psem_give(&(rentry->parentStallSem));
790 void INITIALIZEBUF(MemoryQueue * q){
792 for(i=0; i<NUMBINS; i++){
798 void ADDRENTRYTOBUF(MemoryQueue * q, REntry * r){
799 q->buf[q->bufcount]=r;
803 int RESOLVEBUFFORHASHTABLE(MemoryQueue * q, Hashtable* table, SESEcommon *seseCommon){
805 // first phase: only consider write rentry
806 for(i=0; i<q->bufcount;i++){
809 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
810 if(q->binbuf[key]==NULL){
811 // for multiple writes, add only the first write that hashes to the same bin
818 // second phase: enqueue read items if it is eligible
819 for(i=0; i<q->bufcount;i++){
821 if(r!=NULL && r->type==READ){
822 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
823 if(q->binbuf[key]==NULL){
824 // read item that hashes to the bin which doen't contain any write
825 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
826 if(ADDTABLEITEM(table, r, FALSE)==READY){
827 resolveDependencies(r);
834 // then, add only one of write items that hashes to the same bin
835 for(i=0; i<q->bufcount;i++){
838 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
839 if(ADDTABLEITEM(table, r, FALSE)==READY){
840 resolveDependencies(r);
846 int RESOLVEBUF(MemoryQueue * q, SESEcommon *seseCommon){
849 // check if every waiting entry is resolved
850 // if not, defer every items for hashtable until it is resolved.
851 int unresolved=FALSE;
852 for(i=0; i<q->bufcount;i++){
854 if(*(r->pointer)==0){
858 if(unresolved==TRUE){
859 for(i=0; i<q->bufcount;i++){
863 if(ADDRENTRY(q,r)==NOTREADY){
870 // first phase: only consider write rentry
871 for(i=0; i<q->bufcount;i++){
874 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
875 if(q->binbuf[key]==NULL){
876 // for multiple writes, add only the first write that hashes to the same bin
883 // second phase: enqueue read items if it is eligible
884 for(i=0; i<q->bufcount;i++){
886 if(r!=NULL && r->type==READ){
887 int key=generateKey( OBJPTRPTR_2_OBJOID( r->pointer ) );
888 if(q->binbuf[key]==NULL){
889 // read item that hashes to the bin which doen't contain any write
890 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
891 if(ADDRENTRY(q,r)==NOTREADY){
899 // then, add only one of write items that hashes to the same bin
900 for(i=0; i<q->bufcount;i++){
903 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
904 if(ADDRENTRY(q,r)==NOTREADY){
913 resolvePointer(REntry* rentry){
915 Hashtable* table=rentry->hashtable;
918 //resolved already before related rentry is enqueued to the waiting queue
923 val=(struct Queue*)0x1;
924 val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
925 } while(val==(struct Queue*)0x1);
926 if(val!=NULL && getHead(val)->objectptr==rentry){
927 // handling pointer is the first item of the queue
928 // start to resolve until it reaches unresolved pointer or end of queue
929 INTPTR currentSESE=0;
931 struct QueueItem* head=getHead(val);
933 REntry* rentry=(REntry*)head->objectptr;
934 if(*(rentry->pointer)==0){
935 // encounters following unresolved pointer
936 table->unresolvedQueue=val;//released lock
939 removeItem(val,head);
941 //now, address is resolved
943 //check if rentry is buffer mode
944 if(rentry->isBufMode==TRUE){
947 INITIALIZEBUF(queue);
948 currentSESE=(INTPTR)rentry;
949 ADDRENTRYTOBUF(queue,rentry);
950 } else if(currentSESE==(INTPTR)rentry){
951 ADDRENTRYTOBUF(queue,rentry);
952 } else if(currentSESE!=(INTPTR)rentry){
953 RESOLVEBUFFORHASHTABLE(queue,table,(SESEcommon*)rentry->seseRec);
954 currentSESE=(INTPTR)rentry;
955 INITIALIZEBUF(queue);
956 ADDRENTRYTOBUF(rentry->queue,rentry);
960 //previous SESE has buf mode, need to invoke resolve buffer
961 RESOLVEBUFFORHASHTABLE(queue,table,(SESEcommon*)rentry->seseRec);
965 if(ADDTABLEITEM(table, rentry, FALSE)==READY){
966 resolveDependencies(rentry);
970 table->unresolvedQueue=NULL; // set hashtable as normal-mode.
975 // resolved rentry is not head of queue
976 table->unresolvedQueue=val;//released lock;
980 void rehashMemoryQueue(SESEcommon* seseParent){
982 // update memory queue
984 for(i=0; i<seseParent->numMemoryQueue; i++){
985 MemoryQueue *memoryQueue=seseParent->memoryQueueArray[i];
986 MemoryQueueItem *memoryItem=memoryQueue->head;
987 MemoryQueueItem *prevItem=NULL;
988 while(memoryItem!=NULL){
989 if(memoryItem->type==HASHTABLE){
991 Hashtable* ht=(Hashtable*)memoryItem;
992 Hashtable* newht=createHashtable();
994 for(binidx=0; binidx<NUMBINS; binidx++){
995 BinElement *bin=ht->array[binidx];
996 BinItem *binItem=bin->head;
997 //traverse over the list of each bin
998 while(binItem!=NULL){
999 if(binItem->type==READBIN){
1000 ReadBinItem* readBinItem=(ReadBinItem*)binItem;
1002 for(ridx=0; ridx<readBinItem->index; ridx++){
1003 REntry *rentry=readBinItem->array[ridx];
1004 int newkey=generateKey((unsigned int)(unsigned INTPTR)*(rentry->pointer));
1005 int status=rentry->binitem->status;
1006 ADDTABLEITEM(newht,rentry,TRUE);
1007 rentry->binitem->status=status; // update bin status as before rehash
1010 REntry *rentry=((WriteBinItem*)binItem)->val;
1011 int newkey=generateKey((unsigned int)(unsigned INTPTR)*(rentry->pointer));
1012 int status=rentry->binitem->status;
1013 ADDTABLEITEM(newht,rentry,TRUE);
1014 int newstatus=rentry->binitem->status;
1015 //printf("[%d]old status=%d new status=%d\n",i,status,newstatus);
1016 rentry->binitem->status=status; // update bin status as before rehash
1018 binItem=binItem->next;
1021 newht->item.status=ht->item.status; // update hashtable status
1023 prevItem->next=(MemoryQueueItem*)newht;
1025 if(memoryQueue->head==memoryQueue->tail){
1026 memoryQueue->tail=(MemoryQueueItem*)newht;
1028 memoryQueue->head=(MemoryQueueItem*)newht;
1030 newht->item.next=ht->item.next;
1032 prevItem=memoryItem;
1033 memoryItem=memoryItem->next;