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;
23 __thread void * baseptr=NULL;
25 __thread int spaceleft=0;
30 void * MLPMALLOC(int size) {
31 // printf("%d\n",size);
33 baseptr=malloc(MBLOCK);
41 char *charbase=(char *)baseptr;
42 baseptr=(void *)(charbase+size);
48 void* mlpAllocSESErecord( int size ) {
49 void* newrec = MLPMALLOC( size );
51 printf( "mlpAllocSESErecord did not obtain memory!\n" );
58 void mlpFreeSESErecord( void* seseRecord ) {
59 // MLPFREE( seseRecord );
62 MemoryQueue** mlpCreateMemoryQueueArray(int numMemoryQueue){
64 MemoryQueue** newMemoryQueue=(MemoryQueue**)MLPMALLOC( sizeof( MemoryQueue* ) * numMemoryQueue );
65 for(i=0; i<numMemoryQueue; i++){
66 newMemoryQueue[i]=createMemoryQueue();
68 return newMemoryQueue;
71 REntry* mlpCreateREntryArray(){
72 REntry* newREntryArray=(REntry*)MLPMALLOC(sizeof(REntry)*NUMRENTRY);
73 return newREntryArray;
76 REntry* mlpCreateFineREntry(int type, void* seseToIssue, void* dynID){
77 struct ___Object___ * obj=(struct ___Object___*)*((unsigned INTPTR *)dynID);
78 REntry* newREntry=(REntry*)MLPMALLOC(sizeof(REntry));
80 newREntry->seseRec=seseToIssue;
81 newREntry->pointer=dynID;
83 newREntry->oid=obj->oid;
88 REntry* mlpCreateREntry(int type, void* seseToIssue){
89 REntry* newREntry=(REntry*)MLPMALLOC(sizeof(REntry));
91 newREntry->seseRec=seseToIssue;
95 int isParent(REntry *r) {
96 if (r->type==PARENTREAD || r->type==PARENTWRITE || r->type==PARENTCOARSE) {
103 int isParentCoarse(REntry *r){
104 if (r->type==PARENTCOARSE){
111 int isFineRead(REntry *r) {
112 if (r->type==READ || r->type==PARENTREAD) {
119 int isFineWrite(REntry *r) {
120 if (r->type==WRITE || r->type==PARENTWRITE) {
127 int isCoarse(REntry *r){
128 if(r->type==COARSE || r->type==PARENTCOARSE){
135 int isSCC(REntry *r){
136 if(r->type==SCCITEM){
143 int isSingleItem(MemoryQueueItem *qItem){
144 if(qItem->type==SINGLEITEM){
151 int isHashtable(MemoryQueueItem *qItem){
152 if(qItem->type==HASHTABLE){
159 int isVector(MemoryQueueItem *qItem){
160 if(qItem->type==VECTOR){
167 int isReadBinItem(BinItem* b){
168 if(b->type==READBIN){
175 int isWriteBinItem(BinItem* b){
176 if(b->type==WRITEBIN){
183 int generateKey(unsigned int data){
184 return (data&H_MASK)>> 4;
187 Hashtable* createHashtable(){
189 Hashtable* newTable=(Hashtable*)MLPMALLOC(sizeof(Hashtable));
190 newTable->item.type=HASHTABLE;
191 for(i=0;i<NUMBINS;i++){
192 newTable->array[i]=(BinElement*)MLPMALLOC(sizeof(BinElement));
193 newTable->array[i]->head=NULL;
194 newTable->array[i]->tail=NULL;
196 newTable->unresolvedQueue=NULL;
200 WriteBinItem* createWriteBinItem(){
201 WriteBinItem* binitem=(WriteBinItem*)MLPMALLOC(sizeof(WriteBinItem));
202 binitem->item.type=WRITEBIN;
206 ReadBinItem* createReadBinItem(){
207 ReadBinItem* binitem=(ReadBinItem*)MLPMALLOC(sizeof(ReadBinItem));
209 binitem->item.type=READBIN;
213 Vector* createVector(){
214 Vector* vector=(Vector*)MLPMALLOC(sizeof(Vector));
216 vector->item.type=VECTOR;
221 SCC* scc=(SCC*)MLPMALLOC(sizeof(SCC));
222 scc->item.type=SINGLEITEM;
226 MemoryQueue* createMemoryQueue(){
227 MemoryQueue* queue = (MemoryQueue*)MLPMALLOC(sizeof(MemoryQueue));
228 MemoryQueueItem* dummy=(MemoryQueueItem*)MLPMALLOC(sizeof(MemoryQueueItem));
229 dummy->type=3; // dummy type
237 int ADDRENTRY(MemoryQueue * q, REntry * r) {
238 if (isFineRead(r) || isFineWrite(r)) {
239 return ADDTABLE(q, r);
240 } else if (isCoarse(r)) {
241 return ADDVECTOR(q, r);
242 } else if (isSCC(r)) {
247 int ADDTABLE(MemoryQueue *q, REntry *r) {
248 if(!isHashtable(q->tail)) {
250 MemoryQueueItem* tail=q->tail;
251 if (isParent(r) && tail->total==0 && q->tail==q->head) {
256 Hashtable* h=createHashtable();
257 tail->next=(MemoryQueueItem*)h;
258 //************NEED memory barrier here to ensure compiler does not cache Q.tail.status********
259 if (BARRIER() && tail->status==READY && tail->total==0 && q->tail==q->head) {
260 //previous Q item is finished
261 h->item.status=READY;
263 q->tail=(MemoryQueueItem*)h;
264 // handle the the queue item case
265 if(q->head->type==3){
266 q->head=(MemoryQueueItem*)h;
270 //at this point, have table
271 Hashtable* table=(Hashtable*)q->tail;
272 r->hashtable=table; // set rentry's hashtable
273 if((*(r->pointer)==0 || (*(r->pointer)!=0 && BARRIER() && table->unresolvedQueue!=NULL))){
275 // grab lock on the queue
277 val=(struct Queue*)0x1;
278 val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
279 } while(val==(struct Queue*)0x1);
281 //queue is null, first case
282 if(*(r->pointer)!=0){
283 // check whether pointer is already resolved, or not.
284 table->unresolvedQueue=NULL; //released lock;
285 return ADDTABLEITEM(table,r,TRUE);
287 struct Queue* queue=createQueue();
288 addNewItemBack(queue,r);
289 atomic_inc(&table->item.total);
290 table->unresolvedQueue=queue; // expose new queue
292 // add unresolved rentry at the end of the queue.
293 addNewItemBack(val,r);
294 atomic_inc(&table->item.total);
295 table->unresolvedQueue=val; // released lock
300 //int key=generateKey((unsigned int)(unsigned INTPTR)*(r->pointer));
301 int key=generateKey(r->oid);
304 BinElement* bin=table->array[key];
305 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);//note...talk to me about optimizations here.
306 } while(val==(BinItem*)0x1);
307 //at this point have locked bin
309 return EMPTYBINCASE(table, table->array[key], r, TRUE);
311 if (isFineWrite(r)) {
312 return WRITEBINCASE(table, r, val, key, TRUE);
313 } else if (isFineRead(r)) {
314 return READBINCASE(table, r, val, key, TRUE);
319 int ADDTABLEITEM(Hashtable* table, REntry* r, int inc){
322 // int key=generateKey((unsigned int)(unsigned INTPTR)*(r->pointer));
323 int key=generateKey(r->oid);
326 BinElement* bin=table->array[key];
327 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);
328 } while(val==(BinItem*)0x1);
329 //at this point have locked bin
331 return EMPTYBINCASE(table, table->array[key], r, inc);
333 if (isFineWrite(r)) {
334 return WRITEBINCASE(table, r, val, key, inc);
335 } else if (isFineRead(r)) {
336 return READBINCASE(table, r, val, key, inc);
341 int EMPTYBINCASE(Hashtable *T, BinElement* be, REntry *r, int inc) {
344 if (isFineWrite(r)) {
345 b=(BinItem*)createWriteBinItem();
346 ((WriteBinItem*)b)->val=r;//<-only different statement
347 } else if (isFineRead(r)) {
348 b=(BinItem*)createReadBinItem();
349 ReadBinItem* readbin=(ReadBinItem*)b;
350 readbin->array[readbin->index++]=r;
354 if (T->item.status==READY) {
355 //current entry is ready
359 be->head=NULL; // released lock
368 atomic_inc(&T->item.total);
373 be->head=b;//released lock
377 int WRITEBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) {
378 //chain of bins exists => tail is valid
379 //if there is something in front of us, then we are not ready
382 BinElement* be=T->array[key];
384 BinItem *bintail=be->tail;
386 WriteBinItem *b=createWriteBinItem();
390 // note: If current table clears all dependencies, then write bin is ready
394 atomic_inc(&T->item.total);
398 r->binitem=(BinItem*)b;
400 be->tail->next=(BinItem*)b;
401 //need to check if we can go...
403 if (T->item.status==READY) {
404 for(;val!=NULL;val=val->next) {
405 if (val==((BinItem *)b)) {
409 b->item.status=retval;//unsure if really needed at this point..
410 be->head=NULL; // released lock
414 } else if (val->total!=0) {
420 b->item.status=retval;
421 be->tail=(BinItem*)b;
426 READBINCASE(Hashtable *T, REntry *r, BinItem *val, int key, int inc) {
427 BinItem * bintail=T->array[key]->tail;
428 if (isReadBinItem(bintail)) {
429 return TAILREADCASE(T, r, val, bintail, key, inc);
430 } else if (!isReadBinItem(bintail)) {
431 TAILWRITECASE(T, r, val, bintail, key, inc);
436 int TAILREADCASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
437 ReadBinItem * readbintail=(ReadBinItem*)T->array[key]->tail;
439 if (readbintail->item.status==READY) {
443 T->array[key]->head=val;//released lock
451 if (readbintail->index==NUMREAD) { // create new read group
452 ReadBinItem* rb=createReadBinItem();
453 rb->array[rb->index++]=r;
454 rb->item.total=1;//safe only because item could not have started
455 rb->item.status=status;
456 T->array[key]->tail->next=(BinItem*)rb;
457 T->array[key]->tail=(BinItem*)rb;
458 r->binitem=(BinItem*)rb;
459 } else { // group into old tail
460 readbintail->array[readbintail->index++]=r;
461 atomic_inc(&readbintail->item.total);
462 r->binitem=(BinItem*)readbintail;
463 //printf("grouping with %d\n",readbintail->index);
466 atomic_inc(&T->item.total);
469 T->array[key]->head=val;//released lock
473 TAILWRITECASE(Hashtable *T, REntry *r, BinItem *val, BinItem *bintail, int key, int inc) {
474 // WriteBinItem* wb=createWriteBinItem();
476 //wb->item.total=1;//safe because item could not have started
477 //wb->item.status=NOTREADY;
478 ReadBinItem* rb=createReadBinItem();
479 rb->array[rb->index++]=r;
480 rb->item.total=1;//safe because item could not have started
481 rb->item.status=NOTREADY;
483 atomic_inc(&T->item.total);
486 r->binitem=(BinItem*)rb;
487 T->array[key]->tail->next=(BinItem*)rb;
488 T->array[key]->tail=(BinItem*)rb;
489 T->array[key]->head=val;//released lock
492 ADDVECTOR(MemoryQueue *Q, REntry *r) {
493 if(!isVector(Q->tail)) {
495 if (isParentCoarse(r) && Q->tail->total==0 && Q->tail==Q->head) {
500 Vector* V=createVector();
501 Q->tail->next=(MemoryQueueItem*)V;
502 //************NEED memory barrier here to ensure compiler does not cache Q.tail.status******
503 if (BARRIER() && Q->tail->status==READY&&Q->tail->total==0) {
504 //previous Q item is finished
505 V->item.status=READY;
507 Q->tail=(MemoryQueueItem*)V;
508 // handle the the queue item case
509 if(Q->head->type==3){
510 Q->head=(MemoryQueueItem*)V;
513 //at this point, have vector
514 Vector* V=(Vector*)Q->tail;
515 if (V->index==NUMITEMS) {
519 V->item.status=NOTREADY;
520 Q->tail->next=(MemoryQueueItem*)V;
521 //***NEED memory barrier here to ensure compiler does not cache Q.tail.status******
522 if (BARRIER() && Q->tail->status==READY) {
523 V->item.status=READY;
525 Q->tail=(MemoryQueueItem*)V;
528 atomic_inc(&V->item.total);
532 //*****NEED memory barrier here to ensure compiler does not reorder writes to V.array and V.index
535 //*****NEED memory barrier here to ensure compiler does not cache V.status*********
537 if (BARRIER() && V->item.status==READY) {
539 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(V->array[index]), (unsigned INTPTR)flag);
541 if (isParentCoarse(r)) { //parent's retire immediately
542 atomic_dec(&V->item.total);
546 return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
554 //SCC's don't come in parent variety
555 ADDSCC(MemoryQueue *Q, REntry *r) {
561 Q->tail->next=(MemoryQueueItem*)S;
562 //*** NEED BARRIER HERE
563 if (BARRIER() && Q->tail->status==READY && Q->tail->total==0 && Q->tail==Q->head) {
564 //previous Q item is finished
565 S->item.status=READY;
566 Q->tail=(MemoryQueueItem*)S;
567 // handle the the queue item case
568 if(Q->head->type==3){
569 Q->head=(MemoryQueueItem*)S;
572 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(S->val), (unsigned INTPTR)flag);
576 return NOTREADY;//<- means that some other dispatcher got this one...so need to do accounting correctly
579 Q->tail=(MemoryQueueItem*)S;
585 void RETIRERENTRY(MemoryQueue* Q, REntry * r) {
586 if (isFineWrite(r)||isFineRead(r)) {
587 RETIREHASHTABLE(Q, r);
588 } else if (isCoarse(r)) {
590 } else if (isSCC(r)) {
595 RETIRESCC(MemoryQueue *Q, REntry *r) {
597 s->item.total=0;//don't need atomicdec
602 RETIREHASHTABLE(MemoryQueue *q, REntry *r) {
603 Hashtable *T=r->hashtable;
604 BinItem *b=r->binitem;
606 atomic_dec(&T->item.total);
607 if (T->item.next!=NULL && T->item.total==0) {
612 RETIREBIN(Hashtable *T, REntry *r, BinItem *b) {
613 // int key=generateKey((unsigned int)(unsigned INTPTR)*(r->pointer));
614 int key=generateKey(r->oid);
616 atomic_dec(&b->total);
618 if (isFineWrite(r) || (isFineRead(r) && b->next!=NULL && b->total==0)) {
619 // CHECK FIRST IF next is nonnull to guarantee that b.total cannot change
623 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(T->array[key]->head), (unsigned INTPTR)val);
624 } while(val==(BinItem*)0x1);
625 // at this point have locked bin
630 if (isReadBinItem(ptr)) {
631 ReadBinItem* rptr=(ReadBinItem*)ptr;
632 if (rptr->item.status==NOTREADY) {
633 for (i=0;i<rptr->index;i++) {
634 resolveDependencies(rptr->array[i]);
635 if (isParent(rptr->array[i])) {
636 //parents go immediately
637 atomic_dec(&rptr->item.total);
638 atomic_dec(&T->item.total);
642 rptr->item.status=READY;
643 if (rptr->item.next==NULL) {
646 if (rptr->item.total!=0) {
648 } else if ((BinItem*)rptr==val) {
651 } else if(isWriteBinItem(ptr)) {
654 if(ptr->status==NOTREADY){
655 resolveDependencies(((WriteBinItem*)ptr)->val);
657 if(isParent(((WriteBinItem*)ptr)->val)){
658 atomic_dec(&T->item.total);
662 }else{ // write bin is already resolved
666 if(ptr->status==NOTREADY) {
667 resolveDependencies(((WriteBinItem*)ptr)->val);
670 if (isParent(((WriteBinItem*)ptr)->val)) {
671 atomic_dec(&T->item.total);
681 T->array[key]->head=val; // release lock
686 RETIREVECTOR(MemoryQueue *Q, REntry *r) {
688 atomic_dec(&V->item.total);
689 if (V->item.next!=NULL && V->item.total==0) { //NOTE: ORDERING CRUCIAL HERE
694 RESOLVECHAIN(MemoryQueue *Q) {
696 MemoryQueueItem* head=Q->head;
697 if (head->next==NULL||head->total!=0) {
698 //item is not finished
699 if (head->status!=READY) {
700 //need to update status
702 if (isHashtable(head)) {
703 RESOLVEHASHTABLE(Q, head);
704 } else if (isVector(head)) {
705 RESOLVEVECTOR(Q, head);
706 } else if (isSingleItem(head)) {
709 if (head->next==NULL)
716 MemoryQueueItem* nextitem=head->next;
717 CAS((unsigned INTPTR*)&(Q->head), (unsigned INTPTR)head, (unsigned INTPTR)nextitem);
718 //oldvalue not needed... if we fail we just repeat
723 RESOLVEHASHTABLE(MemoryQueue *Q, Hashtable *T) {
725 for (binidx=0;binidx<NUMBINS;binidx++) {
726 BinElement* bin=T->array[binidx];
730 val=(BinItem*)LOCKXCHG((unsigned INTPTR*)&(bin->head), (unsigned INTPTR)val);
731 } while (val==(BinItem*)1);
732 //at this point have locked bin
735 if(ptr!=NULL&&ptr->status==NOTREADY) {
737 if (isWriteBinItem(ptr)) {
740 resolveDependencies(((WriteBinItem*)ptr)->val);
742 if (isParent(((WriteBinItem*)ptr)->val)) {
743 atomic_dec(&T->item.total);
747 } else if (isReadBinItem(ptr)) {
749 ReadBinItem* rptr=(ReadBinItem*)ptr;
750 for(i=0;i<rptr->index;i++) {
751 resolveDependencies(rptr->array[i]);
752 if (isParent(rptr->array[i])) {
753 atomic_dec(&rptr->item.total);
754 atomic_dec(&T->item.total);
757 if (rptr->item.next==NULL||rptr->item.total!=0) {
759 } else if((BinItem*)rptr==val) {
762 rptr->item.status=READY;
767 bin->head=val; // released lock;
771 RESOLVEVECTOR(MemoryQueue *q, Vector *V) {
777 for (i=0;i<NUMITEMS;i++) {
779 val=(REntry*)LOCKXCHG((unsigned INTPTR*)&(tmp->array[i]), (unsigned INTPTR)val);
781 resolveDependencies(val);
783 atomic_dec(&tmp->item.total);
787 if (tmp->item.next!=NULL&&isVector(tmp->item.next)) {
788 tmp=(Vector*)tmp->item.next;
796 //precondition: SCC's state is READY
798 flag=(void*)LOCKXCHG((unsigned INTPTR*)&(S->val), (unsigned INTPTR)flag);
800 resolveDependencies(flag);
805 resolveDependencies(REntry* rentry){
806 SESEcommon* seseCommon=(SESEcommon*)rentry->seseRec;
807 if(rentry->type==READ || rentry->type==WRITE || rentry->type==COARSE || rentry->type==SCCITEM){
808 if( atomic_sub_and_test(1, &(seseCommon->unresolvedDependencies)) ){
809 workScheduleSubmit(seseCommon);
811 }else if(rentry->type==PARENTREAD || rentry->type==PARENTWRITE ||rentry->type==PARENTCOARSE){
812 psem_give(&(rentry->parentStallSem));
816 void INITIALIZEBUF(MemoryQueue * q){
818 for(i=0; i<NUMBINS; i++){
824 void ADDRENTRYTOBUF(MemoryQueue * q, REntry * r){
825 q->buf[q->bufcount]=r;
829 int RESOLVEBUFFORHASHTABLE(MemoryQueue * q, Hashtable* table, SESEcommon *seseCommon){
831 // first phase: only consider write rentry
832 for(i=0; i<q->bufcount;i++){
835 int key=generateKey(r->oid);
836 if(q->binbuf[key]==NULL){
837 // for multiple writes, add only the first write that hashes to the same bin
844 // second phase: enqueue read items if it is eligible
845 for(i=0; i<q->bufcount;i++){
847 if(r!=NULL && r->type==READ){
848 int key=generateKey(r->oid);
849 if(q->binbuf[key]==NULL){
850 // read item that hashes to the bin which doen't contain any write
851 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
852 if(ADDTABLEITEM(table, r, FALSE)==READY){
853 resolveDependencies(r);
860 // then, add only one of write items that hashes to the same bin
861 for(i=0; i<q->bufcount;i++){
864 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
865 if(ADDTABLEITEM(table, r, FALSE)==READY){
866 resolveDependencies(r);
872 int RESOLVEBUF(MemoryQueue * q, SESEcommon *seseCommon){
875 // check if every waiting entry is resolved
876 // if not, defer every items for hashtable until it is resolved.
877 int unresolved=FALSE;
878 for(i=0; i<q->bufcount;i++){
880 if(*(r->pointer)==0){
884 if(unresolved==TRUE){
885 for(i=0; i<q->bufcount;i++){
889 if(ADDRENTRY(q,r)==NOTREADY){
896 // first phase: only consider write rentry
897 for(i=0; i<q->bufcount;i++){
900 int key=generateKey(r->oid);
901 if(q->binbuf[key]==NULL){
902 // for multiple writes, add only the first write that hashes to the same bin
909 // second phase: enqueue read items if it is eligible
910 for(i=0; i<q->bufcount;i++){
912 if(r!=NULL && r->type==READ){
913 int key=generateKey(r->oid);
914 if(q->binbuf[key]==NULL){
915 // read item that hashes to the bin which doen't contain any write
916 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
917 if(ADDRENTRY(q,r)==NOTREADY){
925 // then, add only one of write items that hashes to the same bin
926 for(i=0; i<q->bufcount;i++){
929 seseCommon->rentryArray[seseCommon->rentryIdx++]=r;
930 if(ADDRENTRY(q,r)==NOTREADY){
939 resolvePointer(REntry* rentry){
941 Hashtable* table=rentry->hashtable;
944 //resolved already before related rentry is enqueued to the waiting queue
949 val=(struct Queue*)0x1;
950 val=(struct Queue*)LOCKXCHG((unsigned INTPTR*)&(table->unresolvedQueue), (unsigned INTPTR)val);
951 } while(val==(struct Queue*)0x1);
952 if(val!=NULL && getHead(val)->objectptr==rentry){
953 // handling pointer is the first item of the queue
954 // start to resolve until it reaches unresolved pointer or end of queue
955 INTPTR currentSESE=0;
957 struct QueueItem* head=getHead(val);
959 REntry* rentry=(REntry*)head->objectptr;
960 if(*(rentry->pointer)==0){
961 // encounters following unresolved pointer
962 table->unresolvedQueue=val;//released lock
965 removeItem(val,head);
966 //now, address is resolved. update OID field.
967 struct ___Object___ * obj=(struct ___Object___*)((unsigned INTPTR)*rentry->pointer);
968 rentry->oid=obj->oid;
970 //check if rentry is buffer mode
971 if(rentry->isBufMode==TRUE){
974 INITIALIZEBUF(queue);
975 currentSESE=(INTPTR)rentry;
976 ADDRENTRYTOBUF(queue,rentry);
977 } else if(currentSESE==(INTPTR)rentry){
978 ADDRENTRYTOBUF(queue,rentry);
979 } else if(currentSESE!=(INTPTR)rentry){
980 RESOLVEBUFFORHASHTABLE(queue,table,(SESEcommon*)rentry->seseRec);
981 currentSESE=(INTPTR)rentry;
982 INITIALIZEBUF(queue);
983 ADDRENTRYTOBUF(rentry->queue,rentry);
987 //previous SESE has buf mode, need to invoke resolve buffer
988 RESOLVEBUFFORHASHTABLE(queue,table,(SESEcommon*)rentry->seseRec);
992 if(ADDTABLEITEM(table, rentry, FALSE)==READY){
993 resolveDependencies(rentry);
997 table->unresolvedQueue=NULL; // set hashtable as normal-mode.
1002 // resolved rentry is not head of queue
1003 table->unresolvedQueue=val;//released lock;
1007 void rehashMemoryQueue(SESEcommon_p seseParent){
1009 // update memory queue
1011 for(i=0; i<seseParent->numMemoryQueue; i++){
1012 MemoryQueue *memoryQueue=seseParent->memoryQueueArray[i];
1013 MemoryQueueItem *memoryItem=memoryQueue->head;
1014 MemoryQueueItem *prevItem=NULL;
1015 while(memoryItem!=NULL){
1016 if(memoryItem->type==HASHTABLE){
1018 Hashtable* ht=(Hashtable*)memoryItem;
1019 Hashtable* newht=createHashtable();
1021 for(binidx=0; binidx<NUMBINS; binidx++){
1022 BinElement *bin=ht->array[binidx];
1023 BinItem *binItem=bin->head;
1024 //traverse over the list of each bin
1025 while(binItem!=NULL){
1026 if(binItem->type==READBIN){
1027 ReadBinItem* readBinItem=(ReadBinItem*)binItem;
1029 for(ridx=0; ridx<readBinItem->index; ridx++){
1030 REntry *rentry=readBinItem->array[ridx];
1031 int newkey=generateKey((unsigned int)(unsigned INTPTR)*(rentry->pointer));
1032 int status=rentry->binitem->status;
1033 ADDTABLEITEM(newht,rentry,TRUE);
1034 rentry->binitem->status=status; // update bin status as before rehash
1037 REntry *rentry=((WriteBinItem*)binItem)->val;
1038 int newkey=generateKey((unsigned int)(unsigned INTPTR)*(rentry->pointer));
1039 int status=rentry->binitem->status;
1040 ADDTABLEITEM(newht,rentry,TRUE);
1041 int newstatus=rentry->binitem->status;
1042 //printf("[%d]old status=%d new status=%d\n",i,status,newstatus);
1043 rentry->binitem->status=status; // update bin status as before rehash
1045 binItem=binItem->next;
1048 newht->item.status=ht->item.status; // update hashtable status
1050 prevItem->next=(MemoryQueueItem*)newht;
1052 if(memoryQueue->head==memoryQueue->tail){
1053 memoryQueue->tail=(MemoryQueueItem*)newht;
1055 memoryQueue->head=(MemoryQueueItem*)newht;
1057 newht->item.next=ht->item.next;
1059 prevItem=memoryItem;
1060 memoryItem=memoryItem->next;