3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5 #include "GenericHashtable.h"
7 // data structures for task invocation
8 struct genhashtable * activetasks;
9 struct taskparamdescriptor * currtpd;
11 // specific functions used inside critical sections
12 void enqueueObject_I(void * ptr,
13 struct parameterwrapper ** queues,
15 int enqueuetasks_I(struct parameterwrapper *parameter,
16 struct parameterwrapper *prevptr,
17 struct ___Object___ *ptr,
21 inline void initruntimedata() {
22 // initialize the arrays
23 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
24 // startup core to initialize corestatus[]
25 for(i = 0; i < NUMCORES; ++i) {
28 numreceiveobjs[i] = 0;
30 // initialize the profile data arrays
36 gcnumreceiveobjs[i] = 0;
39 } // for(i = 0; i < NUMCORES; ++i)
49 self_numreceiveobjs = 0;
51 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
56 msglength = BAMBOO_MSG_BUF_LENGTH;
57 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
67 bamboo_cur_msp = NULL;
73 gcphase = FINISHPHASE;
74 gcself_numsendobjs = 0;
75 gcself_numreceiveobjs = 0;
77 gcpointertbl = allocateRuntimeHash(20);
96 gchead=gctail=gctail2=malloc(sizeof(struct pointerblock));
98 // initialize the large obj queues
99 if (gclobjhead==NULL) {
102 gclobjtailindex2 = 0;
103 gclobjhead=gclobjtail=gclobjtail2=
104 malloc(sizeof(struct lobjpointerblock));
107 // create the lock table, lockresult table and obj queue
110 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
111 /* Set allocation blocks*/
112 locktable.listhead=NULL;
113 locktable.listtail=NULL;
115 locktable.numelements = 0;
120 lockRedirectTbl = allocateRuntimeHash(20);
121 objRedirectLockTbl = allocateRuntimeHash(20);
126 objqueue.head = NULL;
127 objqueue.tail = NULL;
131 //isInterrupt = true;
134 taskInfoOverflow = false;
135 /*interruptInfoIndex = 0;
136 interruptInfoOverflow = false;*/
140 inline void disruntimedata() {
142 freeRuntimeHash(gcpointertbl);
144 freeRuntimeHash(lockRedirectTbl);
145 freeRuntimeHash(objRedirectLockTbl);
146 RUNFREE(locktable.bucket);
148 genfreehashtable(activetasks);
152 bool checkObjQueue() {
154 struct transObjInfo * objInfo = NULL;
158 #ifdef ACCURATEPROFILE
159 bool isChecking = false;
160 if(!isEmpty(&objqueue)) {
161 profileTaskStart("objqueue checking");
163 } // if(!isEmpty(&objqueue))
167 while(!isEmpty(&objqueue)) {
169 BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE();
171 BAMBOO_DEBUGPRINT(0xf001);
174 //isInterrupt = false;
177 BAMBOO_DEBUGPRINT(0xeee1);
180 objInfo = (struct transObjInfo *)getItem(&objqueue);
181 obj = objInfo->objptr;
183 BAMBOO_DEBUGPRINT_REG((int)obj);
185 // grab lock and flush the obj
189 BAMBOO_WAITING_FOR_LOCK();
190 } // while(!lockflag)
193 BAMBOO_DEBUGPRINT_REG(grount);
208 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
209 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
210 classsize[((struct ___Object___ *)obj)->type]);
212 // enqueue the object
213 for(k = 0; k < objInfo->length; ++k) {
214 int taskindex = objInfo->queues[2 * k];
215 int paramindex = objInfo->queues[2 * k + 1];
216 struct parameterwrapper ** queues =
217 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
219 BAMBOO_DEBUGPRINT_REG(taskindex);
220 BAMBOO_DEBUGPRINT_REG(paramindex);
221 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
222 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
223 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
224 (long)obj, tmpptr->flag);
226 enqueueObject_I(obj, queues, 1);
228 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
230 } // for(k = 0; k < objInfo->length; ++k)
231 releasewritelock_I(obj);
232 RUNFREE(objInfo->queues);
236 // put it at the end of the queue if no update version in the queue
237 struct QueueItem * qitem = getHead(&objqueue);
238 struct QueueItem * prev = NULL;
239 while(qitem != NULL) {
240 struct transObjInfo * tmpinfo =
241 (struct transObjInfo *)(qitem->objectptr);
242 if(tmpinfo->objptr == obj) {
243 // the same object in the queue, which should be enqueued
244 // recently. Current one is outdate, do not re-enqueue it
245 RUNFREE(objInfo->queues);
250 } // if(tmpinfo->objptr == obj)
251 qitem = getNextQueueItem(prev);
252 } // while(qitem != NULL)
253 // try to execute active tasks already enqueued first
254 addNewItem_I(&objqueue, objInfo);
256 //isInterrupt = true;
259 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
261 BAMBOO_DEBUGPRINT(0xf000);
265 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
267 BAMBOO_DEBUGPRINT(0xf000);
269 } // while(!isEmpty(&objqueue))
272 #ifdef ACCURATEPROFILE
280 BAMBOO_DEBUGPRINT(0xee02);
285 inline void checkCoreStatue() {
286 bool allStall = false;
290 (waitconfirm && (numconfirm == 0))) {
292 BAMBOO_DEBUGPRINT(0xee04);
293 BAMBOO_DEBUGPRINT_REG(waitconfirm);
295 BAMBOO_START_CRITICAL_SECTION_STATUS();
297 BAMBOO_DEBUGPRINT(0xf001);
299 corestatus[BAMBOO_NUM_OF_CORE] = 0;
300 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
301 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
302 // check the status of all cores
305 BAMBOO_DEBUGPRINT_REG(NUMCORES);
307 for(i = 0; i < NUMCORES; ++i) {
309 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
311 if(corestatus[i] != 0) {
315 } // for(i = 0; i < NUMCORES; ++i)
317 // check if the sum of send objs and receive obj are the same
318 // yes->check if the info is the latest; no->go on executing
320 for(i = 0; i < NUMCORES; ++i) {
321 sumsendobj += numsendobjs[i];
323 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
325 } // for(i = 0; i < NUMCORES; ++i)
326 for(i = 0; i < NUMCORES; ++i) {
327 sumsendobj -= numreceiveobjs[i];
329 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
331 } // for(i = 0; i < NUMCORES; ++i)
332 if(0 == sumsendobj) {
334 // the first time found all cores stall
335 // send out status confirm msg to all other cores
336 // reset the corestatus array too
338 BAMBOO_DEBUGPRINT(0xee05);
340 corestatus[BAMBOO_NUM_OF_CORE] = 1;
341 for(i = 1; i < NUMCORES; ++i) {
343 // send status confirm msg to core i
344 send_msg_1(i, STATUSCONFIRM);
345 } // for(i = 1; i < NUMCORES; ++i)
347 numconfirm = NUMCORES - 1;
349 // all the core status info are the latest
350 // terminate; for profiling mode, send request to all
351 // other cores to pour out profiling data
353 BAMBOO_DEBUGPRINT(0xee06);
357 totalexetime = BAMBOO_GET_EXE_TIME();
359 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
360 BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
361 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
363 // profile mode, send msgs to other cores to request pouring
364 // out progiling data
366 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
368 BAMBOO_DEBUGPRINT(0xf000);
370 for(i = 1; i < NUMCORES; ++i) {
371 // send profile request msg to core i
372 send_msg_2(i, PROFILEOUTPUT, totalexetime);
373 } // for(i = 1; i < NUMCORES; ++i)
374 // pour profiling data on startup core
377 BAMBOO_START_CRITICAL_SECTION_STATUS();
379 BAMBOO_DEBUGPRINT(0xf001);
381 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
382 // check the status of all cores
385 BAMBOO_DEBUGPRINT_REG(NUMCORES);
387 for(i = 0; i < NUMCORES; ++i) {
389 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
391 if(profilestatus[i] != 0) {
395 } // for(i = 0; i < NUMCORES; ++i)
398 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
400 BAMBOO_DEBUGPRINT(0xf000);
410 terminate(); // All done.
411 } // if(!waitconfirm)
413 // still some objects on the fly on the network
414 // reset the waitconfirm and numconfirm
416 BAMBOO_DEBUGPRINT(0xee07);
420 } // if(0 == sumsendobj)
422 // not all cores are stall, keep on waiting
424 BAMBOO_DEBUGPRINT(0xee08);
429 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
431 BAMBOO_DEBUGPRINT(0xf000);
433 } // if((!waitconfirm) ||
436 // main function for each core
437 inline void run(void * arg) {
441 bool sendStall = false;
443 bool tocontinue = false;
445 corenum = BAMBOO_GET_NUM_OF_CORE();
447 BAMBOO_DEBUGPRINT(0xeeee);
448 BAMBOO_DEBUGPRINT_REG(corenum);
449 BAMBOO_DEBUGPRINT(STARTUPCORE);
452 // initialize runtime data structures
455 // other architecture related initialization
459 initializeexithandler();
461 // main process of the execution module
462 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
463 // non-executing cores, only processing communications
466 BAMBOO_DEBUGPRINT(0xee01);
467 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
468 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
469 profileTaskStart("msg handling");
473 //isInterrupt = false;
477 /* Create queue of active tasks */
479 genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
480 (int(*) (void *,void *)) &comparetpd);
482 /* Process task information */
485 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
486 /* Create startup object */
487 createstartupobject(argc, argv);
491 BAMBOO_DEBUGPRINT(0xee00);
496 // check if need to do GC
500 // check if there are new active tasks can be executed
504 while(receiveObject() != -1) {
509 BAMBOO_DEBUGPRINT(0xee01);
512 // check if there are some pending objects,
513 // if yes, enqueue them and executetasks again
514 tocontinue = checkObjQueue();
518 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
521 BAMBOO_DEBUGPRINT(0xee03);
529 BAMBOO_DEBUGPRINT(0xee09);
535 // wait for some time
538 BAMBOO_DEBUGPRINT(0xee0a);
544 // send StallMsg to startup core
546 BAMBOO_DEBUGPRINT(0xee0b);
549 send_msg_4(STARTUPCORE, 1, BAMBOO_NUM_OF_CORE,
550 self_numsendobjs, self_numreceiveobjs);
562 BAMBOO_DEBUGPRINT(0xee0c);
565 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
568 } // if(BAMBOO_NUM_OF_CORE > NUMCORES - 1)
572 void createstartupobject(int argc,
576 /* Allocate startup object */
578 struct ___StartupObject___ *startupobject=
579 (struct ___StartupObject___*) allocate_new(NULL, STARTUPTYPE);
580 struct ArrayObject * stringarray=
581 allocate_newarray(NULL, STRINGARRAYTYPE, argc-1);
583 struct ___StartupObject___ *startupobject=
584 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
585 struct ArrayObject * stringarray=
586 allocate_newarray(STRINGARRAYTYPE, argc-1);
588 /* Build array of strings */
589 startupobject->___parameters___=stringarray;
590 for(i=1; i<argc; i++) {
591 int length=strlen(argv[i]);
593 struct ___String___ *newstring=NewString(NULL, argv[i],length);
595 struct ___String___ *newstring=NewString(argv[i],length);
597 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
601 startupobject->version = 0;
602 startupobject->lock = NULL;
604 /* Set initialized flag for startup object */
605 flagorandinit(startupobject,1,0xFFFFFFFF);
606 enqueueObject(startupobject, NULL, 0);
608 BAMBOO_CACHE_FLUSH_ALL();
612 int hashCodetpd(struct taskparamdescriptor *ftd) {
613 int hash=(int)ftd->task;
615 for(i=0; i<ftd->numParameters; i++) {
616 hash^=(int)ftd->parameterArray[i];
621 int comparetpd(struct taskparamdescriptor *ftd1,
622 struct taskparamdescriptor *ftd2) {
624 if (ftd1->task!=ftd2->task)
626 for(i=0; i<ftd1->numParameters; i++)
627 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
632 /* This function sets a tag. */
634 void tagset(void *ptr,
635 struct ___Object___ * obj,
636 struct ___TagDescriptor___ * tagd) {
638 void tagset(struct ___Object___ * obj,
639 struct ___TagDescriptor___ * tagd) {
641 struct ArrayObject * ao=NULL;
642 struct ___Object___ * tagptr=obj->___tags___;
644 obj->___tags___=(struct ___Object___ *)tagd;
646 /* Have to check if it is already set */
647 if (tagptr->type==TAGTYPE) {
648 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
653 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
654 struct ArrayObject * ao=
655 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
656 obj=(struct ___Object___ *)ptrarray[2];
657 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
658 td=(struct ___TagDescriptor___ *) obj->___tags___;
660 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
663 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
664 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
665 obj->___tags___=(struct ___Object___ *) ao;
666 ao->___cachedCode___=2;
670 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
671 for(i=0; i<ao->___cachedCode___; i++) {
672 struct ___TagDescriptor___ * td=
673 ARRAYGET(ao, struct ___TagDescriptor___*, i);
678 if (ao->___cachedCode___<ao->___length___) {
679 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
680 ao->___cachedCode___++;
683 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
684 struct ArrayObject * aonew=
685 allocate_newarray(&ptrarray,TAGARRAYTYPE,
686 TAGARRAYINTERVAL+ao->___length___);
687 obj=(struct ___Object___ *)ptrarray[2];
688 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
689 ao=(struct ArrayObject *)obj->___tags___;
691 struct ArrayObject * aonew=
692 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
695 aonew->___cachedCode___=ao->___length___+1;
696 for(i=0; i<ao->___length___; i++) {
697 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
698 ARRAYGET(ao, struct ___TagDescriptor___*, i));
700 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
706 struct ___Object___ * tagset=tagd->flagptr;
709 } else if (tagset->type!=OBJECTARRAYTYPE) {
711 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
712 struct ArrayObject * ao=
713 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
714 obj=(struct ___Object___ *)ptrarray[2];
715 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
717 struct ArrayObject * ao=
718 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
720 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
721 ARRAYSET(ao, struct ___Object___ *, 1, obj);
722 ao->___cachedCode___=2;
723 tagd->flagptr=(struct ___Object___ *)ao;
725 struct ArrayObject *ao=(struct ArrayObject *) tagset;
726 if (ao->___cachedCode___<ao->___length___) {
727 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
731 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
732 struct ArrayObject * aonew=
733 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
734 OBJECTARRAYINTERVAL+ao->___length___);
735 obj=(struct ___Object___ *)ptrarray[2];
736 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
737 ao=(struct ArrayObject *)tagd->flagptr;
739 struct ArrayObject * aonew=
740 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
742 aonew->___cachedCode___=ao->___cachedCode___+1;
743 for(i=0; i<ao->___length___; i++) {
744 ARRAYSET(aonew, struct ___Object___*, i,
745 ARRAYGET(ao, struct ___Object___*, i));
747 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
748 tagd->flagptr=(struct ___Object___ *) aonew;
754 /* This function clears a tag. */
756 void tagclear(void *ptr,
757 struct ___Object___ * obj,
758 struct ___TagDescriptor___ * tagd) {
760 void tagclear(struct ___Object___ * obj,
761 struct ___TagDescriptor___ * tagd) {
763 /* We'll assume that tag is alway there.
764 Need to statically check for this of course. */
765 struct ___Object___ * tagptr=obj->___tags___;
767 if (tagptr->type==TAGTYPE) {
768 if ((struct ___TagDescriptor___ *)tagptr==tagd)
769 obj->___tags___=NULL;
771 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
773 for(i=0; i<ao->___cachedCode___; i++) {
774 struct ___TagDescriptor___ * td=
775 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
777 ao->___cachedCode___--;
778 if (i<ao->___cachedCode___)
779 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
780 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
781 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
782 if (ao->___cachedCode___==0)
783 obj->___tags___=NULL;
790 struct ___Object___ *tagset=tagd->flagptr;
791 if (tagset->type!=OBJECTARRAYTYPE) {
795 struct ArrayObject *ao=(struct ArrayObject *) tagset;
797 for(i=0; i<ao->___cachedCode___; i++) {
798 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
800 ao->___cachedCode___--;
801 if (i<ao->___cachedCode___)
802 ARRAYSET(ao, struct ___Object___ *, i,
803 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
804 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
805 if (ao->___cachedCode___==0)
816 /* This function allocates a new tag. */
818 struct ___TagDescriptor___ * allocate_tag(void *ptr,
820 struct ___TagDescriptor___ * v=
821 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
824 struct ___TagDescriptor___ * allocate_tag(int index) {
825 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
827 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
835 /* This function updates the flag for object ptr. It or's the flag
836 with the or mask and and's it with the andmask. */
838 void flagbody(struct ___Object___ *ptr,
840 struct parameterwrapper ** queues,
844 int flagcomp(const int *val1, const int *val2) {
845 return (*val1)-(*val2);
848 void flagorand(void * ptr,
851 struct parameterwrapper ** queues,
854 int oldflag=((int *)ptr)[1];
855 int flag=ormask|oldflag;
857 flagbody(ptr, flag, queues, length, false);
861 bool intflagorand(void * ptr,
865 int oldflag=((int *)ptr)[1];
866 int flag=ormask|oldflag;
868 if (flag==oldflag) /* Don't do anything */
871 flagbody(ptr, flag, NULL, 0, false);
877 void flagorandinit(void * ptr,
880 int oldflag=((int *)ptr)[1];
881 int flag=ormask|oldflag;
883 flagbody(ptr,flag,NULL,0,true);
886 void flagbody(struct ___Object___ *ptr,
888 struct parameterwrapper ** vqueues,
891 struct parameterwrapper * flagptr = NULL;
893 struct parameterwrapper ** queues = vqueues;
894 int length = vlength;
897 int * enterflags = NULL;
898 if((!isnew) && (queues == NULL)) {
899 if(BAMBOO_NUM_OF_CORE < NUMCORES) {
900 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
901 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
908 /*Remove object from all queues */
909 for(i = 0; i < length; ++i) {
911 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
912 (int *) &enterflags, &UNUSED, &UNUSED2);
913 ObjectHashremove(flagptr->objectset, (int)ptr);
914 if (enterflags!=NULL)
919 void enqueueObject(void * vptr,
920 struct parameterwrapper ** vqueues,
922 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
925 //struct QueueItem *tmpptr;
926 struct parameterwrapper * parameter=NULL;
929 struct parameterwrapper * prevptr=NULL;
930 struct ___Object___ *tagptr=NULL;
931 struct parameterwrapper ** queues = vqueues;
932 int length = vlength;
933 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
937 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
938 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
940 tagptr=ptr->___tags___;
942 /* Outer loop iterates through all parameter queues an object of
943 this type could be in. */
944 for(j = 0; j < length; ++j) {
945 parameter = queues[j];
947 if (parameter->numbertags>0) {
949 goto nextloop; //that means the object has no tag
950 //but that param needs tag
951 else if(tagptr->type==TAGTYPE) { //one tag
952 //struct ___TagDescriptor___ * tag=
953 //(struct ___TagDescriptor___*) tagptr;
954 for(i=0; i<parameter->numbertags; i++) {
955 //slotid is parameter->tagarray[2*i];
956 int tagid=parameter->tagarray[2*i+1];
957 if (tagid!=tagptr->flag)
958 goto nextloop; /*We don't have this tag */
960 } else { //multiple tags
961 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
962 for(i=0; i<parameter->numbertags; i++) {
963 //slotid is parameter->tagarray[2*i];
964 int tagid=parameter->tagarray[2*i+1];
966 for(j=0; j<ao->___cachedCode___; j++) {
967 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
978 for(i=0; i<parameter->numberofterms; i++) {
979 int andmask=parameter->intarray[i*2];
980 int checkmask=parameter->intarray[i*2+1];
981 if ((ptr->flag&andmask)==checkmask) {
982 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
993 void enqueueObject_I(void * vptr,
994 struct parameterwrapper ** vqueues,
996 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
999 //struct QueueItem *tmpptr;
1000 struct parameterwrapper * parameter=NULL;
1003 struct parameterwrapper * prevptr=NULL;
1004 struct ___Object___ *tagptr=NULL;
1005 struct parameterwrapper ** queues = vqueues;
1006 int length = vlength;
1007 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1010 if(queues == NULL) {
1011 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1012 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1014 tagptr=ptr->___tags___;
1016 /* Outer loop iterates through all parameter queues an object of
1017 this type could be in. */
1018 for(j = 0; j < length; ++j) {
1019 parameter = queues[j];
1021 if (parameter->numbertags>0) {
1023 goto nextloop; //that means the object has no tag
1024 //but that param needs tag
1025 else if(tagptr->type==TAGTYPE) { //one tag
1026 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1027 for(i=0; i<parameter->numbertags; i++) {
1028 //slotid is parameter->tagarray[2*i];
1029 int tagid=parameter->tagarray[2*i+1];
1030 if (tagid!=tagptr->flag)
1031 goto nextloop; /*We don't have this tag */
1033 } else { //multiple tags
1034 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1035 for(i=0; i<parameter->numbertags; i++) {
1036 //slotid is parameter->tagarray[2*i];
1037 int tagid=parameter->tagarray[2*i+1];
1039 for(j=0; j<ao->___cachedCode___; j++) {
1040 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1051 for(i=0; i<parameter->numberofterms; i++) {
1052 int andmask=parameter->intarray[i*2];
1053 int checkmask=parameter->intarray[i*2+1];
1054 if ((ptr->flag&andmask)==checkmask) {
1055 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1067 int * getAliasLock(void ** ptrs,
1069 struct RuntimeHash * tbl) {
1071 return (int*)(RUNMALLOC(sizeof(int)));
1076 bool redirect = false;
1077 int redirectlock = 0;
1078 for(; i < length; i++) {
1079 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1082 if(ptr->lock == NULL) {
1085 lock = (int)(ptr->lock);
1088 if(lock != redirectlock) {
1089 RuntimeHashadd(tbl, lock, redirectlock);
1092 if(RuntimeHashcontainskey(tbl, lock)) {
1093 // already redirected
1095 RuntimeHashget(tbl, lock, &redirectlock);
1096 for(; j < locklen; j++) {
1097 if(locks[j] != redirectlock) {
1098 RuntimeHashadd(tbl, locks[j], redirectlock);
1103 for(j = 0; j < locklen; j++) {
1104 if(locks[j] == lock) {
1107 } else if(locks[j] > lock) {
1114 locks[h] = locks[h-1];
1123 return (int *)redirectlock;
1125 return (int *)(locks[0]);
1130 void addAliasLock(void * ptr,
1132 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1133 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1134 // originally no alias lock associated or have a different alias lock
1135 // flush it as the new one
1136 obj->lock = (int *)lock;
1141 inline void setTaskExitIndex(int index) {
1142 taskInfoArray[taskInfoIndex]->exitIndex = index;
1145 inline void addNewObjInfo(void * nobj) {
1146 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1147 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1149 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1153 void * smemalloc(int size,
1156 // go through free mem list for suitable blocks
1157 struct freeMemItem * freemem = bamboo_free_mem_list->head;
1158 struct freeMemItem * prev = NULL;
1160 if(freemem->size > size) {
1165 freemem = freemem->next;
1166 } while(freemem != NULL);
1167 if(freemem != NULL) {
1168 void * mem = (void *)(freemem->ptr);
1170 freemem->ptr += size;
1171 freemem->size -= size;
1172 // check how many blocks it acrosses
1174 BLOCKINDEX(mem, &b);
1175 // check the remaining space in this block
1176 int remain = (b < NUMCORES? (b+1)*BAMBOO_SMEM_SIZE_L
1177 : BAMBOO_LARGE_SMEM_BOUND+(b-NUMCORES+1)*BAMBOO_SMEM_SIZE)
1178 -(mem-BAMBOO_BASE_VA);
1180 // this object acrosses blocks
1181 int tmpsbs = 1+(size-remain-1)/BAMBOO_SMEM_SIZE;
1182 for(int k = 0; k < tmpsbs-1; k++) {
1183 sbstarttbl[k+b] = (INTPTR)(-1);
1185 if((size-remain)%BAMBOO_SMEM_SIZE == 0) {
1186 sbstarttbl[b+tmpsbs-1] = (INTPTR)(-1);
1188 sbstarttbl[b+tmpsbs-1] = (INTPTR)(mem+size);
1193 void * mem = mspace_calloc(bamboo_free_msp, 1, size);
1197 // no enough shared global memory
1201 gcrequiredmem = size;
1204 BAMBOO_DEBUGPRINT(0xa016);
1205 BAMBOO_EXIT(0xa016);
1211 // receive object transferred from other cores
1212 // or the terminate message from other cores
1213 // Should be invoked in critical sections!!
1214 // NOTICE: following format is for threadsimulate version only
1215 // RAW version please see previous description
1216 // format: type + object
1217 // type: -1--stall msg
1219 // return value: 0--received an object
1220 // 1--received nothing
1221 // 2--received a Stall Msg
1222 // 3--received a lock Msg
1223 // RAW version: -1 -- received nothing
1224 // otherwise -- received msg type
1225 int receiveObject() {
1229 if(receiveMsg() == -1) {
1233 if(msgdataindex == msglength) {
1234 // received a whole msg
1239 // receive a object transfer msg
1240 struct transObjInfo * transObj =
1241 RUNMALLOC_I(sizeof(struct transObjInfo));
1245 BAMBOO_DEBUGPRINT(0xe880);
1248 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1250 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1252 BAMBOO_EXIT(0xa005);
1254 // store the object and its corresponding queue info, enqueue it later
1255 transObj->objptr = (void *)msgdata[2];
1256 transObj->length = (msglength - 3) / 2;
1257 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1258 for(k = 0; k < transObj->length; ++k) {
1259 transObj->queues[2*k] = msgdata[3+2*k];
1262 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1265 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1268 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1272 // check if there is an existing duplicate item
1274 struct QueueItem * qitem = getHead(&objqueue);
1275 struct QueueItem * prev = NULL;
1276 while(qitem != NULL) {
1277 struct transObjInfo * tmpinfo =
1278 (struct transObjInfo *)(qitem->objectptr);
1279 if(tmpinfo->objptr == transObj->objptr) {
1280 // the same object, remove outdate one
1281 removeItem(&objqueue, qitem);
1287 qitem = getHead(&objqueue);
1289 qitem = getNextQueueItem(prev);
1292 addNewItem_I(&objqueue, (void *)transObj);
1294 ++(self_numreceiveobjs);
1299 // receive a stall msg
1300 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1301 // non startup core can not receive stall msg
1303 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1305 BAMBOO_EXIT(0xa006);
1307 if(msgdata[1] < NUMCORES) {
1310 BAMBOO_DEBUGPRINT(0xe881);
1313 corestatus[msgdata[1]] = 0;
1314 numsendobjs[msgdata[1]] = msgdata[2];
1315 numreceiveobjs[msgdata[1]] = msgdata[3];
1320 // GC version have no lock msgs
1321 #ifndef MULTICORE_GC
1323 // receive lock request msg, handle it right now
1324 // check to see if there is a lock exist for the required obj
1325 // msgdata[1] -> lock type
1326 int data2 = msgdata[2]; // obj pointer
1327 int data3 = msgdata[3]; // lock
1328 int data4 = msgdata[4]; // request core
1329 // -1: redirected, 0: approved, 1: denied
1330 deny = processlockrequest(msgdata[1], data3, data2,
1331 data4, data4, true);
1333 // this lock request is redirected
1336 // send response msg
1337 // for 32 bit machine, the size is always 4 words
1338 int tmp = deny==1?LOCKDENY:LOCKGROUNT;
1340 cache_msg_4(data4, tmp, msgdata[1], data2, data3);
1342 send_msg_4(data4, tmp, msgdata[1], data2, data3);
1349 // receive lock grount msg
1350 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1352 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1354 BAMBOO_EXIT(0xa007);
1356 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1359 BAMBOO_DEBUGPRINT(0xe882);
1368 // conflicts on lockresults
1370 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1372 BAMBOO_EXIT(0xa008);
1378 // receive lock deny msg
1379 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1381 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1383 BAMBOO_EXIT(0xa009);
1385 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1388 BAMBOO_DEBUGPRINT(0xe883);
1397 // conflicts on lockresults
1399 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1401 BAMBOO_EXIT(0xa00a);
1407 // receive lock release msg
1408 processlockrelease(msgdata[1], msgdata[2], 0, false);
1414 case PROFILEOUTPUT: {
1415 // receive an output profile data request msg
1416 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1417 // startup core can not receive profile output finish msg
1418 BAMBOO_EXIT(0xa00c);
1422 BAMBOO_DEBUGPRINT(0xe885);
1426 totalexetime = msgdata[1];
1427 outputProfileData();
1429 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1431 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1436 case PROFILEFINISH: {
1437 // receive a profile output finish msg
1438 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1439 // non startup core can not receive profile output finish msg
1441 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1443 BAMBOO_EXIT(0xa00d);
1447 BAMBOO_DEBUGPRINT(0xe886);
1450 profilestatus[msgdata[1]] = 0;
1455 // GC version has no lock msgs
1456 #ifndef MULTICORE_GC
1457 case REDIRECTLOCK: {
1458 // receive a redirect lock request msg, handle it right now
1459 // check to see if there is a lock exist for the required obj
1460 int data1 = msgdata[1]; // lock type
1461 int data2 = msgdata[2]; // obj pointer
1462 int data3 = msgdata[3]; // redirect lock
1463 int data4 = msgdata[4]; // root request core
1464 int data5 = msgdata[5]; // request core
1465 deny = processlockrequest(msgdata[1], data3, data2, data5, data4, true);
1467 // this lock request is redirected
1470 // send response msg
1471 // for 32 bit machine, the size is always 4 words
1473 cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1474 data1, data2, data3);
1476 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1477 data1, data2, data3);
1483 case REDIRECTGROUNT: {
1484 // receive a lock grant msg with redirect info
1485 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1487 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1489 BAMBOO_EXIT(0xa00e);
1491 if(lockobj == msgdata[2]) {
1494 BAMBOO_DEBUGPRINT(0xe891);
1499 RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1504 // conflicts on lockresults
1506 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1508 BAMBOO_EXIT(0xa00f);
1513 case REDIRECTDENY: {
1514 // receive a lock deny msg with redirect info
1515 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1517 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1519 BAMBOO_EXIT(0xa010);
1521 if(lockobj == msgdata[2]) {
1524 BAMBOO_DEBUGPRINT(0xe892);
1533 // conflicts on lockresults
1535 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1537 BAMBOO_EXIT(0xa011);
1542 case REDIRECTRELEASE: {
1543 // receive a lock release msg with redirect info
1544 processlockrelease(msgdata[1], msgdata[2], msgdata[3], true);
1549 case STATUSCONFIRM: {
1550 // receive a status confirm info
1551 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1552 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
1553 // wrong core to receive such msg
1554 BAMBOO_EXIT(0xa013);
1556 // send response msg
1559 BAMBOO_DEBUGPRINT(0xe887);
1563 cache_msg_5(STARTUPCORE, STATUSREPORT,
1564 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1565 self_numsendobjs, self_numreceiveobjs);
1567 send_msg_5(STARTUPCORE, STATUSREPORT,
1568 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1569 self_numsendobjs, self_numreceiveobjs);
1575 case STATUSREPORT: {
1576 // receive a status confirm info
1577 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1578 // wrong core to receive such msg
1580 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1582 BAMBOO_EXIT(0xa014);
1586 BAMBOO_DEBUGPRINT(0xe888);
1592 corestatus[msgdata[2]] = msgdata[1];
1593 numsendobjs[msgdata[1]] = msgdata[2];
1594 numreceiveobjs[msgdata[1]] = msgdata[3];
1600 // receive a terminate msg
1603 BAMBOO_DEBUGPRINT(0xe889);
1612 // receive a shared memory request msg
1613 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1614 // wrong core to receive such msg
1616 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1618 BAMBOO_EXIT(0xa015);
1622 BAMBOO_DEBUGPRINT(0xe88a);
1627 // is currently doing gc, dump this msg
1632 void * mem = smemalloc(msgdata[1], &allocsize);
1636 // send the start_va to request core
1638 cache_msg_3(msgdata[2], MEMRESPONSE, mem, allocsize);
1640 send_msg_3( msgdata[2], MEMRESPONSE, mem, allocsize);
1647 // receive a shared memory response msg
1650 BAMBOO_DEBUGPRINT(0xe88b);
1655 // is currently doing gc, dump this msg
1659 if(msgdata[2] == 0) {
1660 bamboo_smem_size = 0;
1663 // fill header to store the size of this mem block
1664 (*((int*)msgdata[1])) = msgdata[2];
1665 bamboo_smem_size = msgdata[2] - BAMBOO_CACHE_LINE_SIZE;
1667 bamboo_cur_msp = msgdata[1] + BAMBOO_CACHE_LINE_SIZE;
1670 create_mspace_with_base((void*)(msgdata[1]+BAMBOO_CACHE_LINE_SIZE),
1671 msgdata[2]-BAMBOO_CACHE_LINE_SIZE,
1682 // receive a start GC msg
1685 BAMBOO_DEBUGPRINT(0xe88c);
1690 gcphase = MARKPHASE;
1692 // is waiting for response of mem request
1693 // let it return NULL and start gc
1694 bamboo_smem_size = 0;
1695 bamboo_cur_msp = NULL;
1701 case GCSTARTCOMPACT: {
1702 // a compact phase start msg
1703 gcstopblock = msgdata[1];
1704 gcphase = COMPACTPHASE;
1708 case GCSTARTFLUSH: {
1709 // received a flush phase start msg
1710 gcphase = FLUSHPHASE;
1714 case GCFINISHMARK: {
1715 // received a mark phase finish msg
1716 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1717 // non startup core can not receive this msg
1719 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1721 BAMBOO_EXIT(0xb006);
1723 if(msgdata[1] < NUMCORES) {
1724 gccorestatus[msgdata[1]] = 0;
1725 gcnumsendobjs[msgdata[1]] = gcmsgdata[2];
1726 gcnumreceiveobjs[msgdata[1]] = gcmsgdata[3];
1731 case GCFINISHCOMPACT: {
1732 // received a compact phase finish msg
1733 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1734 // non startup core can not receive this msg
1737 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1739 BAMBOO_EXIT(0xb006);
1741 if(msgdata[1] < NUMCORES) {
1742 gcnumblocks[msgdata[1]] = msgdata[2];
1743 if(msgdata[3] == 0) {
1747 if(findSpareMem(&startaddr, &tomove, msgdata[2])) {
1748 send_msg_4(msgdata[1], GCMOVESTART, k, startaddr, tomove);
1750 // TODO if not success
1753 gccorestatus[msgdata[1]] = 0;
1754 gcloads[msgdata[1]] = msgdata[4];
1760 case GCFINISHFLUSH: {
1761 // received a flush phase finish msg
1762 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1763 // non startup core can not receive this msg
1766 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1768 BAMBOO_EXIT(0xb006);
1770 if(msgdata[1] < NUMCORES) {
1771 gccorestatus[msgdata[1]] = 0;
1777 // received a GC finish msg
1778 gcphase = FINISHPHASE;
1782 case GCMARKCONFIRM: {
1783 // received a marked phase finish confirm request msg
1784 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1785 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
1786 // wrong core to receive such msg
1787 BAMBOO_EXIT(0xa013);
1789 // send response msg
1791 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
1792 gcbusystatus, gcself_numsendobjs,
1793 gcself_numreceiveobjs);
1795 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
1796 gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
1802 case GCMARKREPORT: {
1803 // received a marked phase finish confirm response msg
1804 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1805 // wrong core to receive such msg
1807 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1809 BAMBOO_EXIT(0xb014);
1814 gccorestatus[msgdata[1]] = gcmsgdata[2];
1815 gcnumsendobjs[msgdata[1]] = gcmsgdata[3];
1816 gcnumreceiveobjs[msgdata[1]] = gcmsgdata[4];
1822 // received a markedObj msg
1823 gc_enqueue(msgdata[1]);
1824 gcself_numreceiveobjs++;
1825 gcbusystatus = true;
1830 // received a start moving objs msg
1832 gcmovestartaddr = msgdata[2];
1833 gcstopblock = msgdata[3];
1837 case GCMAPREQUEST: {
1838 // received a mapping info request msg
1839 void * dstptr = NULL;
1840 RuntimeHashget(gcpointertbl, msgdata[1], &dstptr);
1841 if(NULL == dstptr) {
1842 // no such pointer in this core, something is wrong
1843 BAMBOO_EXIT(0xb008);
1845 // send back the mapping info
1847 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
1849 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
1856 // received a mapping info response msg
1857 if(msgdata[1] != gcobj2map) {
1858 // obj not matched, something is wrong
1859 BAMBOO_EXIT(0xb009);
1861 gcmappedobj = msgdata[2];
1862 RuntimeHashadd(gcpointertbl, gcobj2map, gcmappedobj);
1868 case GCLOBJREQUEST: {
1869 // received a large objs info request msg
1870 transferMarkResults();
1875 // received a large objs info response msg
1878 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1880 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1882 BAMBOO_EXIT(0xa005);
1884 // store the mark result info
1885 int cnum = msgdata[2];
1886 gcloads[cnum] = msgdata[3];
1887 if(gcheaptop < msgdata[4]) {
1888 gcheaptop = msgdata[4];
1890 // large obj info here
1891 for(int k = 5; k < msgdata[1];) {
1892 gc_lobjenqueue(msgdata[k++], msgdata[k++], cnum, NULL);
1893 } // for(int k = 5; k < msgdata[1];)
1897 case GCLOBJMAPPING: {
1898 // received a large obj mapping info msg
1899 RuntimeHashadd(gcpointertbl, msgdata[1], msgdata[2]);
1908 for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
1909 msgdata[msgdataindex] = -1;
1915 BAMBOO_DEBUGPRINT(0xe88d);
1919 if(BAMBOO_MSG_AVAIL() != 0) {
1932 BAMBOO_DEBUGPRINT(0xe88e);
1936 /* if(isInterrupt) {
1944 int enqueuetasks(struct parameterwrapper *parameter,
1945 struct parameterwrapper *prevptr,
1946 struct ___Object___ *ptr,
1948 int numenterflags) {
1949 void * taskpointerarray[MAXTASKPARAMS];
1951 //int numparams=parameter->task->numParameters;
1952 int numiterators=parameter->task->numTotal-1;
1955 struct taskdescriptor * task=parameter->task;
1957 //this add the object to parameterwrapper
1958 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
1959 numenterflags, enterflags==NULL);
1961 /* Add enqueued object to parameter vector */
1962 taskpointerarray[parameter->slot]=ptr;
1964 /* Reset iterators */
1965 for(j=0; j<numiterators; j++) {
1966 toiReset(¶meter->iterators[j]);
1969 /* Find initial state */
1970 for(j=0; j<numiterators; j++) {
1972 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
1973 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
1975 /* Need to backtrack */
1976 toiReset(¶meter->iterators[j]);
1980 /* Nothing to enqueue */
1986 /* Enqueue current state */
1988 struct taskparamdescriptor *tpd=
1989 RUNMALLOC(sizeof(struct taskparamdescriptor));
1991 tpd->numParameters=numiterators+1;
1992 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
1994 for(j=0; j<=numiterators; j++) {
1995 //store the actual parameters
1996 tpd->parameterArray[j]=taskpointerarray[j];
1999 if ((/*!gencontains(failedtasks, tpd)&&*/
2000 !gencontains(activetasks,tpd))) {
2001 genputtable(activetasks, tpd, tpd);
2003 RUNFREE(tpd->parameterArray);
2007 /* This loop iterates to the next parameter combination */
2008 if (numiterators==0)
2011 for(j=numiterators-1; j<numiterators; j++) {
2013 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2014 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2016 /* Need to backtrack */
2017 toiReset(¶meter->iterators[j]);
2021 /* Nothing more to enqueue */
2029 int enqueuetasks_I(struct parameterwrapper *parameter,
2030 struct parameterwrapper *prevptr,
2031 struct ___Object___ *ptr,
2033 int numenterflags) {
2034 void * taskpointerarray[MAXTASKPARAMS];
2036 //int numparams=parameter->task->numParameters;
2037 int numiterators=parameter->task->numTotal-1;
2042 struct taskdescriptor * task=parameter->task;
2044 //this add the object to parameterwrapper
2045 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2046 numenterflags, enterflags==NULL);
2048 /* Add enqueued object to parameter vector */
2049 taskpointerarray[parameter->slot]=ptr;
2051 /* Reset iterators */
2052 for(j=0; j<numiterators; j++) {
2053 toiReset(¶meter->iterators[j]);
2056 /* Find initial state */
2057 for(j=0; j<numiterators; j++) {
2059 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2060 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2062 /* Need to backtrack */
2063 toiReset(¶meter->iterators[j]);
2067 /* Nothing to enqueue */
2073 /* Enqueue current state */
2075 struct taskparamdescriptor *tpd=
2076 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2078 tpd->numParameters=numiterators+1;
2079 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2081 for(j=0; j<=numiterators; j++) {
2082 //store the actual parameters
2083 tpd->parameterArray[j]=taskpointerarray[j];
2086 if ((/*!gencontains(failedtasks, tpd)&&*/
2087 !gencontains(activetasks,tpd))) {
2088 genputtable_I(activetasks, tpd, tpd);
2090 RUNFREE(tpd->parameterArray);
2094 /* This loop iterates to the next parameter combination */
2095 if (numiterators==0)
2098 for(j=numiterators-1; j<numiterators; j++) {
2100 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2101 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2103 /* Need to backtrack */
2104 toiReset(¶meter->iterators[j]);
2108 /* Nothing more to enqueue */
2122 int containstag(struct ___Object___ *ptr,
2123 struct ___TagDescriptor___ *tag);
2125 void executetasks() {
2126 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2129 struct ___Object___ * tmpparam = NULL;
2130 struct parameterdescriptor * pd=NULL;
2131 struct parameterwrapper *pw=NULL;
2136 struct LockValue locks[MAXTASKPARAMS];
2144 while(hashsize(activetasks)>0) {
2149 BAMBOO_DEBUGPRINT(0xe990);
2152 /* See if there are any active tasks */
2153 if (hashsize(activetasks)>0) {
2156 #ifdef ACCURATEPROFILE
2157 profileTaskStart("tpd checking");
2161 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2162 genfreekey(activetasks, currtpd);
2164 numparams=currtpd->task->numParameters;
2165 numtotal=currtpd->task->numTotal;
2167 // clear the lockRedirectTbl
2168 // (TODO, this table should be empty after all locks are released)
2170 for(j = 0; j < MAXTASKPARAMS; j++) {
2171 locks[j].redirectlock = 0;
2174 // get all required locks
2176 // check which locks are needed
2177 for(i = 0; i < numparams; i++) {
2178 void * param = currtpd->parameterArray[i];
2182 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2184 taskpointerarray[i+OFFSET]=param;
2187 if(((struct ___Object___ *)param)->lock == NULL) {
2188 tmplock = (int)param;
2190 tmplock = (int)(((struct ___Object___ *)param)->lock);
2192 // insert into the locks array
2193 for(j = 0; j < locklen; j++) {
2194 if(locks[j].value == tmplock) {
2197 } else if(locks[j].value > tmplock) {
2204 locks[h].redirectlock = locks[h-1].redirectlock;
2205 locks[h].value = locks[h-1].value;
2207 locks[j].value = tmplock;
2208 locks[j].redirectlock = (int)param;
2211 } // line 2713: for(i = 0; i < numparams; i++)
2212 // grab these required locks
2214 BAMBOO_DEBUGPRINT(0xe991);
2216 for(i = 0; i < locklen; i++) {
2217 int * lock = (int *)(locks[i].redirectlock);
2219 // require locks for this parameter if it is not a startup object
2221 BAMBOO_DEBUGPRINT_REG((int)lock);
2222 BAMBOO_DEBUGPRINT_REG((int)(locks[i].value));
2225 BAMBOO_START_CRITICAL_SECTION();
2227 BAMBOO_DEBUGPRINT(0xf001);
2230 //isInterrupt = false;
2233 BAMBOO_WAITING_FOR_LOCK();
2237 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2241 grount = lockresult;
2251 //isInterrupt = true;
2253 BAMBOO_CLOSE_CRITICAL_SECTION();
2255 BAMBOO_DEBUGPRINT(0xf000);
2261 BAMBOO_DEBUGPRINT(0xe992);
2263 // can not get the lock, try later
2264 // releas all grabbed locks for previous parameters
2265 for(j = 0; j < i; ++j) {
2266 lock = (int*)(locks[j].redirectlock);
2267 releasewritelock(lock);
2269 genputtable(activetasks, currtpd, currtpd);
2270 if(hashsize(activetasks) == 1) {
2271 // only one task right now, wait a little while before next try
2277 #ifdef ACCURATEPROFILE
2278 // fail, set the end of the checkTaskInfo
2283 } // line 2794: if(grount == 0)
2284 } // line 2752: for(i = 0; i < locklen; i++)
2287 BAMBOO_DEBUGPRINT(0xe993);
2289 /* Make sure that the parameters are still in the queues */
2290 for(i=0; i<numparams; i++) {
2291 void * parameter=currtpd->parameterArray[i];
2295 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
2296 classsize[((struct ___Object___ *)parameter)->type]);
2298 tmpparam = (struct ___Object___ *)parameter;
2299 pd=currtpd->task->descriptorarray[i];
2300 pw=(struct parameterwrapper *) pd->queue;
2301 /* Check that object is still in queue */
2303 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2305 BAMBOO_DEBUGPRINT(0xe994);
2307 // release grabbed locks
2308 for(j = 0; j < locklen; ++j) {
2309 int * lock = (int *)(locks[j].redirectlock);
2310 releasewritelock(lock);
2312 RUNFREE(currtpd->parameterArray);
2317 /* Check if the object's flags still meets requirements */
2321 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2322 andmask=pw->intarray[tmpi*2];
2323 checkmask=pw->intarray[tmpi*2+1];
2324 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2330 // flags are never suitable
2331 // remove this obj from the queue
2333 int UNUSED, UNUSED2;
2336 BAMBOO_DEBUGPRINT(0xe995);
2338 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
2339 (int *) &enterflags, &UNUSED, &UNUSED2);
2340 ObjectHashremove(pw->objectset, (int)parameter);
2341 if (enterflags!=NULL)
2342 RUNFREE(enterflags);
2343 // release grabbed locks
2344 for(j = 0; j < locklen; ++j) {
2345 int * lock = (int *)(locks[j].redirectlock);
2346 releasewritelock(lock);
2348 RUNFREE(currtpd->parameterArray);
2351 #ifdef ACCURATEPROFILE
2352 // fail, set the end of the checkTaskInfo
2357 } // line 2878: if (!ismet)
2361 /* Check that object still has necessary tags */
2362 for(j=0; j<pd->numbertags; j++) {
2363 int slotid=pd->tagarray[2*j]+numparams;
2364 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2365 if (!containstag(parameter, tagd)) {
2367 BAMBOO_DEBUGPRINT(0xe996);
2370 // release grabbed locks
2372 for(tmpj = 0; tmpj < locklen; ++tmpj) {
2373 int * lock = (int *)(locks[tmpj].redirectlock);
2374 releasewritelock(lock);
2377 RUNFREE(currtpd->parameterArray);
2380 } // line2911: if (!containstag(parameter, tagd))
2381 } // line 2808: for(j=0; j<pd->numbertags; j++)
2383 taskpointerarray[i+OFFSET]=parameter;
2384 } // line 2824: for(i=0; i<numparams; i++)
2386 for(; i<numtotal; i++) {
2387 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2391 /* Actually call task */
2393 ((int *)taskpointerarray)[0]=currtpd->numParameters;
2394 taskpointerarray[1]=NULL;
2398 #ifdef ACCURATEPROFILE
2399 // check finish, set the end of the checkTaskInfo
2402 profileTaskStart(currtpd->task->name);
2406 BAMBOO_DEBUGPRINT(0xe997);
2408 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2410 #ifdef ACCURATEPROFILE
2411 // task finish, set the end of the checkTaskInfo
2413 // new a PostTaskInfo for the post-task execution
2414 profileTaskStart("post task execution");
2418 BAMBOO_DEBUGPRINT(0xe998);
2419 BAMBOO_DEBUGPRINT_REG(islock);
2424 BAMBOO_DEBUGPRINT(0xe999);
2426 for(i = 0; i < locklen; ++i) {
2427 void * ptr = (void *)(locks[i].redirectlock);
2428 int * lock = (int *)(locks[i].value);
2430 BAMBOO_DEBUGPRINT_REG((int)ptr);
2431 BAMBOO_DEBUGPRINT_REG((int)lock);
2433 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2435 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2436 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2437 releasewritelock_r(lock, (int *)redirectlock);
2439 releasewritelock(ptr);
2442 } // line 3015: if(islock)
2445 // post task execution finish, set the end of the postTaskInfo
2449 // Free up task parameter descriptor
2450 RUNFREE(currtpd->parameterArray);
2453 BAMBOO_DEBUGPRINT(0xe99a);
2456 } // if (hashsize(activetasks)>0)
2457 } // while(hashsize(activetasks)>0)
2459 BAMBOO_DEBUGPRINT(0xe99b);
2463 /* This function processes an objects tags */
2464 void processtags(struct parameterdescriptor *pd,
2466 struct parameterwrapper *parameter,
2467 int * iteratorcount,
2472 for(i=0; i<pd->numbertags; i++) {
2473 int slotid=pd->tagarray[2*i];
2474 int tagid=pd->tagarray[2*i+1];
2476 if (statusarray[slotid+numparams]==0) {
2477 parameter->iterators[*iteratorcount].istag=1;
2478 parameter->iterators[*iteratorcount].tagid=tagid;
2479 parameter->iterators[*iteratorcount].slot=slotid+numparams;
2480 parameter->iterators[*iteratorcount].tagobjectslot=index;
2481 statusarray[slotid+numparams]=1;
2488 void processobject(struct parameterwrapper *parameter,
2490 struct parameterdescriptor *pd,
2496 struct ObjectHash * objectset=
2497 ((struct parameterwrapper *)pd->queue)->objectset;
2499 parameter->iterators[*iteratorcount].istag=0;
2500 parameter->iterators[*iteratorcount].slot=index;
2501 parameter->iterators[*iteratorcount].objectset=objectset;
2502 statusarray[index]=1;
2504 for(i=0; i<pd->numbertags; i++) {
2505 int slotid=pd->tagarray[2*i];
2506 //int tagid=pd->tagarray[2*i+1];
2507 if (statusarray[slotid+numparams]!=0) {
2508 /* This tag has already been enqueued, use it to narrow search */
2509 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
2514 parameter->iterators[*iteratorcount].numtags=tagcount;
2519 /* This function builds the iterators for a task & parameter */
2521 void builditerators(struct taskdescriptor * task,
2523 struct parameterwrapper * parameter) {
2524 int statusarray[MAXTASKPARAMS];
2526 int numparams=task->numParameters;
2527 int iteratorcount=0;
2528 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
2530 statusarray[index]=1; /* Initial parameter */
2531 /* Process tags for initial iterator */
2533 processtags(task->descriptorarray[index], index, parameter,
2534 &iteratorcount, statusarray, numparams);
2538 /* Check for objects with existing tags */
2539 for(i=0; i<numparams; i++) {
2540 if (statusarray[i]==0) {
2541 struct parameterdescriptor *pd=task->descriptorarray[i];
2543 for(j=0; j<pd->numbertags; j++) {
2544 int slotid=pd->tagarray[2*j];
2545 if(statusarray[slotid+numparams]!=0) {
2546 processobject(parameter, i, pd, &iteratorcount, statusarray,
2548 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2555 /* Next do objects w/ unbound tags*/
2557 for(i=0; i<numparams; i++) {
2558 if (statusarray[i]==0) {
2559 struct parameterdescriptor *pd=task->descriptorarray[i];
2560 if (pd->numbertags>0) {
2561 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2562 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2568 /* Nothing with a tag enqueued */
2570 for(i=0; i<numparams; i++) {
2571 if (statusarray[i]==0) {
2572 struct parameterdescriptor *pd=task->descriptorarray[i];
2573 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2574 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2587 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2590 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2591 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2593 printf("%s\n", task->name);
2595 for(j=0; j<task->numParameters; j++) {
2596 struct parameterdescriptor *param=task->descriptorarray[j];
2597 struct parameterwrapper *parameter=param->queue;
2598 struct ObjectHash * set=parameter->objectset;
2599 struct ObjectIterator objit;
2601 printf(" Parameter %d\n", j);
2603 ObjectHashiterator(set, &objit);
2604 while(ObjhasNext(&objit)) {
2605 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
2606 struct ___Object___ * tagptr=obj->___tags___;
2607 int nonfailed=Objdata4(&objit);
2608 int numflags=Objdata3(&objit);
2609 int flags=Objdata2(&objit);
2612 printf(" Contains %lx\n", obj);
2613 printf(" flag=%d\n", obj->flag);
2616 } else if (tagptr->type==TAGTYPE) {
2618 printf(" tag=%lx\n",tagptr);
2624 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
2625 for(; tagindex<ao->___cachedCode___; tagindex++) {
2627 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
2640 /* This function processes the task information to create queues for
2641 each parameter type. */
2643 void processtasks() {
2645 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2648 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2649 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2652 /* Build objectsets */
2653 for(j=0; j<task->numParameters; j++) {
2654 struct parameterdescriptor *param=task->descriptorarray[j];
2655 struct parameterwrapper *parameter=param->queue;
2656 parameter->objectset=allocateObjectHash(10);
2657 parameter->task=task;
2660 /* Build iterators for parameters */
2661 for(j=0; j<task->numParameters; j++) {
2662 struct parameterdescriptor *param=task->descriptorarray[j];
2663 struct parameterwrapper *parameter=param->queue;
2664 builditerators(task, j, parameter);
2669 void toiReset(struct tagobjectiterator * it) {
2672 } else if (it->numtags>0) {
2675 ObjectHashiterator(it->objectset, &it->it);
2679 int toiHasNext(struct tagobjectiterator *it,
2680 void ** objectarray OPTARG(int * failed)) {
2683 /* Get object with tags */
2684 struct ___Object___ *obj=objectarray[it->tagobjectslot];
2685 struct ___Object___ *tagptr=obj->___tags___;
2686 if (tagptr->type==TAGTYPE) {
2687 if ((it->tagobjindex==0)&& /* First object */
2688 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
2693 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
2694 int tagindex=it->tagobjindex;
2695 for(; tagindex<ao->___cachedCode___; tagindex++) {
2696 struct ___TagDescriptor___ *td=
2697 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
2698 if (td->flag==it->tagid) {
2699 it->tagobjindex=tagindex; /* Found right type of tag */
2705 } else if (it->numtags>0) {
2706 /* Use tags to locate appropriate objects */
2707 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
2708 struct ___Object___ *objptr=tag->flagptr;
2710 if (objptr->type!=OBJECTARRAYTYPE) {
2711 if (it->tagobjindex>0)
2713 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
2715 for(i=1; i<it->numtags; i++) {
2716 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
2717 if (!containstag(objptr,tag2))
2722 struct ArrayObject *ao=(struct ArrayObject *) objptr;
2725 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
2726 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
2727 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
2729 for(i=1; i<it->numtags; i++) {
2730 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
2731 if (!containstag(objptr,tag2))
2734 it->tagobjindex=tagindex;
2739 it->tagobjindex=tagindex;
2743 return ObjhasNext(&it->it);
2747 int containstag(struct ___Object___ *ptr,
2748 struct ___TagDescriptor___ *tag) {
2750 struct ___Object___ * objptr=tag->flagptr;
2751 if (objptr->type==OBJECTARRAYTYPE) {
2752 struct ArrayObject *ao=(struct ArrayObject *)objptr;
2753 for(j=0; j<ao->___cachedCode___; j++) {
2754 if (ptr==ARRAYGET(ao, struct ___Object___*, j))
2762 void toiNext(struct tagobjectiterator *it,
2763 void ** objectarray OPTARG(int * failed)) {
2764 /* hasNext has all of the intelligence */
2767 /* Get object with tags */
2768 struct ___Object___ *obj=objectarray[it->tagobjectslot];
2769 struct ___Object___ *tagptr=obj->___tags___;
2770 if (tagptr->type==TAGTYPE) {
2772 objectarray[it->slot]=tagptr;
2774 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
2775 objectarray[it->slot]=
2776 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
2778 } else if (it->numtags>0) {
2779 /* Use tags to locate appropriate objects */
2780 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
2781 struct ___Object___ *objptr=tag->flagptr;
2782 if (objptr->type!=OBJECTARRAYTYPE) {
2784 objectarray[it->slot]=objptr;
2786 struct ArrayObject *ao=(struct ArrayObject *) objptr;
2787 objectarray[it->slot]=
2788 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
2791 /* Iterate object */
2792 objectarray[it->slot]=(void *)Objkey(&it->it);