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) {
81 msglength = BAMBOO_MSG_BUF_LENGTH;
82 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
92 bamboo_cur_msp = NULL;
94 totransobjqueue = createQueue();
99 gcphase = FINISHPHASE;
101 gcself_numsendobjs = 0;
102 gcself_numreceiveobjs = 0;
103 gcmarkedptrbound = 0;
104 gcpointertbl = allocateRuntimeHash(20);
116 gcsbstarttbl = BAMBOO_BASE_VA;
117 gcsmemtbl = RUNMALLOC_I(sizeof(int)*gcnumblock);
119 // create the lock table, lockresult table and obj queue
122 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
123 /* Set allocation blocks*/
124 locktable.listhead=NULL;
125 locktable.listtail=NULL;
127 locktable.numelements = 0;
132 lockRedirectTbl = allocateRuntimeHash(20);
133 objRedirectLockTbl = allocateRuntimeHash(20);
138 objqueue.head = NULL;
139 objqueue.tail = NULL;
145 //isInterrupt = true;
148 taskInfoOverflow = false;
149 /*interruptInfoIndex = 0;
150 interruptInfoOverflow = false;*/
153 for(i = 0; i < MAXTASKPARAMS; i++) {
154 runtime_locks[i].redirectlock = 0;
155 runtime_locks[i].value = 0;
160 inline __attribute__((always_inline))
161 void disruntimedata() {
163 freeRuntimeHash(gcpointertbl);
165 freeRuntimeHash(lockRedirectTbl);
166 freeRuntimeHash(objRedirectLockTbl);
167 RUNFREE(locktable.bucket);
169 genfreehashtable(activetasks);
170 if(currtpd != NULL) {
171 RUNFREE(currtpd->parameterArray);
177 inline __attribute__((always_inline))
178 bool checkObjQueue() {
180 struct transObjInfo * objInfo = NULL;
184 #ifdef ACCURATEPROFILE
185 bool isChecking = false;
186 if(!isEmpty(&objqueue)) {
187 profileTaskStart("objqueue checking");
189 } // if(!isEmpty(&objqueue))
193 while(!isEmpty(&objqueue)) {
195 BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE();
197 BAMBOO_DEBUGPRINT(0xf001);
200 //isInterrupt = false;
203 BAMBOO_DEBUGPRINT(0xeee1);
206 objInfo = (struct transObjInfo *)getItem(&objqueue);
207 obj = objInfo->objptr;
209 BAMBOO_DEBUGPRINT_REG((int)obj);
211 // grab lock and flush the obj
215 BAMBOO_WAITING_FOR_LOCK();
216 } // while(!lockflag)
219 BAMBOO_DEBUGPRINT_REG(grount);
234 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
235 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
236 classsize[((struct ___Object___ *)obj)->type]);
238 // enqueue the object
239 for(k = 0; k < objInfo->length; ++k) {
240 int taskindex = objInfo->queues[2 * k];
241 int paramindex = objInfo->queues[2 * k + 1];
242 struct parameterwrapper ** queues =
243 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
245 BAMBOO_DEBUGPRINT_REG(taskindex);
246 BAMBOO_DEBUGPRINT_REG(paramindex);
247 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
248 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
249 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
250 (long)obj, tmpptr->flag);
252 enqueueObject_I(obj, queues, 1);
254 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
256 } // for(k = 0; k < objInfo->length; ++k)
257 releasewritelock_I(obj);
258 RUNFREE(objInfo->queues);
262 // put it at the end of the queue if no update version in the queue
263 struct QueueItem * qitem = getHead(&objqueue);
264 struct QueueItem * prev = NULL;
265 while(qitem != NULL) {
266 struct transObjInfo * tmpinfo =
267 (struct transObjInfo *)(qitem->objectptr);
268 if(tmpinfo->objptr == obj) {
269 // the same object in the queue, which should be enqueued
270 // recently. Current one is outdate, do not re-enqueue it
271 RUNFREE(objInfo->queues);
276 } // if(tmpinfo->objptr == obj)
277 qitem = getNextQueueItem(prev);
278 } // while(qitem != NULL)
279 // try to execute active tasks already enqueued first
280 addNewItem_I(&objqueue, objInfo);
282 //isInterrupt = true;
285 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
287 BAMBOO_DEBUGPRINT(0xf000);
291 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
293 BAMBOO_DEBUGPRINT(0xf000);
295 } // while(!isEmpty(&objqueue))
298 #ifdef ACCURATEPROFILE
306 BAMBOO_DEBUGPRINT(0xee02);
311 inline __attribute__((always_inline))
312 void checkCoreStatus() {
313 bool allStall = false;
317 (waitconfirm && (numconfirm == 0))) {
319 BAMBOO_DEBUGPRINT(0xee04);
320 BAMBOO_DEBUGPRINT_REG(waitconfirm);
322 BAMBOO_START_CRITICAL_SECTION_STATUS();
324 BAMBOO_DEBUGPRINT(0xf001);
326 corestatus[BAMBOO_NUM_OF_CORE] = 0;
327 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
328 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
329 // check the status of all cores
332 BAMBOO_DEBUGPRINT_REG(NUMCORES);
334 for(i = 0; i < NUMCORES; ++i) {
336 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
338 if(corestatus[i] != 0) {
342 } // for(i = 0; i < NUMCORES; ++i)
344 // check if the sum of send objs and receive obj are the same
345 // yes->check if the info is the latest; no->go on executing
347 for(i = 0; i < NUMCORES; ++i) {
348 sumsendobj += numsendobjs[i];
350 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
352 } // for(i = 0; i < NUMCORES; ++i)
353 for(i = 0; i < NUMCORES; ++i) {
354 sumsendobj -= numreceiveobjs[i];
356 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
358 } // for(i = 0; i < NUMCORES; ++i)
359 if(0 == sumsendobj) {
361 // the first time found all cores stall
362 // send out status confirm msg to all other cores
363 // reset the corestatus array too
365 BAMBOO_DEBUGPRINT(0xee05);
367 corestatus[BAMBOO_NUM_OF_CORE] = 1;
368 for(i = 1; i < NUMCORES; ++i) {
370 // send status confirm msg to core i
371 send_msg_1(i, STATUSCONFIRM);
372 } // for(i = 1; i < NUMCORES; ++i)
374 numconfirm = NUMCORES - 1;
376 // all the core status info are the latest
377 // terminate; for profiling mode, send request to all
378 // other cores to pour out profiling data
380 BAMBOO_DEBUGPRINT(0xee06);
384 totalexetime = BAMBOO_GET_EXE_TIME();
386 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
387 BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
388 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
390 // profile mode, send msgs to other cores to request pouring
391 // out progiling data
393 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
395 BAMBOO_DEBUGPRINT(0xf000);
397 for(i = 1; i < NUMCORES; ++i) {
398 // send profile request msg to core i
399 send_msg_2(i, PROFILEOUTPUT, totalexetime);
400 } // for(i = 1; i < NUMCORES; ++i)
401 // pour profiling data on startup core
404 BAMBOO_START_CRITICAL_SECTION_STATUS();
406 BAMBOO_DEBUGPRINT(0xf001);
408 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
409 // check the status of all cores
412 BAMBOO_DEBUGPRINT_REG(NUMCORES);
414 for(i = 0; i < NUMCORES; ++i) {
416 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
418 if(profilestatus[i] != 0) {
422 } // for(i = 0; i < NUMCORES; ++i)
425 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
427 BAMBOO_DEBUGPRINT(0xf000);
437 terminate(); // All done.
438 } // if(!waitconfirm)
440 // still some objects on the fly on the network
441 // reset the waitconfirm and numconfirm
443 BAMBOO_DEBUGPRINT(0xee07);
447 } // if(0 == sumsendobj)
449 // not all cores are stall, keep on waiting
451 BAMBOO_DEBUGPRINT(0xee08);
456 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
458 BAMBOO_DEBUGPRINT(0xf000);
460 } // if((!waitconfirm) ||
463 // main function for each core
464 inline void run(void * arg) {
468 bool sendStall = false;
470 bool tocontinue = false;
472 corenum = BAMBOO_GET_NUM_OF_CORE();
474 BAMBOO_DEBUGPRINT(0xeeee);
475 BAMBOO_DEBUGPRINT_REG(corenum);
476 BAMBOO_DEBUGPRINT(STARTUPCORE);
479 // initialize runtime data structures
482 // other architecture related initialization
486 initializeexithandler();
488 // main process of the execution module
489 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
490 // non-executing cores, only processing communications
493 BAMBOO_DEBUGPRINT(0xee01);
494 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
495 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
496 profileTaskStart("msg handling");
500 //isInterrupt = false;
504 /* Create queue of active tasks */
506 genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
507 (int(*) (void *,void *)) &comparetpd);
509 /* Process task information */
512 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
513 /* Create startup object */
514 createstartupobject(argc, argv);
518 BAMBOO_DEBUGPRINT(0xee00);
523 // check if need to do GC
527 // check if there are new active tasks can be executed
534 while(receiveObject() != -1) {
539 BAMBOO_DEBUGPRINT(0xee01);
542 // check if there are some pending objects,
543 // if yes, enqueue them and executetasks again
544 tocontinue = checkObjQueue();
548 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
551 BAMBOO_DEBUGPRINT(0xee03);
559 BAMBOO_DEBUGPRINT(0xee09);
565 // wait for some time
568 BAMBOO_DEBUGPRINT(0xee0a);
574 // send StallMsg to startup core
576 BAMBOO_DEBUGPRINT(0xee0b);
579 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
580 self_numsendobjs, self_numreceiveobjs);
592 BAMBOO_DEBUGPRINT(0xee0c);
595 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
598 } // if(BAMBOO_NUM_OF_CORE > NUMCORES - 1)
602 struct ___createstartupobject____I_locals {
605 struct ___StartupObject___ * ___startupobject___;
606 struct ArrayObject * ___stringarray___;
607 }; // struct ___createstartupobject____I_locals
609 void createstartupobject(int argc,
613 /* Allocate startup object */
615 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
616 struct ___StartupObject___ *startupobject=
617 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
618 ___locals___.___startupobject___ = startupobject;
619 struct ArrayObject * stringarray=
620 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
621 ___locals___.___stringarray___ = stringarray;
623 struct ___StartupObject___ *startupobject=
624 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
625 struct ArrayObject * stringarray=
626 allocate_newarray(STRINGARRAYTYPE, argc-1);
628 /* Build array of strings */
629 startupobject->___parameters___=stringarray;
630 for(i=1; i<argc; i++) {
631 int length=strlen(argv[i]);
633 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
635 struct ___String___ *newstring=NewString(argv[i],length);
637 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
641 startupobject->version = 0;
642 startupobject->lock = NULL;
644 /* Set initialized flag for startup object */
645 flagorandinit(startupobject,1,0xFFFFFFFF);
646 enqueueObject(startupobject, NULL, 0);
648 BAMBOO_CACHE_FLUSH_ALL();
652 int hashCodetpd(struct taskparamdescriptor *ftd) {
653 int hash=(int)ftd->task;
655 for(i=0; i<ftd->numParameters; i++) {
656 hash^=(int)ftd->parameterArray[i];
661 int comparetpd(struct taskparamdescriptor *ftd1,
662 struct taskparamdescriptor *ftd2) {
664 if (ftd1->task!=ftd2->task)
666 for(i=0; i<ftd1->numParameters; i++)
667 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
672 /* This function sets a tag. */
674 void tagset(void *ptr,
675 struct ___Object___ * obj,
676 struct ___TagDescriptor___ * tagd) {
678 void tagset(struct ___Object___ * obj,
679 struct ___TagDescriptor___ * tagd) {
681 struct ArrayObject * ao=NULL;
682 struct ___Object___ * tagptr=obj->___tags___;
684 obj->___tags___=(struct ___Object___ *)tagd;
686 /* Have to check if it is already set */
687 if (tagptr->type==TAGTYPE) {
688 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
693 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
694 struct ArrayObject * ao=
695 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
696 obj=(struct ___Object___ *)ptrarray[2];
697 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
698 td=(struct ___TagDescriptor___ *) obj->___tags___;
700 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
703 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
704 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
705 obj->___tags___=(struct ___Object___ *) ao;
706 ao->___cachedCode___=2;
710 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
711 for(i=0; i<ao->___cachedCode___; i++) {
712 struct ___TagDescriptor___ * td=
713 ARRAYGET(ao, struct ___TagDescriptor___*, i);
718 if (ao->___cachedCode___<ao->___length___) {
719 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
720 ao->___cachedCode___++;
723 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
724 struct ArrayObject * aonew=
725 allocate_newarray(&ptrarray,TAGARRAYTYPE,
726 TAGARRAYINTERVAL+ao->___length___);
727 obj=(struct ___Object___ *)ptrarray[2];
728 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
729 ao=(struct ArrayObject *)obj->___tags___;
731 struct ArrayObject * aonew=
732 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
735 aonew->___cachedCode___=ao->___length___+1;
736 for(i=0; i<ao->___length___; i++) {
737 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
738 ARRAYGET(ao, struct ___TagDescriptor___*, i));
740 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
746 struct ___Object___ * tagset=tagd->flagptr;
749 } else if (tagset->type!=OBJECTARRAYTYPE) {
751 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
752 struct ArrayObject * ao=
753 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
754 obj=(struct ___Object___ *)ptrarray[2];
755 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
757 struct ArrayObject * ao=
758 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
760 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
761 ARRAYSET(ao, struct ___Object___ *, 1, obj);
762 ao->___cachedCode___=2;
763 tagd->flagptr=(struct ___Object___ *)ao;
765 struct ArrayObject *ao=(struct ArrayObject *) tagset;
766 if (ao->___cachedCode___<ao->___length___) {
767 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
771 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
772 struct ArrayObject * aonew=
773 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
774 OBJECTARRAYINTERVAL+ao->___length___);
775 obj=(struct ___Object___ *)ptrarray[2];
776 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
777 ao=(struct ArrayObject *)tagd->flagptr;
779 struct ArrayObject * aonew=
780 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
782 aonew->___cachedCode___=ao->___cachedCode___+1;
783 for(i=0; i<ao->___length___; i++) {
784 ARRAYSET(aonew, struct ___Object___*, i,
785 ARRAYGET(ao, struct ___Object___*, i));
787 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
788 tagd->flagptr=(struct ___Object___ *) aonew;
794 /* This function clears a tag. */
796 void tagclear(void *ptr,
797 struct ___Object___ * obj,
798 struct ___TagDescriptor___ * tagd) {
800 void tagclear(struct ___Object___ * obj,
801 struct ___TagDescriptor___ * tagd) {
803 /* We'll assume that tag is alway there.
804 Need to statically check for this of course. */
805 struct ___Object___ * tagptr=obj->___tags___;
807 if (tagptr->type==TAGTYPE) {
808 if ((struct ___TagDescriptor___ *)tagptr==tagd)
809 obj->___tags___=NULL;
811 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
813 for(i=0; i<ao->___cachedCode___; i++) {
814 struct ___TagDescriptor___ * td=
815 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
817 ao->___cachedCode___--;
818 if (i<ao->___cachedCode___)
819 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
820 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
821 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
822 if (ao->___cachedCode___==0)
823 obj->___tags___=NULL;
830 struct ___Object___ *tagset=tagd->flagptr;
831 if (tagset->type!=OBJECTARRAYTYPE) {
835 struct ArrayObject *ao=(struct ArrayObject *) tagset;
837 for(i=0; i<ao->___cachedCode___; i++) {
838 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
840 ao->___cachedCode___--;
841 if (i<ao->___cachedCode___)
842 ARRAYSET(ao, struct ___Object___ *, i,
843 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
844 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
845 if (ao->___cachedCode___==0)
856 /* This function allocates a new tag. */
858 struct ___TagDescriptor___ * allocate_tag(void *ptr,
860 struct ___TagDescriptor___ * v=
861 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
864 struct ___TagDescriptor___ * allocate_tag(int index) {
865 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
874 /* This function updates the flag for object ptr. It or's the flag
875 with the or mask and and's it with the andmask. */
877 void flagbody(struct ___Object___ *ptr,
879 struct parameterwrapper ** queues,
883 int flagcomp(const int *val1, const int *val2) {
884 return (*val1)-(*val2);
887 void flagorand(void * ptr,
890 struct parameterwrapper ** queues,
893 int oldflag=((int *)ptr)[1];
894 int flag=ormask|oldflag;
896 flagbody(ptr, flag, queues, length, false);
900 bool intflagorand(void * ptr,
904 int oldflag=((int *)ptr)[1];
905 int flag=ormask|oldflag;
907 if (flag==oldflag) /* Don't do anything */
910 flagbody(ptr, flag, NULL, 0, false);
916 void flagorandinit(void * ptr,
919 int oldflag=((int *)ptr)[1];
920 int flag=ormask|oldflag;
922 flagbody(ptr,flag,NULL,0,true);
925 void flagbody(struct ___Object___ *ptr,
927 struct parameterwrapper ** vqueues,
930 struct parameterwrapper * flagptr = NULL;
932 struct parameterwrapper ** queues = vqueues;
933 int length = vlength;
936 int * enterflags = NULL;
937 if((!isnew) && (queues == NULL)) {
938 if(BAMBOO_NUM_OF_CORE < NUMCORES) {
939 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
940 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
947 /*Remove object from all queues */
948 for(i = 0; i < length; ++i) {
950 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
951 (int *) &enterflags, &UNUSED, &UNUSED2);
952 ObjectHashremove(flagptr->objectset, (int)ptr);
953 if (enterflags!=NULL)
958 void enqueueObject(void * vptr,
959 struct parameterwrapper ** vqueues,
961 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
964 //struct QueueItem *tmpptr;
965 struct parameterwrapper * parameter=NULL;
968 struct parameterwrapper * prevptr=NULL;
969 struct ___Object___ *tagptr=NULL;
970 struct parameterwrapper ** queues = vqueues;
971 int length = vlength;
972 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
976 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
977 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
979 tagptr=ptr->___tags___;
981 /* Outer loop iterates through all parameter queues an object of
982 this type could be in. */
983 for(j = 0; j < length; ++j) {
984 parameter = queues[j];
986 if (parameter->numbertags>0) {
988 goto nextloop; //that means the object has no tag
989 //but that param needs tag
990 else if(tagptr->type==TAGTYPE) { //one tag
991 //struct ___TagDescriptor___ * tag=
992 //(struct ___TagDescriptor___*) tagptr;
993 for(i=0; i<parameter->numbertags; i++) {
994 //slotid is parameter->tagarray[2*i];
995 int tagid=parameter->tagarray[2*i+1];
996 if (tagid!=tagptr->flag)
997 goto nextloop; /*We don't have this tag */
999 } else { //multiple tags
1000 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1001 for(i=0; i<parameter->numbertags; i++) {
1002 //slotid is parameter->tagarray[2*i];
1003 int tagid=parameter->tagarray[2*i+1];
1005 for(j=0; j<ao->___cachedCode___; j++) {
1006 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1017 for(i=0; i<parameter->numberofterms; i++) {
1018 int andmask=parameter->intarray[i*2];
1019 int checkmask=parameter->intarray[i*2+1];
1020 if ((ptr->flag&andmask)==checkmask) {
1021 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1032 void enqueueObject_I(void * vptr,
1033 struct parameterwrapper ** vqueues,
1035 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1038 //struct QueueItem *tmpptr;
1039 struct parameterwrapper * parameter=NULL;
1042 struct parameterwrapper * prevptr=NULL;
1043 struct ___Object___ *tagptr=NULL;
1044 struct parameterwrapper ** queues = vqueues;
1045 int length = vlength;
1046 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1049 if(queues == NULL) {
1050 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1051 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1053 tagptr=ptr->___tags___;
1055 /* Outer loop iterates through all parameter queues an object of
1056 this type could be in. */
1057 for(j = 0; j < length; ++j) {
1058 parameter = queues[j];
1060 if (parameter->numbertags>0) {
1062 goto nextloop; //that means the object has no tag
1063 //but that param needs tag
1064 else if(tagptr->type==TAGTYPE) { //one tag
1065 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1066 for(i=0; i<parameter->numbertags; i++) {
1067 //slotid is parameter->tagarray[2*i];
1068 int tagid=parameter->tagarray[2*i+1];
1069 if (tagid!=tagptr->flag)
1070 goto nextloop; /*We don't have this tag */
1072 } else { //multiple tags
1073 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1074 for(i=0; i<parameter->numbertags; i++) {
1075 //slotid is parameter->tagarray[2*i];
1076 int tagid=parameter->tagarray[2*i+1];
1078 for(j=0; j<ao->___cachedCode___; j++) {
1079 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1090 for(i=0; i<parameter->numberofterms; i++) {
1091 int andmask=parameter->intarray[i*2];
1092 int checkmask=parameter->intarray[i*2+1];
1093 if ((ptr->flag&andmask)==checkmask) {
1094 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1106 int * getAliasLock(void ** ptrs,
1108 struct RuntimeHash * tbl) {
1110 return (int*)(RUNMALLOC(sizeof(int)));
1115 bool redirect = false;
1116 int redirectlock = 0;
1117 for(; i < length; i++) {
1118 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1121 if(ptr->lock == NULL) {
1124 lock = (int)(ptr->lock);
1127 if(lock != redirectlock) {
1128 RuntimeHashadd(tbl, lock, redirectlock);
1131 if(RuntimeHashcontainskey(tbl, lock)) {
1132 // already redirected
1134 RuntimeHashget(tbl, lock, &redirectlock);
1135 for(; j < locklen; j++) {
1136 if(locks[j] != redirectlock) {
1137 RuntimeHashadd(tbl, locks[j], redirectlock);
1142 for(j = 0; j < locklen; j++) {
1143 if(locks[j] == lock) {
1146 } else if(locks[j] > lock) {
1153 locks[h] = locks[h-1];
1162 return (int *)redirectlock;
1164 return (int *)(locks[0]);
1169 void addAliasLock(void * ptr,
1171 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1172 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1173 // originally no alias lock associated or have a different alias lock
1174 // flush it as the new one
1175 obj->lock = (int *)lock;
1180 inline void setTaskExitIndex(int index) {
1181 taskInfoArray[taskInfoIndex]->exitIndex = index;
1184 inline void addNewObjInfo(void * nobj) {
1185 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1186 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1188 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1193 struct freeMemItem * findFreeMemChunk_I(int coren,
1196 struct freeMemItem * freemem = bamboo_free_mem_list->head;
1197 struct freeMemItem * prev = NULL;
1200 *tofindb = gc_core2block[2*coren+i]+(NUMCORES*2)*j;
1201 // check available shared mem chunks
1204 switch(bamboo_smem_mode) {
1206 int startb = freemem->startblock;
1207 int endb = freemem->endblock;
1208 while(startb > *tofindb) {
1214 *tofindb = gc_core2block[2*coren+i]+(NUMCORES*2)*j;
1215 } // while(startb > tofindb)
1216 if(startb <= *tofindb) {
1217 if((endb >= *tofindb) && (freemem->size >= isize)) {
1219 } else if(*tofindb > gcnumblock-1) {
1220 // no more local mem
1222 } // if(endb >= tofindb)
1223 } // if(startb <= tofindb)
1228 int startb = freemem->startblock;
1229 int endb = freemem->endblock;
1230 if(startb <= *tofindb) {
1231 if((endb >= *tofindb) && (freemem->size >= isize)) {
1235 // use the global mem
1236 if(((startb > NUMCORES-1) && (freemem->size >= isize)) ||
1237 ((endb > NUMCORES-1) && ((freemem->size-
1238 (gcbaseva+BAMBOO_LARGE_SMEM_BOUND-freemem->ptr))>=isize))) {
1246 // TODO not supported yet
1247 BAMBOO_EXIT(0xe001);
1252 foundsmem = (freemem->size >= isize);
1259 if(1 == foundsmem) {
1262 } else if (2 == foundsmem) {
1263 // terminate, no more mem
1268 freemem = freemem->next;
1269 } while(freemem != NULL);
1272 } // struct freeMemItem * findFreeMemChunk_I(int, int, int *)
1274 void * localmalloc_I(int tofindb,
1276 struct freeMemItem * freemem,
1279 int startb = freemem->startblock;
1280 int endb = freemem->endblock;
1281 int tmpptr = gcbaseva+((tofindb<NUMCORES)?tofindb*BAMBOO_SMEM_SIZE_L
1282 :BAMBOO_LARGE_SMEM_BOUND+(tofindb-NUMCORES)*BAMBOO_SMEM_SIZE);
1283 if((freemem->size+freemem->ptr-tmpptr)>=isize) {
1284 mem = (tmpptr>freemem->ptr)?((void *)tmpptr):(freemem->ptr);
1286 mem = (void *)(freemem->size+freemem->ptr-isize);
1288 // check the remaining space in this block
1289 int remain = (int)(mem-gcbaseva);
1290 int bound = (BAMBOO_SMEM_SIZE);
1291 if(remain < BAMBOO_LARGE_SMEM_BOUND) {
1292 bound = (BAMBOO_SMEM_SIZE_L);
1294 remain = bound - remain%bound;
1295 if(remain < isize) {
1296 // this object acrosses blocks
1299 // round the asigned block to the end of the current block
1300 *allocsize = remain;
1302 if(freemem->ptr == (int)mem) {
1303 freemem->ptr = ((void*)freemem->ptr) + (*allocsize);
1304 freemem->size -= *allocsize;
1305 BLOCKINDEX(freemem->ptr, &(freemem->startblock));
1306 } else if((freemem->ptr+freemem->size) == ((int)mem+(*allocsize))) {
1307 freemem->size -= *allocsize;
1308 BLOCKINDEX(((int)mem)-1, &(freemem->endblock));
1310 struct freeMemItem * tmp =
1311 (struct freeMemItem *)RUNMALLOC_I(sizeof(struct freeMemItem));
1312 tmp->ptr = (int)mem+*allocsize;
1313 tmp->size = freemem->ptr+freemem->size-(int)mem-*allocsize;
1314 BLOCKINDEX(tmp->ptr, &(tmp->startblock));
1315 tmp->endblock = freemem->endblock;
1316 tmp->next = freemem->next;
1317 freemem->next = tmp;
1318 freemem->size = (int)mem - freemem->ptr;
1319 BLOCKINDEX(((int)mem-1), &(freemem->endblock));
1322 } // void * localmalloc_I(int, int, struct freeMemItem *, int *)
1324 void * globalmalloc_I(int isize,
1325 struct freeMemItem * freemem,
1327 void * mem = (void *)(freemem->ptr);
1328 // check the remaining space in this block
1329 int remain = (int)(mem-(BAMBOO_BASE_VA));
1330 int bound = (BAMBOO_SMEM_SIZE);
1331 if(remain < BAMBOO_LARGE_SMEM_BOUND) {
1332 bound = (BAMBOO_SMEM_SIZE_L);
1334 remain = bound - remain%bound;
1335 if(remain < isize) {
1336 // this object acrosses blocks
1339 // round the asigned block to the end of the current block
1340 *allocsize = remain;
1342 freemem->ptr = ((void*)freemem->ptr) + (*allocsize);
1343 freemem->size -= *allocsize;
1345 } // void * globalmalloc_I(int, struct freeMemItem *, int *)
1348 // malloc from the shared memory
1349 void * smemalloc_I(int coren,
1354 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1355 int toallocate = (isize>(BAMBOO_SMEM_SIZE)) ? (isize):(BAMBOO_SMEM_SIZE);
1356 // go through free mem list for suitable chunks
1358 struct freeMemItem * freemem = findFreeMemChunk_I(coren, isize, &tofindb);
1360 // allocate shared mem if available
1361 if(freemem != NULL) {
1362 switch(bamboo_smem_mode) {
1364 mem = localmalloc_I(tofindb, isize, freemem, allocsize);
1369 int startb = freemem->startblock;
1370 int endb = freemem->endblock;
1371 if(startb > tofindb) {
1372 // malloc on global mem
1373 mem = globalmalloc_I(isize, freemem, allocsize);
1375 // malloc on local mem
1376 mem = localmalloc_I(tofindb, isize, freemem, allocsize);
1382 // TODO not supported yet
1383 BAMBOO_EXIT(0xe002);
1388 mem = globalmalloc_I(isize,freemem, allocsize);
1397 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size):(BAMBOO_SMEM_SIZE);
1398 mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1399 *allocsize = toallocate;
1402 // no enough shared global memory
1408 BAMBOO_DEBUGPRINT(0xa001);
1409 BAMBOO_EXIT(0xa001);
1413 } // void * smemalloc_I(int, int, int)
1415 // receive object transferred from other cores
1416 // or the terminate message from other cores
1417 // Should be invoked in critical sections!!
1418 // NOTICE: following format is for threadsimulate version only
1419 // RAW version please see previous description
1420 // format: type + object
1421 // type: -1--stall msg
1423 // return value: 0--received an object
1424 // 1--received nothing
1425 // 2--received a Stall Msg
1426 // 3--received a lock Msg
1427 // RAW version: -1 -- received nothing
1428 // otherwise -- received msg type
1429 int receiveObject() {
1433 if(receiveMsg() == -1) {
1437 if(msgdataindex == msglength) {
1438 // received a whole msg
1443 // receive a object transfer msg
1444 struct transObjInfo * transObj =
1445 RUNMALLOC_I(sizeof(struct transObjInfo));
1449 BAMBOO_DEBUGPRINT(0xe880);
1452 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1454 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1456 BAMBOO_EXIT(0xa002);
1458 // store the object and its corresponding queue info, enqueue it later
1459 transObj->objptr = (void *)msgdata[2];
1460 transObj->length = (msglength - 3) / 2;
1461 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1462 for(k = 0; k < transObj->length; ++k) {
1463 transObj->queues[2*k] = msgdata[3+2*k];
1466 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1469 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1472 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1476 // check if there is an existing duplicate item
1478 struct QueueItem * qitem = getHead(&objqueue);
1479 struct QueueItem * prev = NULL;
1480 while(qitem != NULL) {
1481 struct transObjInfo * tmpinfo =
1482 (struct transObjInfo *)(qitem->objectptr);
1483 if(tmpinfo->objptr == transObj->objptr) {
1484 // the same object, remove outdate one
1485 removeItem(&objqueue, qitem);
1491 qitem = getHead(&objqueue);
1493 qitem = getNextQueueItem(prev);
1496 addNewItem_I(&objqueue, (void *)transObj);
1498 ++(self_numreceiveobjs);
1503 // receive a stall msg
1504 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1505 // non startup core can not receive stall msg
1507 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1509 BAMBOO_EXIT(0xa003);
1511 if(msgdata[1] < NUMCORES) {
1514 BAMBOO_DEBUGPRINT(0xe881);
1517 corestatus[msgdata[1]] = 0;
1518 numsendobjs[msgdata[1]] = msgdata[2];
1519 numreceiveobjs[msgdata[1]] = msgdata[3];
1524 // GC version have no lock msgs
1525 #ifndef MULTICORE_GC
1527 // receive lock request msg, handle it right now
1528 // check to see if there is a lock exist for the required obj
1529 // msgdata[1] -> lock type
1530 int data2 = msgdata[2]; // obj pointer
1531 int data3 = msgdata[3]; // lock
1532 int data4 = msgdata[4]; // request core
1533 // -1: redirected, 0: approved, 1: denied
1534 deny = processlockrequest(msgdata[1], data3, data2,
1535 data4, data4, true);
1537 // this lock request is redirected
1540 // send response msg
1541 // for 32 bit machine, the size is always 4 words
1542 int tmp = deny==1?LOCKDENY:LOCKGROUNT;
1544 cache_msg_4(data4, tmp, msgdata[1], data2, data3);
1546 send_msg_4(data4, tmp, msgdata[1], data2, data3);
1553 // receive lock grount msg
1554 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1556 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1558 BAMBOO_EXIT(0xa004);
1560 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1563 BAMBOO_DEBUGPRINT(0xe882);
1572 // conflicts on lockresults
1574 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1576 BAMBOO_EXIT(0xa005);
1582 // receive lock deny msg
1583 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1585 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1587 BAMBOO_EXIT(0xa006);
1589 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1592 BAMBOO_DEBUGPRINT(0xe883);
1601 // conflicts on lockresults
1603 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1605 BAMBOO_EXIT(0xa007);
1611 // receive lock release msg
1612 processlockrelease(msgdata[1], msgdata[2], 0, false);
1618 case PROFILEOUTPUT: {
1619 // receive an output profile data request msg
1620 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1621 // startup core can not receive profile output finish msg
1622 BAMBOO_EXIT(0xa008);
1626 BAMBOO_DEBUGPRINT(0xe885);
1630 totalexetime = msgdata[1];
1631 outputProfileData();
1633 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1635 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1640 case PROFILEFINISH: {
1641 // receive a profile output finish msg
1642 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1643 // non startup core can not receive profile output finish msg
1645 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1647 BAMBOO_EXIT(0xa009);
1651 BAMBOO_DEBUGPRINT(0xe886);
1654 profilestatus[msgdata[1]] = 0;
1659 // GC version has no lock msgs
1660 #ifndef MULTICORE_GC
1661 case REDIRECTLOCK: {
1662 // receive a redirect lock request msg, handle it right now
1663 // check to see if there is a lock exist for the required obj
1664 int data1 = msgdata[1]; // lock type
1665 int data2 = msgdata[2]; // obj pointer
1666 int data3 = msgdata[3]; // redirect lock
1667 int data4 = msgdata[4]; // root request core
1668 int data5 = msgdata[5]; // request core
1669 deny = processlockrequest(msgdata[1], data3, data2, data5, data4, true);
1671 // this lock request is redirected
1674 // send response msg
1675 // for 32 bit machine, the size is always 4 words
1677 cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1678 data1, data2, data3);
1680 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1681 data1, data2, data3);
1687 case REDIRECTGROUNT: {
1688 // receive a lock grant msg with redirect info
1689 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1691 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1693 BAMBOO_EXIT(0xa00a);
1695 if(lockobj == msgdata[2]) {
1698 BAMBOO_DEBUGPRINT(0xe891);
1703 RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1708 // conflicts on lockresults
1710 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1712 BAMBOO_EXIT(0xa00b);
1717 case REDIRECTDENY: {
1718 // receive a lock deny msg with redirect info
1719 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1721 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1723 BAMBOO_EXIT(0xa00c);
1725 if(lockobj == msgdata[2]) {
1728 BAMBOO_DEBUGPRINT(0xe892);
1737 // conflicts on lockresults
1739 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1741 BAMBOO_EXIT(0xa00d);
1746 case REDIRECTRELEASE: {
1747 // receive a lock release msg with redirect info
1748 processlockrelease(msgdata[1], msgdata[2], msgdata[3], true);
1753 case STATUSCONFIRM: {
1754 // receive a status confirm info
1755 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1756 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
1757 // wrong core to receive such msg
1758 BAMBOO_EXIT(0xa00e);
1760 // send response msg
1763 BAMBOO_DEBUGPRINT(0xe887);
1767 cache_msg_5(STARTUPCORE, STATUSREPORT,
1768 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1769 self_numsendobjs, self_numreceiveobjs);
1771 send_msg_5(STARTUPCORE, STATUSREPORT,
1772 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1773 self_numsendobjs, self_numreceiveobjs);
1779 case STATUSREPORT: {
1780 // receive a status confirm info
1781 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1782 // wrong core to receive such msg
1784 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1786 BAMBOO_EXIT(0xa00f);
1790 BAMBOO_DEBUGPRINT(0xe888);
1796 corestatus[msgdata[2]] = msgdata[1];
1797 numsendobjs[msgdata[2]] = msgdata[3];
1798 numreceiveobjs[msgdata[2]] = msgdata[4];
1804 // receive a terminate msg
1807 BAMBOO_DEBUGPRINT(0xe889);
1816 // receive a shared memory request msg
1817 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1818 // wrong core to receive such msg
1820 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1822 BAMBOO_EXIT(0xa010);
1826 BAMBOO_DEBUGPRINT(0xe88a);
1831 // is currently doing gc, dump this msg
1836 void * mem = smemalloc_I(msgdata[2], msgdata[1], &allocsize);
1840 // send the start_va to request core
1842 cache_msg_3(msgdata[2], MEMRESPONSE, mem, allocsize);
1844 send_msg_3( msgdata[2], MEMRESPONSE, mem, allocsize);
1851 // receive a shared memory response msg
1854 BAMBOO_DEBUGPRINT(0xe88b);
1859 // is currently doing gc, dump this msg
1863 if(msgdata[2] == 0) {
1864 bamboo_smem_size = 0;
1868 // fill header to store the size of this mem block
1869 (*((int*)msgdata[1])) = msgdata[2];
1870 bamboo_smem_size = msgdata[2] - BAMBOO_CACHE_LINE_SIZE;
1871 bamboo_cur_msp = msgdata[1] + BAMBOO_CACHE_LINE_SIZE;
1873 bamboo_smem_size = msgdata[2];
1874 bamboo_cur_msp =(void*)(msgdata[1]);
1885 gcphase = INITPHASE;
1887 // is waiting for response of mem request
1888 // let it return NULL and start gc
1889 bamboo_smem_size = 0;
1890 bamboo_cur_msp = NULL;
1897 // receive a start GC msg
1900 BAMBOO_DEBUGPRINT(0xe88c);
1904 gcphase = MARKPHASE;
1908 case GCSTARTCOMPACT: {
1909 // a compact phase start msg
1910 gcblock2fill = msgdata[1];
1911 gcphase = COMPACTPHASE;
1915 case GCSTARTFLUSH: {
1916 // received a flush phase start msg
1917 gcphase = FLUSHPHASE;
1921 case GCFINISHINIT: {
1922 // received a init phase finish msg
1923 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1924 // non startup core can not receive this msg
1926 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1928 BAMBOO_EXIT(0xb001);
1931 BAMBOO_DEBUGPRINT(0xe88c);
1932 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1934 if(msgdata[1] < NUMCORES) {
1935 gccorestatus[msgdata[1]] = 0;
1939 case GCFINISHMARK: {
1940 // received a mark phase finish msg
1941 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1942 // non startup core can not receive this msg
1944 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1946 BAMBOO_EXIT(0xb002);
1948 if(msgdata[1] < NUMCORES) {
1949 gccorestatus[msgdata[1]] = 0;
1950 gcnumsendobjs[msgdata[1]] = msgdata[2];
1951 gcnumreceiveobjs[msgdata[1]] = msgdata[3];
1956 case GCFINISHCOMPACT: {
1957 // received a compact phase finish msg
1958 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1959 // non startup core can not receive this msg
1962 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1964 BAMBOO_EXIT(0xb003);
1966 int cnum = msgdata[1];
1967 int filledblocks = msgdata[2];
1968 int heaptop = msgdata[3];
1969 int data4 = msgdata[4];
1970 if(cnum < NUMCORES) {
1971 if(COMPACTPHASE == gcphase) {
1972 gcfilledblocks[cnum] = filledblocks;
1973 gcloads[cnum] = heaptop;
1980 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
1982 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
1984 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
1988 gccorestatus[cnum] = 0;
1989 // check if there is pending move request
1990 /*if(gcmovepending > 0) {
1992 for(j = 0; j < NUMCORES; j++) {
1993 if(gcrequiredmems[j]>0) {
2001 gcrequiredmems[j] = assignSpareMem_I(cnum,
2005 if(STARTUPCORE == j) {
2008 gcmovestartaddr = startaddr;
2009 gcblock2fill = tomove;
2012 cache_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
2014 send_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
2016 } // if(STARTUPCORE == j)
2017 if(gcrequiredmems[j] == 0) {
2020 } // if(j < NUMCORES)
2021 } // if(gcmovepending > 0) */
2023 } // if(cnum < NUMCORES)
2027 case GCFINISHFLUSH: {
2028 // received a flush phase finish msg
2029 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2030 // non startup core can not receive this msg
2033 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2035 BAMBOO_EXIT(0xb004);
2037 if(msgdata[1] < NUMCORES) {
2038 gccorestatus[msgdata[1]] = 0;
2044 // received a GC finish msg
2045 gcphase = FINISHPHASE;
2049 case GCMARKCONFIRM: {
2050 // received a marked phase finish confirm request msg
2051 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2052 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
2053 // wrong core to receive such msg
2054 BAMBOO_EXIT(0xb005);
2056 // send response msg
2058 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2059 gcbusystatus, gcself_numsendobjs,
2060 gcself_numreceiveobjs);
2062 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2063 gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
2069 case GCMARKREPORT: {
2070 // received a marked phase finish confirm response msg
2071 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2072 // wrong core to receive such msg
2074 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2076 BAMBOO_EXIT(0xb006);
2081 gccorestatus[msgdata[1]] = msgdata[2];
2082 gcnumsendobjs[msgdata[1]] = msgdata[3];
2083 gcnumreceiveobjs[msgdata[1]] = msgdata[4];
2089 // received a markedObj msg
2090 gc_enqueue_I(msgdata[1]);
2091 gcself_numreceiveobjs++;
2092 gcbusystatus = true;
2097 // received a start moving objs msg
2099 gcdstcore = msgdata[1];
2100 gcmovestartaddr = msgdata[2];
2101 gcblock2fill = msgdata[3];
2105 case GCMAPREQUEST: {
2106 // received a mapping info request msg
2107 void * dstptr = NULL;
2108 RuntimeHashget(gcpointertbl, msgdata[1], &dstptr);
2109 if(NULL == dstptr) {
2110 // no such pointer in this core, something is wrong
2112 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2113 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2115 BAMBOO_EXIT(0xb007);
2117 // send back the mapping info
2119 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
2121 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
2128 // received a mapping info response msg
2129 if(msgdata[1] != gcobj2map) {
2130 // obj not matched, something is wrong
2132 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2133 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2135 BAMBOO_EXIT(0xb008);
2137 gcmappedobj = msgdata[2];
2138 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2144 case GCLOBJREQUEST: {
2145 // received a large objs info request msg
2146 transferMarkResults_I();
2151 // received a large objs info response msg
2154 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2156 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2158 BAMBOO_EXIT(0xb009);
2160 // store the mark result info
2161 int cnum = msgdata[2];
2162 gcloads[cnum] = msgdata[3];
2163 if(gcheaptop < msgdata[4]) {
2164 gcheaptop = msgdata[4];
2166 // large obj info here
2167 for(int k = 5; k < msgdata[1];) {
2168 int lobj = msgdata[k++];
2169 int length = msgdata[k++];
2170 gc_lobjenqueue_I(lobj, length, cnum);
2172 } // for(int k = 5; k < msgdata[1];)
2176 case GCLOBJMAPPING: {
2177 // received a large obj mapping info msg
2178 RuntimeHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2187 for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
2188 msgdata[msgdataindex] = -1;
2194 BAMBOO_DEBUGPRINT(0xe88d);
2198 if(BAMBOO_MSG_AVAIL() != 0) {
2211 BAMBOO_DEBUGPRINT(0xe88e);
2215 /* if(isInterrupt) {
2223 int enqueuetasks(struct parameterwrapper *parameter,
2224 struct parameterwrapper *prevptr,
2225 struct ___Object___ *ptr,
2227 int numenterflags) {
2228 void * taskpointerarray[MAXTASKPARAMS];
2230 //int numparams=parameter->task->numParameters;
2231 int numiterators=parameter->task->numTotal-1;
2234 struct taskdescriptor * task=parameter->task;
2236 //this add the object to parameterwrapper
2237 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
2238 numenterflags, enterflags==NULL);
2240 /* Add enqueued object to parameter vector */
2241 taskpointerarray[parameter->slot]=ptr;
2243 /* Reset iterators */
2244 for(j=0; j<numiterators; j++) {
2245 toiReset(¶meter->iterators[j]);
2248 /* Find initial state */
2249 for(j=0; j<numiterators; j++) {
2251 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2252 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2254 /* Need to backtrack */
2255 toiReset(¶meter->iterators[j]);
2259 /* Nothing to enqueue */
2265 /* Enqueue current state */
2267 struct taskparamdescriptor *tpd=
2268 RUNMALLOC(sizeof(struct taskparamdescriptor));
2270 tpd->numParameters=numiterators+1;
2271 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2273 for(j=0; j<=numiterators; j++) {
2274 //store the actual parameters
2275 tpd->parameterArray[j]=taskpointerarray[j];
2278 if ((/*!gencontains(failedtasks, tpd)&&*/
2279 !gencontains(activetasks,tpd))) {
2280 genputtable(activetasks, tpd, tpd);
2282 RUNFREE(tpd->parameterArray);
2286 /* This loop iterates to the next parameter combination */
2287 if (numiterators==0)
2290 for(j=numiterators-1; j<numiterators; j++) {
2292 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2293 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2295 /* Need to backtrack */
2296 toiReset(¶meter->iterators[j]);
2300 /* Nothing more to enqueue */
2308 int enqueuetasks_I(struct parameterwrapper *parameter,
2309 struct parameterwrapper *prevptr,
2310 struct ___Object___ *ptr,
2312 int numenterflags) {
2313 void * taskpointerarray[MAXTASKPARAMS];
2315 //int numparams=parameter->task->numParameters;
2316 int numiterators=parameter->task->numTotal-1;
2321 struct taskdescriptor * task=parameter->task;
2323 //this add the object to parameterwrapper
2324 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2325 numenterflags, enterflags==NULL);
2327 /* Add enqueued object to parameter vector */
2328 taskpointerarray[parameter->slot]=ptr;
2330 /* Reset iterators */
2331 for(j=0; j<numiterators; j++) {
2332 toiReset(¶meter->iterators[j]);
2335 /* Find initial state */
2336 for(j=0; j<numiterators; j++) {
2338 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2339 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2341 /* Need to backtrack */
2342 toiReset(¶meter->iterators[j]);
2346 /* Nothing to enqueue */
2352 /* Enqueue current state */
2354 struct taskparamdescriptor *tpd=
2355 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2357 tpd->numParameters=numiterators+1;
2358 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2360 for(j=0; j<=numiterators; j++) {
2361 //store the actual parameters
2362 tpd->parameterArray[j]=taskpointerarray[j];
2365 if ((/*!gencontains(failedtasks, tpd)&&*/
2366 !gencontains(activetasks,tpd))) {
2367 genputtable_I(activetasks, tpd, tpd);
2369 RUNFREE(tpd->parameterArray);
2373 /* This loop iterates to the next parameter combination */
2374 if (numiterators==0)
2377 for(j=numiterators-1; j<numiterators; j++) {
2379 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2380 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2382 /* Need to backtrack */
2383 toiReset(¶meter->iterators[j]);
2387 /* Nothing more to enqueue */
2401 int containstag(struct ___Object___ *ptr,
2402 struct ___TagDescriptor___ *tag);
2404 #ifndef MULTICORE_GC
2405 void releasewritelock_r(void * lock, void * redirectlock) {
2407 int reallock = (int)lock;
2408 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2411 BAMBOO_DEBUGPRINT(0xe671);
2412 BAMBOO_DEBUGPRINT_REG((int)lock);
2413 BAMBOO_DEBUGPRINT_REG(reallock);
2414 BAMBOO_DEBUGPRINT_REG(targetcore);
2417 if(targetcore == BAMBOO_NUM_OF_CORE) {
2418 BAMBOO_START_CRITICAL_SECTION_LOCK();
2420 BAMBOO_DEBUGPRINT(0xf001);
2422 // reside on this core
2423 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2424 // no locks for this object, something is wrong
2425 BAMBOO_EXIT(0xa011);
2428 struct LockValue * lockvalue = NULL;
2430 BAMBOO_DEBUGPRINT(0xe672);
2432 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2433 lockvalue = (struct LockValue *)rwlock_obj;
2435 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2438 lockvalue->redirectlock = (int)redirectlock;
2440 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2443 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2445 BAMBOO_DEBUGPRINT(0xf000);
2449 // send lock release with redirect info msg
2450 // for 32 bit machine, the size is always 4 words
2451 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
2456 void executetasks() {
2457 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2460 struct ___Object___ * tmpparam = NULL;
2461 struct parameterdescriptor * pd=NULL;
2462 struct parameterwrapper *pw=NULL;
2472 while(hashsize(activetasks)>0) {
2477 BAMBOO_DEBUGPRINT(0xe990);
2480 /* See if there are any active tasks */
2481 if (hashsize(activetasks)>0) {
2484 #ifdef ACCURATEPROFILE
2485 profileTaskStart("tpd checking");
2489 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2490 genfreekey(activetasks, currtpd);
2492 numparams=currtpd->task->numParameters;
2493 numtotal=currtpd->task->numTotal;
2495 // clear the lockRedirectTbl
2496 // (TODO, this table should be empty after all locks are released)
2498 for(j = 0; j < MAXTASKPARAMS; j++) {
2499 runtime_locks[j].redirectlock = 0;
2500 runtime_locks[j].value = 0;
2502 // get all required locks
2503 runtime_locklen = 0;
2504 // check which locks are needed
2505 for(i = 0; i < numparams; i++) {
2506 void * param = currtpd->parameterArray[i];
2510 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2512 taskpointerarray[i+OFFSET]=param;
2515 if(((struct ___Object___ *)param)->lock == NULL) {
2516 tmplock = (int)param;
2518 tmplock = (int)(((struct ___Object___ *)param)->lock);
2520 // insert into the locks array
2521 for(j = 0; j < runtime_locklen; j++) {
2522 if(runtime_locks[j].value == tmplock) {
2525 } else if(runtime_locks[j].value > tmplock) {
2530 int h = runtime_locklen;
2532 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
2533 runtime_locks[h].value = runtime_locks[h-1].value;
2535 runtime_locks[j].value = tmplock;
2536 runtime_locks[j].redirectlock = (int)param;
2539 } // line 2713: for(i = 0; i < numparams; i++)
2540 // grab these required locks
2542 BAMBOO_DEBUGPRINT(0xe991);
2544 for(i = 0; i < runtime_locklen; i++) {
2545 int * lock = (int *)(runtime_locks[i].redirectlock);
2547 // require locks for this parameter if it is not a startup object
2549 BAMBOO_DEBUGPRINT_REG((int)lock);
2550 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
2553 BAMBOO_START_CRITICAL_SECTION();
2555 BAMBOO_DEBUGPRINT(0xf001);
2558 //isInterrupt = false;
2561 BAMBOO_WAITING_FOR_LOCK();
2565 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2569 grount = lockresult;
2579 //isInterrupt = true;
2581 BAMBOO_CLOSE_CRITICAL_SECTION();
2583 BAMBOO_DEBUGPRINT(0xf000);
2589 BAMBOO_DEBUGPRINT(0xe992);
2590 BAMBOO_DEBUGPRINT_REG(lock);
2592 // can not get the lock, try later
2593 // releas all grabbed locks for previous parameters
2594 for(j = 0; j < i; ++j) {
2595 lock = (int*)(runtime_locks[j].redirectlock);
2596 releasewritelock(lock);
2598 genputtable(activetasks, currtpd, currtpd);
2599 if(hashsize(activetasks) == 1) {
2600 // only one task right now, wait a little while before next try
2606 #ifdef ACCURATEPROFILE
2607 // fail, set the end of the checkTaskInfo
2612 } // line 2794: if(grount == 0)
2613 } // line 2752: for(i = 0; i < runtime_locklen; i++)
2616 BAMBOO_DEBUGPRINT(0xe993);
2618 /* Make sure that the parameters are still in the queues */
2619 for(i=0; i<numparams; i++) {
2620 void * parameter=currtpd->parameterArray[i];
2624 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
2625 classsize[((struct ___Object___ *)parameter)->type]);
2627 tmpparam = (struct ___Object___ *)parameter;
2628 pd=currtpd->task->descriptorarray[i];
2629 pw=(struct parameterwrapper *) pd->queue;
2630 /* Check that object is still in queue */
2632 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2634 BAMBOO_DEBUGPRINT(0xe994);
2635 BAMBOO_DEBUGPRINT_REG(parameter);
2637 // release grabbed locks
2638 for(j = 0; j < runtime_locklen; ++j) {
2639 int * lock = (int *)(runtime_locks[j].redirectlock);
2640 releasewritelock(lock);
2642 RUNFREE(currtpd->parameterArray);
2648 /* Check if the object's flags still meets requirements */
2652 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2653 andmask=pw->intarray[tmpi*2];
2654 checkmask=pw->intarray[tmpi*2+1];
2655 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2661 // flags are never suitable
2662 // remove this obj from the queue
2664 int UNUSED, UNUSED2;
2667 BAMBOO_DEBUGPRINT(0xe995);
2668 BAMBOO_DEBUGPRINT_REG(parameter);
2670 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
2671 (int *) &enterflags, &UNUSED, &UNUSED2);
2672 ObjectHashremove(pw->objectset, (int)parameter);
2673 if (enterflags!=NULL)
2674 RUNFREE(enterflags);
2675 // release grabbed locks
2676 for(j = 0; j < runtime_locklen; ++j) {
2677 int * lock = (int *)(runtime_locks[j].redirectlock);
2678 releasewritelock(lock);
2680 RUNFREE(currtpd->parameterArray);
2684 #ifdef ACCURATEPROFILE
2685 // fail, set the end of the checkTaskInfo
2690 } // line 2878: if (!ismet)
2694 /* Check that object still has necessary tags */
2695 for(j=0; j<pd->numbertags; j++) {
2696 int slotid=pd->tagarray[2*j]+numparams;
2697 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2698 if (!containstag(parameter, tagd)) {
2700 BAMBOO_DEBUGPRINT(0xe996);
2703 // release grabbed locks
2705 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
2706 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
2707 releasewritelock(lock);
2710 RUNFREE(currtpd->parameterArray);
2714 } // line2911: if (!containstag(parameter, tagd))
2715 } // line 2808: for(j=0; j<pd->numbertags; j++)
2717 taskpointerarray[i+OFFSET]=parameter;
2718 } // line 2824: for(i=0; i<numparams; i++)
2720 for(; i<numtotal; i++) {
2721 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2726 /* Actually call task */
2728 ((int *)taskpointerarray)[0]=currtpd->numParameters;
2729 taskpointerarray[1]=NULL;
2732 #ifdef ACCURATEPROFILE
2733 // check finish, set the end of the checkTaskInfo
2736 profileTaskStart(currtpd->task->name);
2740 BAMBOO_DEBUGPRINT(0xe997);
2742 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2744 #ifdef ACCURATEPROFILE
2745 // task finish, set the end of the checkTaskInfo
2747 // new a PostTaskInfo for the post-task execution
2748 profileTaskStart("post task execution");
2752 BAMBOO_DEBUGPRINT(0xe998);
2753 BAMBOO_DEBUGPRINT_REG(islock);
2758 BAMBOO_DEBUGPRINT(0xe999);
2760 for(i = 0; i < runtime_locklen; ++i) {
2761 void * ptr = (void *)(runtime_locks[i].redirectlock);
2762 int * lock = (int *)(runtime_locks[i].value);
2764 BAMBOO_DEBUGPRINT_REG((int)ptr);
2765 BAMBOO_DEBUGPRINT_REG((int)lock);
2767 #ifndef MULTICORE_GC
2768 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2770 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2771 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2772 releasewritelock_r(lock, (int *)redirectlock);
2777 releasewritelock(ptr);
2780 } // line 3015: if(islock)
2783 // post task execution finish, set the end of the postTaskInfo
2787 // Free up task parameter descriptor
2788 RUNFREE(currtpd->parameterArray);
2792 BAMBOO_DEBUGPRINT(0xe99a);
2795 } // if (hashsize(activetasks)>0)
2796 } // while(hashsize(activetasks)>0)
2798 BAMBOO_DEBUGPRINT(0xe99b);
2802 /* This function processes an objects tags */
2803 void processtags(struct parameterdescriptor *pd,
2805 struct parameterwrapper *parameter,
2806 int * iteratorcount,
2811 for(i=0; i<pd->numbertags; i++) {
2812 int slotid=pd->tagarray[2*i];
2813 int tagid=pd->tagarray[2*i+1];
2815 if (statusarray[slotid+numparams]==0) {
2816 parameter->iterators[*iteratorcount].istag=1;
2817 parameter->iterators[*iteratorcount].tagid=tagid;
2818 parameter->iterators[*iteratorcount].slot=slotid+numparams;
2819 parameter->iterators[*iteratorcount].tagobjectslot=index;
2820 statusarray[slotid+numparams]=1;
2827 void processobject(struct parameterwrapper *parameter,
2829 struct parameterdescriptor *pd,
2835 struct ObjectHash * objectset=
2836 ((struct parameterwrapper *)pd->queue)->objectset;
2838 parameter->iterators[*iteratorcount].istag=0;
2839 parameter->iterators[*iteratorcount].slot=index;
2840 parameter->iterators[*iteratorcount].objectset=objectset;
2841 statusarray[index]=1;
2843 for(i=0; i<pd->numbertags; i++) {
2844 int slotid=pd->tagarray[2*i];
2845 //int tagid=pd->tagarray[2*i+1];
2846 if (statusarray[slotid+numparams]!=0) {
2847 /* This tag has already been enqueued, use it to narrow search */
2848 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
2853 parameter->iterators[*iteratorcount].numtags=tagcount;
2858 /* This function builds the iterators for a task & parameter */
2860 void builditerators(struct taskdescriptor * task,
2862 struct parameterwrapper * parameter) {
2863 int statusarray[MAXTASKPARAMS];
2865 int numparams=task->numParameters;
2866 int iteratorcount=0;
2867 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
2869 statusarray[index]=1; /* Initial parameter */
2870 /* Process tags for initial iterator */
2872 processtags(task->descriptorarray[index], index, parameter,
2873 &iteratorcount, statusarray, numparams);
2877 /* Check for objects with existing tags */
2878 for(i=0; i<numparams; i++) {
2879 if (statusarray[i]==0) {
2880 struct parameterdescriptor *pd=task->descriptorarray[i];
2882 for(j=0; j<pd->numbertags; j++) {
2883 int slotid=pd->tagarray[2*j];
2884 if(statusarray[slotid+numparams]!=0) {
2885 processobject(parameter, i, pd, &iteratorcount, statusarray,
2887 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2894 /* Next do objects w/ unbound tags*/
2896 for(i=0; i<numparams; i++) {
2897 if (statusarray[i]==0) {
2898 struct parameterdescriptor *pd=task->descriptorarray[i];
2899 if (pd->numbertags>0) {
2900 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2901 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2907 /* Nothing with a tag enqueued */
2909 for(i=0; i<numparams; i++) {
2910 if (statusarray[i]==0) {
2911 struct parameterdescriptor *pd=task->descriptorarray[i];
2912 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2913 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2926 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2929 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2930 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2932 printf("%s\n", task->name);
2934 for(j=0; j<task->numParameters; j++) {
2935 struct parameterdescriptor *param=task->descriptorarray[j];
2936 struct parameterwrapper *parameter=param->queue;
2937 struct ObjectHash * set=parameter->objectset;
2938 struct ObjectIterator objit;
2940 printf(" Parameter %d\n", j);
2942 ObjectHashiterator(set, &objit);
2943 while(ObjhasNext(&objit)) {
2944 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
2945 struct ___Object___ * tagptr=obj->___tags___;
2946 int nonfailed=Objdata4(&objit);
2947 int numflags=Objdata3(&objit);
2948 int flags=Objdata2(&objit);
2951 printf(" Contains %lx\n", obj);
2952 printf(" flag=%d\n", obj->flag);
2955 } else if (tagptr->type==TAGTYPE) {
2957 printf(" tag=%lx\n",tagptr);
2963 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
2964 for(; tagindex<ao->___cachedCode___; tagindex++) {
2966 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
2979 /* This function processes the task information to create queues for
2980 each parameter type. */
2982 void processtasks() {
2984 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2987 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2988 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2991 /* Build objectsets */
2992 for(j=0; j<task->numParameters; j++) {
2993 struct parameterdescriptor *param=task->descriptorarray[j];
2994 struct parameterwrapper *parameter=param->queue;
2995 parameter->objectset=allocateObjectHash(10);
2996 parameter->task=task;
2999 /* Build iterators for parameters */
3000 for(j=0; j<task->numParameters; j++) {
3001 struct parameterdescriptor *param=task->descriptorarray[j];
3002 struct parameterwrapper *parameter=param->queue;
3003 builditerators(task, j, parameter);
3008 void toiReset(struct tagobjectiterator * it) {
3011 } else if (it->numtags>0) {
3014 ObjectHashiterator(it->objectset, &it->it);
3018 int toiHasNext(struct tagobjectiterator *it,
3019 void ** objectarray OPTARG(int * failed)) {
3022 /* Get object with tags */
3023 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3024 struct ___Object___ *tagptr=obj->___tags___;
3025 if (tagptr->type==TAGTYPE) {
3026 if ((it->tagobjindex==0)&& /* First object */
3027 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3032 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3033 int tagindex=it->tagobjindex;
3034 for(; tagindex<ao->___cachedCode___; tagindex++) {
3035 struct ___TagDescriptor___ *td=
3036 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3037 if (td->flag==it->tagid) {
3038 it->tagobjindex=tagindex; /* Found right type of tag */
3044 } else if (it->numtags>0) {
3045 /* Use tags to locate appropriate objects */
3046 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3047 struct ___Object___ *objptr=tag->flagptr;
3049 if (objptr->type!=OBJECTARRAYTYPE) {
3050 if (it->tagobjindex>0)
3052 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3054 for(i=1; i<it->numtags; i++) {
3055 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3056 if (!containstag(objptr,tag2))
3061 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3064 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
3065 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3066 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3068 for(i=1; i<it->numtags; i++) {
3069 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3070 if (!containstag(objptr,tag2))
3073 it->tagobjindex=tagindex;
3078 it->tagobjindex=tagindex;
3082 return ObjhasNext(&it->it);
3086 int containstag(struct ___Object___ *ptr,
3087 struct ___TagDescriptor___ *tag) {
3089 struct ___Object___ * objptr=tag->flagptr;
3090 if (objptr->type==OBJECTARRAYTYPE) {
3091 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3092 for(j=0; j<ao->___cachedCode___; j++) {
3093 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3103 void toiNext(struct tagobjectiterator *it,
3104 void ** objectarray OPTARG(int * failed)) {
3105 /* hasNext has all of the intelligence */
3108 /* Get object with tags */
3109 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3110 struct ___Object___ *tagptr=obj->___tags___;
3111 if (tagptr->type==TAGTYPE) {
3113 objectarray[it->slot]=tagptr;
3115 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3116 objectarray[it->slot]=
3117 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3119 } else if (it->numtags>0) {
3120 /* Use tags to locate appropriate objects */
3121 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3122 struct ___Object___ *objptr=tag->flagptr;
3123 if (objptr->type!=OBJECTARRAYTYPE) {
3125 objectarray[it->slot]=objptr;
3127 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3128 objectarray[it->slot]=
3129 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3132 /* Iterate object */
3133 objectarray[it->slot]=(void *)Objkey(&it->it);