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;
10 struct LockValue runtime_locks[MAXTASKPARAMS];
13 // specific functions used inside critical sections
14 void enqueueObject_I(void * ptr,
15 struct parameterwrapper ** queues,
17 int enqueuetasks_I(struct parameterwrapper *parameter,
18 struct parameterwrapper *prevptr,
19 struct ___Object___ *ptr,
24 inline __attribute__((always_inline))
25 void setupsmemmode(void) {
27 bamboo_smem_mode = SMEMLOCAL;
29 bamboo_smem_mode = SMEMFIXED;
31 bamboo_smem_mode = SMEMMIXED;
33 bamboo_smem_mode = SMEMGLOBAL;
35 // defaultly using local mode
36 bamboo_smem_mode = SMEMLOCAL;
38 } // void setupsmemmode(void)
41 inline __attribute__((always_inline))
42 void initruntimedata() {
44 // initialize the arrays
45 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
46 // startup core to initialize corestatus[]
47 for(i = 0; i < NUMCORES; ++i) {
50 numreceiveobjs[i] = 0;
52 // initialize the profile data arrays
58 gcnumreceiveobjs[i] = 0;
60 gcrequiredmems[i] = 0;
62 gcfilledblocks[i] = 0;
64 } // for(i = 0; i < NUMCORES; ++i)
74 self_numreceiveobjs = 0;
76 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
80 msglength = BAMBOO_MSG_BUF_LENGTH;
81 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
91 bamboo_cur_msp = NULL;
93 totransobjqueue = createQueue();
98 gcphase = FINISHPHASE;
100 gcself_numsendobjs = 0;
101 gcself_numreceiveobjs = 0;
102 gcmarkedptrbound = 0;
103 gcpointertbl = allocateRuntimeHash(20);
115 gcsbstarttbl = BAMBOO_BASE_VA;
116 gcsmemtbl = RUNMALLOC_I(sizeof(int)*gcnumblock);
118 // create the lock table, lockresult table and obj queue
121 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
122 /* Set allocation blocks*/
123 locktable.listhead=NULL;
124 locktable.listtail=NULL;
126 locktable.numelements = 0;
131 lockRedirectTbl = allocateRuntimeHash(20);
132 objRedirectLockTbl = allocateRuntimeHash(20);
137 objqueue.head = NULL;
138 objqueue.tail = NULL;
144 //isInterrupt = true;
147 taskInfoOverflow = false;
148 /*interruptInfoIndex = 0;
149 interruptInfoOverflow = false;*/
152 for(i = 0; i < MAXTASKPARAMS; i++) {
153 runtime_locks[i].redirectlock = 0;
154 runtime_locks[i].value = 0;
159 inline __attribute__((always_inline))
160 void disruntimedata() {
162 freeRuntimeHash(gcpointertbl);
164 freeRuntimeHash(lockRedirectTbl);
165 freeRuntimeHash(objRedirectLockTbl);
166 RUNFREE(locktable.bucket);
168 genfreehashtable(activetasks);
169 if(currtpd != NULL) {
170 RUNFREE(currtpd->parameterArray);
176 inline __attribute__((always_inline))
177 bool checkObjQueue() {
179 struct transObjInfo * objInfo = NULL;
183 #ifdef ACCURATEPROFILE
184 bool isChecking = false;
185 if(!isEmpty(&objqueue)) {
186 profileTaskStart("objqueue checking");
188 } // if(!isEmpty(&objqueue))
192 while(!isEmpty(&objqueue)) {
194 BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE();
196 BAMBOO_DEBUGPRINT(0xf001);
199 //isInterrupt = false;
202 BAMBOO_DEBUGPRINT(0xeee1);
205 objInfo = (struct transObjInfo *)getItem(&objqueue);
206 obj = objInfo->objptr;
208 BAMBOO_DEBUGPRINT_REG((int)obj);
210 // grab lock and flush the obj
214 BAMBOO_WAITING_FOR_LOCK();
215 } // while(!lockflag)
218 BAMBOO_DEBUGPRINT_REG(grount);
233 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
234 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
235 classsize[((struct ___Object___ *)obj)->type]);
237 // enqueue the object
238 for(k = 0; k < objInfo->length; ++k) {
239 int taskindex = objInfo->queues[2 * k];
240 int paramindex = objInfo->queues[2 * k + 1];
241 struct parameterwrapper ** queues =
242 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
244 BAMBOO_DEBUGPRINT_REG(taskindex);
245 BAMBOO_DEBUGPRINT_REG(paramindex);
246 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
247 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
248 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
249 (long)obj, tmpptr->flag);
251 enqueueObject_I(obj, queues, 1);
253 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
255 } // for(k = 0; k < objInfo->length; ++k)
256 releasewritelock_I(obj);
257 RUNFREE(objInfo->queues);
261 // put it at the end of the queue if no update version in the queue
262 struct QueueItem * qitem = getHead(&objqueue);
263 struct QueueItem * prev = NULL;
264 while(qitem != NULL) {
265 struct transObjInfo * tmpinfo =
266 (struct transObjInfo *)(qitem->objectptr);
267 if(tmpinfo->objptr == obj) {
268 // the same object in the queue, which should be enqueued
269 // recently. Current one is outdate, do not re-enqueue it
270 RUNFREE(objInfo->queues);
275 } // if(tmpinfo->objptr == obj)
276 qitem = getNextQueueItem(prev);
277 } // while(qitem != NULL)
278 // try to execute active tasks already enqueued first
279 addNewItem_I(&objqueue, objInfo);
281 //isInterrupt = true;
284 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
286 BAMBOO_DEBUGPRINT(0xf000);
290 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
292 BAMBOO_DEBUGPRINT(0xf000);
294 } // while(!isEmpty(&objqueue))
297 #ifdef ACCURATEPROFILE
305 BAMBOO_DEBUGPRINT(0xee02);
310 inline __attribute__((always_inline))
311 void checkCoreStatus() {
312 bool allStall = false;
316 (waitconfirm && (numconfirm == 0))) {
318 BAMBOO_DEBUGPRINT(0xee04);
319 BAMBOO_DEBUGPRINT_REG(waitconfirm);
321 BAMBOO_START_CRITICAL_SECTION_STATUS();
323 BAMBOO_DEBUGPRINT(0xf001);
325 corestatus[BAMBOO_NUM_OF_CORE] = 0;
326 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
327 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
328 // check the status of all cores
331 BAMBOO_DEBUGPRINT_REG(NUMCORES);
333 for(i = 0; i < NUMCORES; ++i) {
335 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
337 if(corestatus[i] != 0) {
341 } // for(i = 0; i < NUMCORES; ++i)
343 // check if the sum of send objs and receive obj are the same
344 // yes->check if the info is the latest; no->go on executing
346 for(i = 0; i < NUMCORES; ++i) {
347 sumsendobj += numsendobjs[i];
349 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
351 } // for(i = 0; i < NUMCORES; ++i)
352 for(i = 0; i < NUMCORES; ++i) {
353 sumsendobj -= numreceiveobjs[i];
355 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
357 } // for(i = 0; i < NUMCORES; ++i)
358 if(0 == sumsendobj) {
360 // the first time found all cores stall
361 // send out status confirm msg to all other cores
362 // reset the corestatus array too
364 BAMBOO_DEBUGPRINT(0xee05);
366 corestatus[BAMBOO_NUM_OF_CORE] = 1;
367 for(i = 1; i < NUMCORES; ++i) {
369 // send status confirm msg to core i
370 send_msg_1(i, STATUSCONFIRM);
371 } // for(i = 1; i < NUMCORES; ++i)
373 numconfirm = NUMCORES - 1;
375 // all the core status info are the latest
376 // terminate; for profiling mode, send request to all
377 // other cores to pour out profiling data
379 BAMBOO_DEBUGPRINT(0xee06);
383 totalexetime = BAMBOO_GET_EXE_TIME();
385 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
386 BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
387 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
389 // profile mode, send msgs to other cores to request pouring
390 // out progiling data
392 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
394 BAMBOO_DEBUGPRINT(0xf000);
396 for(i = 1; i < NUMCORES; ++i) {
397 // send profile request msg to core i
398 send_msg_2(i, PROFILEOUTPUT, totalexetime);
399 } // for(i = 1; i < NUMCORES; ++i)
400 // pour profiling data on startup core
403 BAMBOO_START_CRITICAL_SECTION_STATUS();
405 BAMBOO_DEBUGPRINT(0xf001);
407 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
408 // check the status of all cores
411 BAMBOO_DEBUGPRINT_REG(NUMCORES);
413 for(i = 0; i < NUMCORES; ++i) {
415 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
417 if(profilestatus[i] != 0) {
421 } // for(i = 0; i < NUMCORES; ++i)
424 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
426 BAMBOO_DEBUGPRINT(0xf000);
436 terminate(); // All done.
437 } // if(!waitconfirm)
439 // still some objects on the fly on the network
440 // reset the waitconfirm and numconfirm
442 BAMBOO_DEBUGPRINT(0xee07);
446 } // if(0 == sumsendobj)
448 // not all cores are stall, keep on waiting
450 BAMBOO_DEBUGPRINT(0xee08);
455 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
457 BAMBOO_DEBUGPRINT(0xf000);
459 } // if((!waitconfirm) ||
462 // main function for each core
463 inline void run(void * arg) {
467 bool sendStall = false;
469 bool tocontinue = false;
471 corenum = BAMBOO_GET_NUM_OF_CORE();
473 BAMBOO_DEBUGPRINT(0xeeee);
474 BAMBOO_DEBUGPRINT_REG(corenum);
475 BAMBOO_DEBUGPRINT(STARTUPCORE);
478 // initialize runtime data structures
481 // other architecture related initialization
485 initializeexithandler();
487 // main process of the execution module
488 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
489 // non-executing cores, only processing communications
492 BAMBOO_DEBUGPRINT(0xee01);
493 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
494 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
495 profileTaskStart("msg handling");
499 //isInterrupt = false;
503 /* Create queue of active tasks */
505 genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
506 (int(*) (void *,void *)) &comparetpd);
508 /* Process task information */
511 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
512 /* Create startup object */
513 createstartupobject(argc, argv);
517 BAMBOO_DEBUGPRINT(0xee00);
522 // check if need to do GC
526 // check if there are new active tasks can be executed
533 while(receiveObject() != -1) {
538 BAMBOO_DEBUGPRINT(0xee01);
541 // check if there are some pending objects,
542 // if yes, enqueue them and executetasks again
543 tocontinue = checkObjQueue();
547 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
550 BAMBOO_DEBUGPRINT(0xee03);
558 BAMBOO_DEBUGPRINT(0xee09);
564 // wait for some time
567 BAMBOO_DEBUGPRINT(0xee0a);
573 // send StallMsg to startup core
575 BAMBOO_DEBUGPRINT(0xee0b);
578 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
579 self_numsendobjs, self_numreceiveobjs);
591 BAMBOO_DEBUGPRINT(0xee0c);
594 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
597 } // if(BAMBOO_NUM_OF_CORE > NUMCORES - 1)
601 struct ___createstartupobject____I_locals {
604 struct ___StartupObject___ * ___startupobject___;
605 struct ArrayObject * ___stringarray___;
606 }; // struct ___createstartupobject____I_locals
608 void createstartupobject(int argc,
612 /* Allocate startup object */
614 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
615 struct ___StartupObject___ *startupobject=
616 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
617 ___locals___.___startupobject___ = startupobject;
618 struct ArrayObject * stringarray=
619 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
620 ___locals___.___stringarray___ = stringarray;
622 struct ___StartupObject___ *startupobject=
623 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
624 struct ArrayObject * stringarray=
625 allocate_newarray(STRINGARRAYTYPE, argc-1);
627 /* Build array of strings */
628 startupobject->___parameters___=stringarray;
629 for(i=1; i<argc; i++) {
630 int length=strlen(argv[i]);
632 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
634 struct ___String___ *newstring=NewString(argv[i],length);
636 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
640 startupobject->version = 0;
641 startupobject->lock = NULL;
643 /* Set initialized flag for startup object */
644 flagorandinit(startupobject,1,0xFFFFFFFF);
645 enqueueObject(startupobject, NULL, 0);
647 BAMBOO_CACHE_FLUSH_ALL();
651 int hashCodetpd(struct taskparamdescriptor *ftd) {
652 int hash=(int)ftd->task;
654 for(i=0; i<ftd->numParameters; i++) {
655 hash^=(int)ftd->parameterArray[i];
660 int comparetpd(struct taskparamdescriptor *ftd1,
661 struct taskparamdescriptor *ftd2) {
663 if (ftd1->task!=ftd2->task)
665 for(i=0; i<ftd1->numParameters; i++)
666 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
671 /* This function sets a tag. */
673 void tagset(void *ptr,
674 struct ___Object___ * obj,
675 struct ___TagDescriptor___ * tagd) {
677 void tagset(struct ___Object___ * obj,
678 struct ___TagDescriptor___ * tagd) {
680 struct ArrayObject * ao=NULL;
681 struct ___Object___ * tagptr=obj->___tags___;
683 obj->___tags___=(struct ___Object___ *)tagd;
685 /* Have to check if it is already set */
686 if (tagptr->type==TAGTYPE) {
687 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
692 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
693 struct ArrayObject * ao=
694 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
695 obj=(struct ___Object___ *)ptrarray[2];
696 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
697 td=(struct ___TagDescriptor___ *) obj->___tags___;
699 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
702 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
703 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
704 obj->___tags___=(struct ___Object___ *) ao;
705 ao->___cachedCode___=2;
709 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
710 for(i=0; i<ao->___cachedCode___; i++) {
711 struct ___TagDescriptor___ * td=
712 ARRAYGET(ao, struct ___TagDescriptor___*, i);
717 if (ao->___cachedCode___<ao->___length___) {
718 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
719 ao->___cachedCode___++;
722 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
723 struct ArrayObject * aonew=
724 allocate_newarray(&ptrarray,TAGARRAYTYPE,
725 TAGARRAYINTERVAL+ao->___length___);
726 obj=(struct ___Object___ *)ptrarray[2];
727 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
728 ao=(struct ArrayObject *)obj->___tags___;
730 struct ArrayObject * aonew=
731 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
734 aonew->___cachedCode___=ao->___length___+1;
735 for(i=0; i<ao->___length___; i++) {
736 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
737 ARRAYGET(ao, struct ___TagDescriptor___*, i));
739 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
745 struct ___Object___ * tagset=tagd->flagptr;
748 } else if (tagset->type!=OBJECTARRAYTYPE) {
750 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
751 struct ArrayObject * ao=
752 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
753 obj=(struct ___Object___ *)ptrarray[2];
754 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
756 struct ArrayObject * ao=
757 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
759 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
760 ARRAYSET(ao, struct ___Object___ *, 1, obj);
761 ao->___cachedCode___=2;
762 tagd->flagptr=(struct ___Object___ *)ao;
764 struct ArrayObject *ao=(struct ArrayObject *) tagset;
765 if (ao->___cachedCode___<ao->___length___) {
766 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
770 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
771 struct ArrayObject * aonew=
772 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
773 OBJECTARRAYINTERVAL+ao->___length___);
774 obj=(struct ___Object___ *)ptrarray[2];
775 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
776 ao=(struct ArrayObject *)tagd->flagptr;
778 struct ArrayObject * aonew=
779 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
781 aonew->___cachedCode___=ao->___cachedCode___+1;
782 for(i=0; i<ao->___length___; i++) {
783 ARRAYSET(aonew, struct ___Object___*, i,
784 ARRAYGET(ao, struct ___Object___*, i));
786 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
787 tagd->flagptr=(struct ___Object___ *) aonew;
793 /* This function clears a tag. */
795 void tagclear(void *ptr,
796 struct ___Object___ * obj,
797 struct ___TagDescriptor___ * tagd) {
799 void tagclear(struct ___Object___ * obj,
800 struct ___TagDescriptor___ * tagd) {
802 /* We'll assume that tag is alway there.
803 Need to statically check for this of course. */
804 struct ___Object___ * tagptr=obj->___tags___;
806 if (tagptr->type==TAGTYPE) {
807 if ((struct ___TagDescriptor___ *)tagptr==tagd)
808 obj->___tags___=NULL;
810 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
812 for(i=0; i<ao->___cachedCode___; i++) {
813 struct ___TagDescriptor___ * td=
814 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
816 ao->___cachedCode___--;
817 if (i<ao->___cachedCode___)
818 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
819 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
820 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
821 if (ao->___cachedCode___==0)
822 obj->___tags___=NULL;
829 struct ___Object___ *tagset=tagd->flagptr;
830 if (tagset->type!=OBJECTARRAYTYPE) {
834 struct ArrayObject *ao=(struct ArrayObject *) tagset;
836 for(i=0; i<ao->___cachedCode___; i++) {
837 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
839 ao->___cachedCode___--;
840 if (i<ao->___cachedCode___)
841 ARRAYSET(ao, struct ___Object___ *, i,
842 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
843 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
844 if (ao->___cachedCode___==0)
855 /* This function allocates a new tag. */
857 struct ___TagDescriptor___ * allocate_tag(void *ptr,
859 struct ___TagDescriptor___ * v=
860 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
863 struct ___TagDescriptor___ * allocate_tag(int index) {
864 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
873 /* This function updates the flag for object ptr. It or's the flag
874 with the or mask and and's it with the andmask. */
876 void flagbody(struct ___Object___ *ptr,
878 struct parameterwrapper ** queues,
882 int flagcomp(const int *val1, const int *val2) {
883 return (*val1)-(*val2);
886 void flagorand(void * ptr,
889 struct parameterwrapper ** queues,
892 int oldflag=((int *)ptr)[1];
893 int flag=ormask|oldflag;
895 flagbody(ptr, flag, queues, length, false);
899 bool intflagorand(void * ptr,
903 int oldflag=((int *)ptr)[1];
904 int flag=ormask|oldflag;
906 if (flag==oldflag) /* Don't do anything */
909 flagbody(ptr, flag, NULL, 0, false);
915 void flagorandinit(void * ptr,
918 int oldflag=((int *)ptr)[1];
919 int flag=ormask|oldflag;
921 flagbody(ptr,flag,NULL,0,true);
924 void flagbody(struct ___Object___ *ptr,
926 struct parameterwrapper ** vqueues,
929 struct parameterwrapper * flagptr = NULL;
931 struct parameterwrapper ** queues = vqueues;
932 int length = vlength;
935 int * enterflags = NULL;
936 if((!isnew) && (queues == NULL)) {
937 if(BAMBOO_NUM_OF_CORE < NUMCORES) {
938 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
939 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
946 /*Remove object from all queues */
947 for(i = 0; i < length; ++i) {
949 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
950 (int *) &enterflags, &UNUSED, &UNUSED2);
951 ObjectHashremove(flagptr->objectset, (int)ptr);
952 if (enterflags!=NULL)
957 void enqueueObject(void * vptr,
958 struct parameterwrapper ** vqueues,
960 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
963 //struct QueueItem *tmpptr;
964 struct parameterwrapper * parameter=NULL;
967 struct parameterwrapper * prevptr=NULL;
968 struct ___Object___ *tagptr=NULL;
969 struct parameterwrapper ** queues = vqueues;
970 int length = vlength;
971 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
975 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
976 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
978 tagptr=ptr->___tags___;
980 /* Outer loop iterates through all parameter queues an object of
981 this type could be in. */
982 for(j = 0; j < length; ++j) {
983 parameter = queues[j];
985 if (parameter->numbertags>0) {
987 goto nextloop; //that means the object has no tag
988 //but that param needs tag
989 else if(tagptr->type==TAGTYPE) { //one tag
990 //struct ___TagDescriptor___ * tag=
991 //(struct ___TagDescriptor___*) tagptr;
992 for(i=0; i<parameter->numbertags; i++) {
993 //slotid is parameter->tagarray[2*i];
994 int tagid=parameter->tagarray[2*i+1];
995 if (tagid!=tagptr->flag)
996 goto nextloop; /*We don't have this tag */
998 } else { //multiple tags
999 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1000 for(i=0; i<parameter->numbertags; i++) {
1001 //slotid is parameter->tagarray[2*i];
1002 int tagid=parameter->tagarray[2*i+1];
1004 for(j=0; j<ao->___cachedCode___; j++) {
1005 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1016 for(i=0; i<parameter->numberofterms; i++) {
1017 int andmask=parameter->intarray[i*2];
1018 int checkmask=parameter->intarray[i*2+1];
1019 if ((ptr->flag&andmask)==checkmask) {
1020 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1031 void enqueueObject_I(void * vptr,
1032 struct parameterwrapper ** vqueues,
1034 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1037 //struct QueueItem *tmpptr;
1038 struct parameterwrapper * parameter=NULL;
1041 struct parameterwrapper * prevptr=NULL;
1042 struct ___Object___ *tagptr=NULL;
1043 struct parameterwrapper ** queues = vqueues;
1044 int length = vlength;
1045 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1048 if(queues == NULL) {
1049 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1050 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1052 tagptr=ptr->___tags___;
1054 /* Outer loop iterates through all parameter queues an object of
1055 this type could be in. */
1056 for(j = 0; j < length; ++j) {
1057 parameter = queues[j];
1059 if (parameter->numbertags>0) {
1061 goto nextloop; //that means the object has no tag
1062 //but that param needs tag
1063 else if(tagptr->type==TAGTYPE) { //one tag
1064 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1065 for(i=0; i<parameter->numbertags; i++) {
1066 //slotid is parameter->tagarray[2*i];
1067 int tagid=parameter->tagarray[2*i+1];
1068 if (tagid!=tagptr->flag)
1069 goto nextloop; /*We don't have this tag */
1071 } else { //multiple tags
1072 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1073 for(i=0; i<parameter->numbertags; i++) {
1074 //slotid is parameter->tagarray[2*i];
1075 int tagid=parameter->tagarray[2*i+1];
1077 for(j=0; j<ao->___cachedCode___; j++) {
1078 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1089 for(i=0; i<parameter->numberofterms; i++) {
1090 int andmask=parameter->intarray[i*2];
1091 int checkmask=parameter->intarray[i*2+1];
1092 if ((ptr->flag&andmask)==checkmask) {
1093 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1105 int * getAliasLock(void ** ptrs,
1107 struct RuntimeHash * tbl) {
1109 return (int*)(RUNMALLOC(sizeof(int)));
1114 bool redirect = false;
1115 int redirectlock = 0;
1116 for(; i < length; i++) {
1117 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1120 if(ptr->lock == NULL) {
1123 lock = (int)(ptr->lock);
1126 if(lock != redirectlock) {
1127 RuntimeHashadd(tbl, lock, redirectlock);
1130 if(RuntimeHashcontainskey(tbl, lock)) {
1131 // already redirected
1133 RuntimeHashget(tbl, lock, &redirectlock);
1134 for(; j < locklen; j++) {
1135 if(locks[j] != redirectlock) {
1136 RuntimeHashadd(tbl, locks[j], redirectlock);
1141 for(j = 0; j < locklen; j++) {
1142 if(locks[j] == lock) {
1145 } else if(locks[j] > lock) {
1152 locks[h] = locks[h-1];
1161 return (int *)redirectlock;
1163 return (int *)(locks[0]);
1168 void addAliasLock(void * ptr,
1170 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1171 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1172 // originally no alias lock associated or have a different alias lock
1173 // flush it as the new one
1174 obj->lock = (int *)lock;
1179 inline void setTaskExitIndex(int index) {
1180 taskInfoArray[taskInfoIndex]->exitIndex = index;
1183 inline void addNewObjInfo(void * nobj) {
1184 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1185 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1187 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1192 struct freeMemItem * findFreeMemChunk_I(int coren,
1195 struct freeMemItem * freemem = bamboo_free_mem_list->head;
1196 struct freeMemItem * prev = NULL;
1199 *tofindb = gc_core2block[2*coren+i]+(NUMCORES*2)*j;
1200 // check available shared mem chunks
1203 switch(bamboo_smem_mode) {
1205 int startb = freemem->startblock;
1206 int endb = freemem->endblock;
1207 while(startb > *tofindb) {
1213 *tofindb = gc_core2block[2*coren+i]+(NUMCORES*2)*j;
1214 } // while(startb > tofindb)
1215 if(startb <= *tofindb) {
1216 if((endb >= *tofindb) && (freemem->size >= isize)) {
1218 } else if(*tofindb > gcnumblock-1) {
1219 // no more local mem
1221 } // if(endb >= tofindb)
1222 } // if(startb <= tofindb)
1227 int startb = freemem->startblock;
1228 int endb = freemem->endblock;
1229 if(startb <= *tofindb) {
1230 if((endb >= *tofindb) && (freemem->size >= isize)) {
1234 // use the global mem
1235 if(((startb > NUMCORES-1) && (freemem->size >= isize)) ||
1236 ((endb > NUMCORES-1) && ((freemem->size-
1237 (gcbaseva+BAMBOO_LARGE_SMEM_BOUND-freemem->ptr))>=isize))) {
1245 // TODO not supported yet
1246 BAMBOO_EXIT(0xe001);
1251 foundsmem = (freemem->size >= isize);
1258 if(1 == foundsmem) {
1261 } else if (2 == foundsmem) {
1262 // terminate, no more mem
1266 if(freemem->size == 0) {
1267 // an empty item, remove it
1268 struct freeMemItem * toremove = freemem;
1269 freemem = freemem->next;
1272 bamboo_free_mem_list->head = freemem;
1274 prev->next = freemem;
1276 // put it to the tail of the list for reuse
1277 toremove->next = bamboo_free_mem_list->backuplist;
1278 bamboo_free_mem_list->backuplist = toremove;
1281 freemem = freemem->next;
1283 } while(freemem != NULL);
1286 } // struct freeMemItem * findFreeMemChunk_I(int, int, int *)
1288 void * localmalloc_I(int tofindb,
1290 struct freeMemItem * freemem,
1293 int startb = freemem->startblock;
1294 int endb = freemem->endblock;
1295 int tmpptr = gcbaseva+((tofindb<NUMCORES)?tofindb*BAMBOO_SMEM_SIZE_L
1296 :BAMBOO_LARGE_SMEM_BOUND+(tofindb-NUMCORES)*BAMBOO_SMEM_SIZE);
1297 if((freemem->size+freemem->ptr-tmpptr)>=isize) {
1298 mem = (tmpptr>freemem->ptr)?((void *)tmpptr):(freemem->ptr);
1300 mem = (void *)(freemem->size+freemem->ptr-isize);
1302 // check the remaining space in this block
1303 int remain = (int)(mem-gcbaseva);
1304 int bound = (BAMBOO_SMEM_SIZE);
1305 if(remain < BAMBOO_LARGE_SMEM_BOUND) {
1306 bound = (BAMBOO_SMEM_SIZE_L);
1308 remain = bound - remain%bound;
1309 if(remain < isize) {
1310 // this object acrosses blocks
1313 // round the asigned block to the end of the current block
1314 *allocsize = remain;
1316 if(freemem->ptr == (int)mem) {
1317 freemem->ptr = ((void*)freemem->ptr) + (*allocsize);
1318 freemem->size -= *allocsize;
1319 BLOCKINDEX(freemem->ptr, &(freemem->startblock));
1320 } else if((freemem->ptr+freemem->size) == ((int)mem+(*allocsize))) {
1321 freemem->size -= *allocsize;
1322 BLOCKINDEX(((int)mem)-1, &(freemem->endblock));
1324 struct freeMemItem * tmp =
1325 (struct freeMemItem *)RUNMALLOC_I(sizeof(struct freeMemItem));
1326 tmp->ptr = (int)mem+*allocsize;
1327 tmp->size = freemem->ptr+freemem->size-(int)mem-*allocsize;
1328 BLOCKINDEX(tmp->ptr, &(tmp->startblock));
1329 tmp->endblock = freemem->endblock;
1330 tmp->next = freemem->next;
1331 freemem->next = tmp;
1332 freemem->size = (int)mem - freemem->ptr;
1333 BLOCKINDEX(((int)mem-1), &(freemem->endblock));
1336 } // void * localmalloc_I(int, int, struct freeMemItem *, int *)
1338 void * globalmalloc_I(int isize,
1339 struct freeMemItem * freemem,
1341 void * mem = (void *)(freemem->ptr);
1342 // check the remaining space in this block
1343 int remain = (int)(mem-(BAMBOO_BASE_VA));
1344 int bound = (BAMBOO_SMEM_SIZE);
1345 if(remain < BAMBOO_LARGE_SMEM_BOUND) {
1346 bound = (BAMBOO_SMEM_SIZE_L);
1348 remain = bound - remain%bound;
1349 if(remain < isize) {
1350 // this object acrosses blocks
1353 // round the asigned block to the end of the current block
1354 *allocsize = remain;
1356 freemem->ptr = ((void*)freemem->ptr) + (*allocsize);
1357 freemem->size -= *allocsize;
1359 } // void * globalmalloc_I(int, struct freeMemItem *, int *)
1362 // malloc from the shared memory
1363 void * smemalloc_I(int coren,
1368 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1369 int toallocate = (isize>(BAMBOO_SMEM_SIZE)) ? (isize):(BAMBOO_SMEM_SIZE);
1370 // go through free mem list for suitable chunks
1372 struct freeMemItem * freemem = findFreeMemChunk_I(coren, isize, &tofindb);
1374 // allocate shared mem if available
1375 if(freemem != NULL) {
1376 switch(bamboo_smem_mode) {
1378 mem = localmalloc_I(tofindb, isize, freemem, allocsize);
1383 int startb = freemem->startblock;
1384 int endb = freemem->endblock;
1385 if(startb > tofindb) {
1386 // malloc on global mem
1387 mem = globalmalloc_I(isize, freemem, allocsize);
1389 // malloc on local mem
1390 mem = localmalloc_I(tofindb, isize, freemem, allocsize);
1396 // TODO not supported yet
1397 BAMBOO_EXIT(0xe002);
1402 mem = globalmalloc_I(isize,freemem, allocsize);
1411 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size):(BAMBOO_SMEM_SIZE);
1412 mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1413 *allocsize = toallocate;
1416 // no enough shared global memory
1422 BAMBOO_DEBUGPRINT(0xa001);
1423 BAMBOO_EXIT(0xa001);
1427 } // void * smemalloc_I(int, int, int)
1429 // receive object transferred from other cores
1430 // or the terminate message from other cores
1431 // Should be invoked in critical sections!!
1432 // NOTICE: following format is for threadsimulate version only
1433 // RAW version please see previous description
1434 // format: type + object
1435 // type: -1--stall msg
1437 // return value: 0--received an object
1438 // 1--received nothing
1439 // 2--received a Stall Msg
1440 // 3--received a lock Msg
1441 // RAW version: -1 -- received nothing
1442 // otherwise -- received msg type
1443 int receiveObject() {
1447 if(receiveMsg() == -1) {
1451 if(msgdataindex == msglength) {
1452 // received a whole msg
1457 // receive a object transfer msg
1458 struct transObjInfo * transObj =
1459 RUNMALLOC_I(sizeof(struct transObjInfo));
1463 BAMBOO_DEBUGPRINT(0xe880);
1466 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1468 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1470 BAMBOO_EXIT(0xa002);
1472 // store the object and its corresponding queue info, enqueue it later
1473 transObj->objptr = (void *)msgdata[2];
1474 transObj->length = (msglength - 3) / 2;
1475 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1476 for(k = 0; k < transObj->length; ++k) {
1477 transObj->queues[2*k] = msgdata[3+2*k];
1480 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1483 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1486 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1490 // check if there is an existing duplicate item
1492 struct QueueItem * qitem = getHead(&objqueue);
1493 struct QueueItem * prev = NULL;
1494 while(qitem != NULL) {
1495 struct transObjInfo * tmpinfo =
1496 (struct transObjInfo *)(qitem->objectptr);
1497 if(tmpinfo->objptr == transObj->objptr) {
1498 // the same object, remove outdate one
1499 removeItem(&objqueue, qitem);
1505 qitem = getHead(&objqueue);
1507 qitem = getNextQueueItem(prev);
1510 addNewItem_I(&objqueue, (void *)transObj);
1512 ++(self_numreceiveobjs);
1517 // receive a stall msg
1518 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1519 // non startup core can not receive stall msg
1521 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1523 BAMBOO_EXIT(0xa003);
1525 if(msgdata[1] < NUMCORES) {
1528 BAMBOO_DEBUGPRINT(0xe881);
1531 corestatus[msgdata[1]] = 0;
1532 numsendobjs[msgdata[1]] = msgdata[2];
1533 numreceiveobjs[msgdata[1]] = msgdata[3];
1538 // GC version have no lock msgs
1539 #ifndef MULTICORE_GC
1541 // receive lock request msg, handle it right now
1542 // check to see if there is a lock exist for the required obj
1543 // msgdata[1] -> lock type
1544 int data2 = msgdata[2]; // obj pointer
1545 int data3 = msgdata[3]; // lock
1546 int data4 = msgdata[4]; // request core
1547 // -1: redirected, 0: approved, 1: denied
1548 deny = processlockrequest(msgdata[1], data3, data2,
1549 data4, data4, true);
1551 // this lock request is redirected
1554 // send response msg
1555 // for 32 bit machine, the size is always 4 words
1556 int tmp = deny==1?LOCKDENY:LOCKGROUNT;
1558 cache_msg_4(data4, tmp, msgdata[1], data2, data3);
1560 send_msg_4(data4, tmp, msgdata[1], data2, data3);
1567 // receive lock grount msg
1568 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1570 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1572 BAMBOO_EXIT(0xa004);
1574 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1577 BAMBOO_DEBUGPRINT(0xe882);
1586 // conflicts on lockresults
1588 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1590 BAMBOO_EXIT(0xa005);
1596 // receive lock deny msg
1597 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1599 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1601 BAMBOO_EXIT(0xa006);
1603 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1606 BAMBOO_DEBUGPRINT(0xe883);
1615 // conflicts on lockresults
1617 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1619 BAMBOO_EXIT(0xa007);
1625 // receive lock release msg
1626 processlockrelease(msgdata[1], msgdata[2], 0, false);
1632 case PROFILEOUTPUT: {
1633 // receive an output profile data request msg
1634 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1635 // startup core can not receive profile output finish msg
1636 BAMBOO_EXIT(0xa008);
1640 BAMBOO_DEBUGPRINT(0xe885);
1644 totalexetime = msgdata[1];
1645 outputProfileData();
1647 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1649 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1654 case PROFILEFINISH: {
1655 // receive a profile output finish msg
1656 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1657 // non startup core can not receive profile output finish msg
1659 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1661 BAMBOO_EXIT(0xa009);
1665 BAMBOO_DEBUGPRINT(0xe886);
1668 profilestatus[msgdata[1]] = 0;
1673 // GC version has no lock msgs
1674 #ifndef MULTICORE_GC
1675 case REDIRECTLOCK: {
1676 // receive a redirect lock request msg, handle it right now
1677 // check to see if there is a lock exist for the required obj
1678 int data1 = msgdata[1]; // lock type
1679 int data2 = msgdata[2]; // obj pointer
1680 int data3 = msgdata[3]; // redirect lock
1681 int data4 = msgdata[4]; // root request core
1682 int data5 = msgdata[5]; // request core
1683 deny = processlockrequest(msgdata[1], data3, data2, data5, data4, true);
1685 // this lock request is redirected
1688 // send response msg
1689 // for 32 bit machine, the size is always 4 words
1691 cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1692 data1, data2, data3);
1694 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1695 data1, data2, data3);
1701 case REDIRECTGROUNT: {
1702 // receive a lock grant msg with redirect info
1703 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1705 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1707 BAMBOO_EXIT(0xa00a);
1709 if(lockobj == msgdata[2]) {
1712 BAMBOO_DEBUGPRINT(0xe891);
1717 RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1722 // conflicts on lockresults
1724 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1726 BAMBOO_EXIT(0xa00b);
1731 case REDIRECTDENY: {
1732 // receive a lock deny msg with redirect info
1733 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1735 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1737 BAMBOO_EXIT(0xa00c);
1739 if(lockobj == msgdata[2]) {
1742 BAMBOO_DEBUGPRINT(0xe892);
1751 // conflicts on lockresults
1753 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1755 BAMBOO_EXIT(0xa00d);
1760 case REDIRECTRELEASE: {
1761 // receive a lock release msg with redirect info
1762 processlockrelease(msgdata[1], msgdata[2], msgdata[3], true);
1767 case STATUSCONFIRM: {
1768 // receive a status confirm info
1769 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1770 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
1771 // wrong core to receive such msg
1772 BAMBOO_EXIT(0xa00e);
1774 // send response msg
1777 BAMBOO_DEBUGPRINT(0xe887);
1781 cache_msg_5(STARTUPCORE, STATUSREPORT,
1782 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1783 self_numsendobjs, self_numreceiveobjs);
1785 send_msg_5(STARTUPCORE, STATUSREPORT,
1786 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1787 self_numsendobjs, self_numreceiveobjs);
1793 case STATUSREPORT: {
1794 // receive a status confirm info
1795 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1796 // wrong core to receive such msg
1798 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1800 BAMBOO_EXIT(0xa00f);
1804 BAMBOO_DEBUGPRINT(0xe888);
1810 corestatus[msgdata[2]] = msgdata[1];
1811 numsendobjs[msgdata[2]] = msgdata[3];
1812 numreceiveobjs[msgdata[2]] = msgdata[4];
1818 // receive a terminate msg
1821 BAMBOO_DEBUGPRINT(0xe889);
1830 // receive a shared memory request msg
1831 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1832 // wrong core to receive such msg
1834 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1836 BAMBOO_EXIT(0xa010);
1840 BAMBOO_DEBUGPRINT(0xe88a);
1845 // is currently doing gc, dump this msg
1850 void * mem = smemalloc_I(msgdata[2], msgdata[1], &allocsize);
1854 // send the start_va to request core
1856 cache_msg_3(msgdata[2], MEMRESPONSE, mem, allocsize);
1858 send_msg_3( msgdata[2], MEMRESPONSE, mem, allocsize);
1865 // receive a shared memory response msg
1868 BAMBOO_DEBUGPRINT(0xe88b);
1873 // is currently doing gc, dump this msg
1877 if(msgdata[2] == 0) {
1878 bamboo_smem_size = 0;
1882 // fill header to store the size of this mem block
1883 (*((int*)msgdata[1])) = msgdata[2];
1884 bamboo_smem_size = msgdata[2] - BAMBOO_CACHE_LINE_SIZE;
1885 bamboo_cur_msp = msgdata[1] + BAMBOO_CACHE_LINE_SIZE;
1887 bamboo_smem_size = msgdata[2];
1888 bamboo_cur_msp =(void*)(msgdata[1]);
1899 gcphase = INITPHASE;
1901 // is waiting for response of mem request
1902 // let it return NULL and start gc
1903 bamboo_smem_size = 0;
1904 bamboo_cur_msp = NULL;
1911 // receive a start GC msg
1914 BAMBOO_DEBUGPRINT(0xe88c);
1918 gcphase = MARKPHASE;
1922 case GCSTARTCOMPACT: {
1923 // a compact phase start msg
1924 gcblock2fill = msgdata[1];
1925 gcphase = COMPACTPHASE;
1929 case GCSTARTFLUSH: {
1930 // received a flush phase start msg
1931 gcphase = FLUSHPHASE;
1935 case GCFINISHINIT: {
1936 // received a init phase finish msg
1937 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1938 // non startup core can not receive this msg
1940 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1942 BAMBOO_EXIT(0xb001);
1945 BAMBOO_DEBUGPRINT(0xe88c);
1946 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1948 if(msgdata[1] < NUMCORES) {
1949 gccorestatus[msgdata[1]] = 0;
1953 case GCFINISHMARK: {
1954 // received a mark phase finish msg
1955 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1956 // non startup core can not receive this msg
1958 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1960 BAMBOO_EXIT(0xb002);
1962 if(msgdata[1] < NUMCORES) {
1963 gccorestatus[msgdata[1]] = 0;
1964 gcnumsendobjs[msgdata[1]] = msgdata[2];
1965 gcnumreceiveobjs[msgdata[1]] = msgdata[3];
1970 case GCFINISHCOMPACT: {
1971 // received a compact phase finish msg
1972 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1973 // non startup core can not receive this msg
1976 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1978 BAMBOO_EXIT(0xb003);
1980 int cnum = msgdata[1];
1981 int filledblocks = msgdata[2];
1982 int heaptop = msgdata[3];
1983 int data4 = msgdata[4];
1984 if(cnum < NUMCORES) {
1985 if(COMPACTPHASE == gcphase) {
1986 gcfilledblocks[cnum] = filledblocks;
1987 gcloads[cnum] = heaptop;
1994 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
1996 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
1998 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2002 gccorestatus[cnum] = 0;
2003 // check if there is pending move request
2004 /*if(gcmovepending > 0) {
2006 for(j = 0; j < NUMCORES; j++) {
2007 if(gcrequiredmems[j]>0) {
2015 gcrequiredmems[j] = assignSpareMem_I(cnum,
2019 if(STARTUPCORE == j) {
2022 gcmovestartaddr = startaddr;
2023 gcblock2fill = tomove;
2026 cache_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
2028 send_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
2030 } // if(STARTUPCORE == j)
2031 if(gcrequiredmems[j] == 0) {
2034 } // if(j < NUMCORES)
2035 } // if(gcmovepending > 0) */
2037 } // if(cnum < NUMCORES)
2041 case GCFINISHFLUSH: {
2042 // received a flush phase finish msg
2043 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2044 // non startup core can not receive this msg
2047 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2049 BAMBOO_EXIT(0xb004);
2051 if(msgdata[1] < NUMCORES) {
2052 gccorestatus[msgdata[1]] = 0;
2058 // received a GC finish msg
2059 gcphase = FINISHPHASE;
2063 case GCMARKCONFIRM: {
2064 // received a marked phase finish confirm request msg
2065 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2066 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
2067 // wrong core to receive such msg
2068 BAMBOO_EXIT(0xb005);
2070 // send response msg
2072 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2073 gcbusystatus, gcself_numsendobjs,
2074 gcself_numreceiveobjs);
2076 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2077 gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
2083 case GCMARKREPORT: {
2084 // received a marked phase finish confirm response msg
2085 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2086 // wrong core to receive such msg
2088 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2090 BAMBOO_EXIT(0xb006);
2095 gccorestatus[msgdata[1]] = msgdata[2];
2096 gcnumsendobjs[msgdata[1]] = msgdata[3];
2097 gcnumreceiveobjs[msgdata[1]] = msgdata[4];
2103 // received a markedObj msg
2104 gc_enqueue_I(msgdata[1]);
2105 gcself_numreceiveobjs++;
2106 gcbusystatus = true;
2111 // received a start moving objs msg
2113 gcdstcore = msgdata[1];
2114 gcmovestartaddr = msgdata[2];
2115 gcblock2fill = msgdata[3];
2119 case GCMAPREQUEST: {
2120 // received a mapping info request msg
2121 void * dstptr = NULL;
2122 RuntimeHashget(gcpointertbl, msgdata[1], &dstptr);
2123 if(NULL == dstptr) {
2124 // no such pointer in this core, something is wrong
2126 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2127 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2129 BAMBOO_EXIT(0xb007);
2131 // send back the mapping info
2133 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
2135 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
2142 // received a mapping info response msg
2143 if(msgdata[1] != gcobj2map) {
2144 // obj not matched, something is wrong
2146 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2147 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2149 BAMBOO_EXIT(0xb008);
2151 gcmappedobj = msgdata[2];
2152 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2158 case GCLOBJREQUEST: {
2159 // received a large objs info request msg
2160 transferMarkResults_I();
2165 // received a large objs info response msg
2168 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2170 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2172 BAMBOO_EXIT(0xb009);
2174 // store the mark result info
2175 int cnum = msgdata[2];
2176 gcloads[cnum] = msgdata[3];
2177 if(gcheaptop < msgdata[4]) {
2178 gcheaptop = msgdata[4];
2180 // large obj info here
2181 for(int k = 5; k < msgdata[1];) {
2182 int lobj = msgdata[k++];
2183 int length = msgdata[k++];
2184 gc_lobjenqueue_I(lobj, length, cnum);
2186 } // for(int k = 5; k < msgdata[1];)
2190 case GCLOBJMAPPING: {
2191 // received a large obj mapping info msg
2192 RuntimeHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2201 for(; msgdataindex > 0; --msgdataindex) {
2202 msgdata[msgdataindex-1] = -1;
2204 msglength = BAMBOO_MSG_BUF_LENGTH;
2207 BAMBOO_DEBUGPRINT(0xe88d);
2211 if(BAMBOO_MSG_AVAIL() != 0) {
2224 BAMBOO_DEBUGPRINT(0xe88e);
2228 /* if(isInterrupt) {
2236 int enqueuetasks(struct parameterwrapper *parameter,
2237 struct parameterwrapper *prevptr,
2238 struct ___Object___ *ptr,
2240 int numenterflags) {
2241 void * taskpointerarray[MAXTASKPARAMS];
2243 //int numparams=parameter->task->numParameters;
2244 int numiterators=parameter->task->numTotal-1;
2247 struct taskdescriptor * task=parameter->task;
2249 //this add the object to parameterwrapper
2250 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
2251 numenterflags, enterflags==NULL);
2253 /* Add enqueued object to parameter vector */
2254 taskpointerarray[parameter->slot]=ptr;
2256 /* Reset iterators */
2257 for(j=0; j<numiterators; j++) {
2258 toiReset(¶meter->iterators[j]);
2261 /* Find initial state */
2262 for(j=0; j<numiterators; j++) {
2264 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2265 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2267 /* Need to backtrack */
2268 toiReset(¶meter->iterators[j]);
2272 /* Nothing to enqueue */
2278 /* Enqueue current state */
2280 struct taskparamdescriptor *tpd=
2281 RUNMALLOC(sizeof(struct taskparamdescriptor));
2283 tpd->numParameters=numiterators+1;
2284 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2286 for(j=0; j<=numiterators; j++) {
2287 //store the actual parameters
2288 tpd->parameterArray[j]=taskpointerarray[j];
2291 if ((/*!gencontains(failedtasks, tpd)&&*/
2292 !gencontains(activetasks,tpd))) {
2293 genputtable(activetasks, tpd, tpd);
2295 RUNFREE(tpd->parameterArray);
2299 /* This loop iterates to the next parameter combination */
2300 if (numiterators==0)
2303 for(j=numiterators-1; j<numiterators; j++) {
2305 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2306 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2308 /* Need to backtrack */
2309 toiReset(¶meter->iterators[j]);
2313 /* Nothing more to enqueue */
2321 int enqueuetasks_I(struct parameterwrapper *parameter,
2322 struct parameterwrapper *prevptr,
2323 struct ___Object___ *ptr,
2325 int numenterflags) {
2326 void * taskpointerarray[MAXTASKPARAMS];
2328 //int numparams=parameter->task->numParameters;
2329 int numiterators=parameter->task->numTotal-1;
2334 struct taskdescriptor * task=parameter->task;
2336 //this add the object to parameterwrapper
2337 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2338 numenterflags, enterflags==NULL);
2340 /* Add enqueued object to parameter vector */
2341 taskpointerarray[parameter->slot]=ptr;
2343 /* Reset iterators */
2344 for(j=0; j<numiterators; j++) {
2345 toiReset(¶meter->iterators[j]);
2348 /* Find initial state */
2349 for(j=0; j<numiterators; j++) {
2351 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2352 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2354 /* Need to backtrack */
2355 toiReset(¶meter->iterators[j]);
2359 /* Nothing to enqueue */
2365 /* Enqueue current state */
2367 struct taskparamdescriptor *tpd=
2368 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2370 tpd->numParameters=numiterators+1;
2371 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2373 for(j=0; j<=numiterators; j++) {
2374 //store the actual parameters
2375 tpd->parameterArray[j]=taskpointerarray[j];
2378 if ((/*!gencontains(failedtasks, tpd)&&*/
2379 !gencontains(activetasks,tpd))) {
2380 genputtable_I(activetasks, tpd, tpd);
2382 RUNFREE(tpd->parameterArray);
2386 /* This loop iterates to the next parameter combination */
2387 if (numiterators==0)
2390 for(j=numiterators-1; j<numiterators; j++) {
2392 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2393 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2395 /* Need to backtrack */
2396 toiReset(¶meter->iterators[j]);
2400 /* Nothing more to enqueue */
2414 int containstag(struct ___Object___ *ptr,
2415 struct ___TagDescriptor___ *tag);
2417 #ifndef MULTICORE_GC
2418 void releasewritelock_r(void * lock, void * redirectlock) {
2420 int reallock = (int)lock;
2421 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2424 BAMBOO_DEBUGPRINT(0xe671);
2425 BAMBOO_DEBUGPRINT_REG((int)lock);
2426 BAMBOO_DEBUGPRINT_REG(reallock);
2427 BAMBOO_DEBUGPRINT_REG(targetcore);
2430 if(targetcore == BAMBOO_NUM_OF_CORE) {
2431 BAMBOO_START_CRITICAL_SECTION_LOCK();
2433 BAMBOO_DEBUGPRINT(0xf001);
2435 // reside on this core
2436 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2437 // no locks for this object, something is wrong
2438 BAMBOO_EXIT(0xa011);
2441 struct LockValue * lockvalue = NULL;
2443 BAMBOO_DEBUGPRINT(0xe672);
2445 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2446 lockvalue = (struct LockValue *)rwlock_obj;
2448 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2451 lockvalue->redirectlock = (int)redirectlock;
2453 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2456 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2458 BAMBOO_DEBUGPRINT(0xf000);
2462 // send lock release with redirect info msg
2463 // for 32 bit machine, the size is always 4 words
2464 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
2469 void executetasks() {
2470 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2473 struct ___Object___ * tmpparam = NULL;
2474 struct parameterdescriptor * pd=NULL;
2475 struct parameterwrapper *pw=NULL;
2485 while(hashsize(activetasks)>0) {
2490 BAMBOO_DEBUGPRINT(0xe990);
2493 /* See if there are any active tasks */
2494 if (hashsize(activetasks)>0) {
2497 #ifdef ACCURATEPROFILE
2498 profileTaskStart("tpd checking");
2502 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2503 genfreekey(activetasks, currtpd);
2505 numparams=currtpd->task->numParameters;
2506 numtotal=currtpd->task->numTotal;
2508 // clear the lockRedirectTbl
2509 // (TODO, this table should be empty after all locks are released)
2511 for(j = 0; j < MAXTASKPARAMS; j++) {
2512 runtime_locks[j].redirectlock = 0;
2513 runtime_locks[j].value = 0;
2515 // get all required locks
2516 runtime_locklen = 0;
2517 // check which locks are needed
2518 for(i = 0; i < numparams; i++) {
2519 void * param = currtpd->parameterArray[i];
2523 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2525 taskpointerarray[i+OFFSET]=param;
2528 if(((struct ___Object___ *)param)->lock == NULL) {
2529 tmplock = (int)param;
2531 tmplock = (int)(((struct ___Object___ *)param)->lock);
2533 // insert into the locks array
2534 for(j = 0; j < runtime_locklen; j++) {
2535 if(runtime_locks[j].value == tmplock) {
2538 } else if(runtime_locks[j].value > tmplock) {
2543 int h = runtime_locklen;
2545 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
2546 runtime_locks[h].value = runtime_locks[h-1].value;
2548 runtime_locks[j].value = tmplock;
2549 runtime_locks[j].redirectlock = (int)param;
2552 } // line 2713: for(i = 0; i < numparams; i++)
2553 // grab these required locks
2555 BAMBOO_DEBUGPRINT(0xe991);
2557 for(i = 0; i < runtime_locklen; i++) {
2558 int * lock = (int *)(runtime_locks[i].redirectlock);
2560 // require locks for this parameter if it is not a startup object
2562 BAMBOO_DEBUGPRINT_REG((int)lock);
2563 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
2566 BAMBOO_START_CRITICAL_SECTION();
2568 BAMBOO_DEBUGPRINT(0xf001);
2571 //isInterrupt = false;
2574 BAMBOO_WAITING_FOR_LOCK();
2578 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2582 grount = lockresult;
2592 //isInterrupt = true;
2594 BAMBOO_CLOSE_CRITICAL_SECTION();
2596 BAMBOO_DEBUGPRINT(0xf000);
2602 BAMBOO_DEBUGPRINT(0xe992);
2603 BAMBOO_DEBUGPRINT_REG(lock);
2605 // can not get the lock, try later
2606 // releas all grabbed locks for previous parameters
2607 for(j = 0; j < i; ++j) {
2608 lock = (int*)(runtime_locks[j].redirectlock);
2609 releasewritelock(lock);
2611 genputtable(activetasks, currtpd, currtpd);
2612 if(hashsize(activetasks) == 1) {
2613 // only one task right now, wait a little while before next try
2619 #ifdef ACCURATEPROFILE
2620 // fail, set the end of the checkTaskInfo
2625 } // line 2794: if(grount == 0)
2626 } // line 2752: for(i = 0; i < runtime_locklen; i++)
2629 BAMBOO_DEBUGPRINT(0xe993);
2631 /* Make sure that the parameters are still in the queues */
2632 for(i=0; i<numparams; i++) {
2633 void * parameter=currtpd->parameterArray[i];
2637 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
2638 classsize[((struct ___Object___ *)parameter)->type]);
2640 tmpparam = (struct ___Object___ *)parameter;
2641 pd=currtpd->task->descriptorarray[i];
2642 pw=(struct parameterwrapper *) pd->queue;
2643 /* Check that object is still in queue */
2645 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2647 BAMBOO_DEBUGPRINT(0xe994);
2648 BAMBOO_DEBUGPRINT_REG(parameter);
2650 // release grabbed locks
2651 for(j = 0; j < runtime_locklen; ++j) {
2652 int * lock = (int *)(runtime_locks[j].redirectlock);
2653 releasewritelock(lock);
2655 RUNFREE(currtpd->parameterArray);
2661 /* Check if the object's flags still meets requirements */
2665 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2666 andmask=pw->intarray[tmpi*2];
2667 checkmask=pw->intarray[tmpi*2+1];
2668 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2674 // flags are never suitable
2675 // remove this obj from the queue
2677 int UNUSED, UNUSED2;
2680 BAMBOO_DEBUGPRINT(0xe995);
2681 BAMBOO_DEBUGPRINT_REG(parameter);
2683 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
2684 (int *) &enterflags, &UNUSED, &UNUSED2);
2685 ObjectHashremove(pw->objectset, (int)parameter);
2686 if (enterflags!=NULL)
2687 RUNFREE(enterflags);
2688 // release grabbed locks
2689 for(j = 0; j < runtime_locklen; ++j) {
2690 int * lock = (int *)(runtime_locks[j].redirectlock);
2691 releasewritelock(lock);
2693 RUNFREE(currtpd->parameterArray);
2697 #ifdef ACCURATEPROFILE
2698 // fail, set the end of the checkTaskInfo
2703 } // line 2878: if (!ismet)
2707 /* Check that object still has necessary tags */
2708 for(j=0; j<pd->numbertags; j++) {
2709 int slotid=pd->tagarray[2*j]+numparams;
2710 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2711 if (!containstag(parameter, tagd)) {
2713 BAMBOO_DEBUGPRINT(0xe996);
2716 // release grabbed locks
2718 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
2719 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
2720 releasewritelock(lock);
2723 RUNFREE(currtpd->parameterArray);
2727 } // line2911: if (!containstag(parameter, tagd))
2728 } // line 2808: for(j=0; j<pd->numbertags; j++)
2730 taskpointerarray[i+OFFSET]=parameter;
2731 } // line 2824: for(i=0; i<numparams; i++)
2733 for(; i<numtotal; i++) {
2734 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2739 /* Actually call task */
2741 ((int *)taskpointerarray)[0]=currtpd->numParameters;
2742 taskpointerarray[1]=NULL;
2745 #ifdef ACCURATEPROFILE
2746 // check finish, set the end of the checkTaskInfo
2749 profileTaskStart(currtpd->task->name);
2753 BAMBOO_DEBUGPRINT(0xe997);
2755 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2757 #ifdef ACCURATEPROFILE
2758 // task finish, set the end of the checkTaskInfo
2760 // new a PostTaskInfo for the post-task execution
2761 profileTaskStart("post task execution");
2765 BAMBOO_DEBUGPRINT(0xe998);
2766 BAMBOO_DEBUGPRINT_REG(islock);
2771 BAMBOO_DEBUGPRINT(0xe999);
2773 for(i = 0; i < runtime_locklen; ++i) {
2774 void * ptr = (void *)(runtime_locks[i].redirectlock);
2775 int * lock = (int *)(runtime_locks[i].value);
2777 BAMBOO_DEBUGPRINT_REG((int)ptr);
2778 BAMBOO_DEBUGPRINT_REG((int)lock);
2780 #ifndef MULTICORE_GC
2781 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2783 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2784 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2785 releasewritelock_r(lock, (int *)redirectlock);
2790 releasewritelock(ptr);
2793 } // line 3015: if(islock)
2796 // post task execution finish, set the end of the postTaskInfo
2800 // Free up task parameter descriptor
2801 RUNFREE(currtpd->parameterArray);
2805 BAMBOO_DEBUGPRINT(0xe99a);
2808 } // if (hashsize(activetasks)>0)
2809 } // while(hashsize(activetasks)>0)
2811 BAMBOO_DEBUGPRINT(0xe99b);
2815 /* This function processes an objects tags */
2816 void processtags(struct parameterdescriptor *pd,
2818 struct parameterwrapper *parameter,
2819 int * iteratorcount,
2824 for(i=0; i<pd->numbertags; i++) {
2825 int slotid=pd->tagarray[2*i];
2826 int tagid=pd->tagarray[2*i+1];
2828 if (statusarray[slotid+numparams]==0) {
2829 parameter->iterators[*iteratorcount].istag=1;
2830 parameter->iterators[*iteratorcount].tagid=tagid;
2831 parameter->iterators[*iteratorcount].slot=slotid+numparams;
2832 parameter->iterators[*iteratorcount].tagobjectslot=index;
2833 statusarray[slotid+numparams]=1;
2840 void processobject(struct parameterwrapper *parameter,
2842 struct parameterdescriptor *pd,
2848 struct ObjectHash * objectset=
2849 ((struct parameterwrapper *)pd->queue)->objectset;
2851 parameter->iterators[*iteratorcount].istag=0;
2852 parameter->iterators[*iteratorcount].slot=index;
2853 parameter->iterators[*iteratorcount].objectset=objectset;
2854 statusarray[index]=1;
2856 for(i=0; i<pd->numbertags; i++) {
2857 int slotid=pd->tagarray[2*i];
2858 //int tagid=pd->tagarray[2*i+1];
2859 if (statusarray[slotid+numparams]!=0) {
2860 /* This tag has already been enqueued, use it to narrow search */
2861 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
2866 parameter->iterators[*iteratorcount].numtags=tagcount;
2871 /* This function builds the iterators for a task & parameter */
2873 void builditerators(struct taskdescriptor * task,
2875 struct parameterwrapper * parameter) {
2876 int statusarray[MAXTASKPARAMS];
2878 int numparams=task->numParameters;
2879 int iteratorcount=0;
2880 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
2882 statusarray[index]=1; /* Initial parameter */
2883 /* Process tags for initial iterator */
2885 processtags(task->descriptorarray[index], index, parameter,
2886 &iteratorcount, statusarray, numparams);
2890 /* Check for objects with existing tags */
2891 for(i=0; i<numparams; i++) {
2892 if (statusarray[i]==0) {
2893 struct parameterdescriptor *pd=task->descriptorarray[i];
2895 for(j=0; j<pd->numbertags; j++) {
2896 int slotid=pd->tagarray[2*j];
2897 if(statusarray[slotid+numparams]!=0) {
2898 processobject(parameter, i, pd, &iteratorcount, statusarray,
2900 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2907 /* Next do objects w/ unbound tags*/
2909 for(i=0; i<numparams; i++) {
2910 if (statusarray[i]==0) {
2911 struct parameterdescriptor *pd=task->descriptorarray[i];
2912 if (pd->numbertags>0) {
2913 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2914 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2920 /* Nothing with a tag enqueued */
2922 for(i=0; i<numparams; i++) {
2923 if (statusarray[i]==0) {
2924 struct parameterdescriptor *pd=task->descriptorarray[i];
2925 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2926 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2939 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2942 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2943 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2945 printf("%s\n", task->name);
2947 for(j=0; j<task->numParameters; j++) {
2948 struct parameterdescriptor *param=task->descriptorarray[j];
2949 struct parameterwrapper *parameter=param->queue;
2950 struct ObjectHash * set=parameter->objectset;
2951 struct ObjectIterator objit;
2953 printf(" Parameter %d\n", j);
2955 ObjectHashiterator(set, &objit);
2956 while(ObjhasNext(&objit)) {
2957 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
2958 struct ___Object___ * tagptr=obj->___tags___;
2959 int nonfailed=Objdata4(&objit);
2960 int numflags=Objdata3(&objit);
2961 int flags=Objdata2(&objit);
2964 printf(" Contains %lx\n", obj);
2965 printf(" flag=%d\n", obj->flag);
2968 } else if (tagptr->type==TAGTYPE) {
2970 printf(" tag=%lx\n",tagptr);
2976 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
2977 for(; tagindex<ao->___cachedCode___; tagindex++) {
2979 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
2992 /* This function processes the task information to create queues for
2993 each parameter type. */
2995 void processtasks() {
2997 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
3000 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3001 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3004 /* Build objectsets */
3005 for(j=0; j<task->numParameters; j++) {
3006 struct parameterdescriptor *param=task->descriptorarray[j];
3007 struct parameterwrapper *parameter=param->queue;
3008 parameter->objectset=allocateObjectHash(10);
3009 parameter->task=task;
3012 /* Build iterators for parameters */
3013 for(j=0; j<task->numParameters; j++) {
3014 struct parameterdescriptor *param=task->descriptorarray[j];
3015 struct parameterwrapper *parameter=param->queue;
3016 builditerators(task, j, parameter);
3021 void toiReset(struct tagobjectiterator * it) {
3024 } else if (it->numtags>0) {
3027 ObjectHashiterator(it->objectset, &it->it);
3031 int toiHasNext(struct tagobjectiterator *it,
3032 void ** objectarray OPTARG(int * failed)) {
3035 /* Get object with tags */
3036 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3037 struct ___Object___ *tagptr=obj->___tags___;
3038 if (tagptr->type==TAGTYPE) {
3039 if ((it->tagobjindex==0)&& /* First object */
3040 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3045 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3046 int tagindex=it->tagobjindex;
3047 for(; tagindex<ao->___cachedCode___; tagindex++) {
3048 struct ___TagDescriptor___ *td=
3049 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3050 if (td->flag==it->tagid) {
3051 it->tagobjindex=tagindex; /* Found right type of tag */
3057 } else if (it->numtags>0) {
3058 /* Use tags to locate appropriate objects */
3059 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3060 struct ___Object___ *objptr=tag->flagptr;
3062 if (objptr->type!=OBJECTARRAYTYPE) {
3063 if (it->tagobjindex>0)
3065 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3067 for(i=1; i<it->numtags; i++) {
3068 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3069 if (!containstag(objptr,tag2))
3074 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3077 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
3078 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3079 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3081 for(i=1; i<it->numtags; i++) {
3082 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3083 if (!containstag(objptr,tag2))
3086 it->tagobjindex=tagindex;
3091 it->tagobjindex=tagindex;
3095 return ObjhasNext(&it->it);
3099 int containstag(struct ___Object___ *ptr,
3100 struct ___TagDescriptor___ *tag) {
3102 struct ___Object___ * objptr=tag->flagptr;
3103 if (objptr->type==OBJECTARRAYTYPE) {
3104 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3105 for(j=0; j<ao->___cachedCode___; j++) {
3106 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3116 void toiNext(struct tagobjectiterator *it,
3117 void ** objectarray OPTARG(int * failed)) {
3118 /* hasNext has all of the intelligence */
3121 /* Get object with tags */
3122 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3123 struct ___Object___ *tagptr=obj->___tags___;
3124 if (tagptr->type==TAGTYPE) {
3126 objectarray[it->slot]=tagptr;
3128 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3129 objectarray[it->slot]=
3130 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3132 } else if (it->numtags>0) {
3133 /* Use tags to locate appropriate objects */
3134 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3135 struct ___Object___ *objptr=tag->flagptr;
3136 if (objptr->type!=OBJECTARRAYTYPE) {
3138 objectarray[it->slot]=objptr;
3140 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3141 objectarray[it->slot]=
3142 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3145 /* Iterate object */
3146 objectarray[it->slot]=(void *)Objkey(&it->it);