3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5 #include "GenericHashtable.h"
7 // data structures for task invocation
8 struct genhashtable * activetasks;
9 struct taskparamdescriptor * currtpd;
11 // specific functions used inside critical sections
12 void enqueueObject_I(void * ptr,
13 struct parameterwrapper ** queues,
15 int enqueuetasks_I(struct parameterwrapper *parameter,
16 struct parameterwrapper *prevptr,
17 struct ___Object___ *ptr,
22 inline __attribute__((always_inline))
23 void setupsmemmode(void) {
25 bamboo_smem_mode = SMEMLOCAL;
27 bamboo_smem_mode = SMEMFIXED;
29 bamboo_smem_mode = SMEMMIXED;
31 bamboo_smem_mode = SMEMGLOBAL;
33 // defaultly using local mode
34 bamboo_smem_mode = SMEMLOCAL;
36 } // void setupsmemmode(void)
39 inline __attribute__((always_inline))
40 void initruntimedata() {
42 // initialize the arrays
43 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
44 // startup core to initialize corestatus[]
45 for(i = 0; i < NUMCORES; ++i) {
48 numreceiveobjs[i] = 0;
50 // initialize the profile data arrays
56 gcnumreceiveobjs[i] = 0;
58 gcrequiredmems[i] = 0;
60 gcfilledblocks[i] = 0;
62 } // for(i = 0; i < NUMCORES; ++i)
72 self_numreceiveobjs = 0;
74 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
79 msglength = BAMBOO_MSG_BUF_LENGTH;
80 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
90 bamboo_cur_msp = NULL;
92 totransobjqueue = createQueue();
97 gcphase = FINISHPHASE;
99 gcself_numsendobjs = 0;
100 gcself_numreceiveobjs = 0;
101 gcmarkedptrbound = 0;
102 gcpointertbl = allocateRuntimeHash(20);
114 gcsbstarttbl = BAMBOO_BASE_VA;
115 gcsmemtbl = RUNMALLOC_I(sizeof(int)*gcnumblock);
117 // create the lock table, lockresult table and obj queue
120 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
121 /* Set allocation blocks*/
122 locktable.listhead=NULL;
123 locktable.listtail=NULL;
125 locktable.numelements = 0;
130 lockRedirectTbl = allocateRuntimeHash(20);
131 objRedirectLockTbl = allocateRuntimeHash(20);
136 objqueue.head = NULL;
137 objqueue.tail = NULL;
143 //isInterrupt = true;
146 taskInfoOverflow = false;
147 /*interruptInfoIndex = 0;
148 interruptInfoOverflow = false;*/
152 inline __attribute__((always_inline))
153 void disruntimedata() {
155 freeRuntimeHash(gcpointertbl);
157 freeRuntimeHash(lockRedirectTbl);
158 freeRuntimeHash(objRedirectLockTbl);
159 RUNFREE(locktable.bucket);
161 genfreehashtable(activetasks);
162 if(currtpd != NULL) {
163 RUNFREE(currtpd->parameterArray);
169 inline __attribute__((always_inline))
170 bool checkObjQueue() {
172 struct transObjInfo * objInfo = NULL;
176 #ifdef ACCURATEPROFILE
177 bool isChecking = false;
178 if(!isEmpty(&objqueue)) {
179 profileTaskStart("objqueue checking");
181 } // if(!isEmpty(&objqueue))
185 while(!isEmpty(&objqueue)) {
187 BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE();
189 BAMBOO_DEBUGPRINT(0xf001);
192 //isInterrupt = false;
195 BAMBOO_DEBUGPRINT(0xeee1);
198 objInfo = (struct transObjInfo *)getItem(&objqueue);
199 obj = objInfo->objptr;
201 BAMBOO_DEBUGPRINT_REG((int)obj);
203 // grab lock and flush the obj
207 BAMBOO_WAITING_FOR_LOCK();
208 } // while(!lockflag)
211 BAMBOO_DEBUGPRINT_REG(grount);
226 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
227 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
228 classsize[((struct ___Object___ *)obj)->type]);
230 // enqueue the object
231 for(k = 0; k < objInfo->length; ++k) {
232 int taskindex = objInfo->queues[2 * k];
233 int paramindex = objInfo->queues[2 * k + 1];
234 struct parameterwrapper ** queues =
235 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
237 BAMBOO_DEBUGPRINT_REG(taskindex);
238 BAMBOO_DEBUGPRINT_REG(paramindex);
239 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
240 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
241 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
242 (long)obj, tmpptr->flag);
244 enqueueObject_I(obj, queues, 1);
246 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
248 } // for(k = 0; k < objInfo->length; ++k)
249 releasewritelock_I(obj);
250 RUNFREE(objInfo->queues);
254 // put it at the end of the queue if no update version in the queue
255 struct QueueItem * qitem = getHead(&objqueue);
256 struct QueueItem * prev = NULL;
257 while(qitem != NULL) {
258 struct transObjInfo * tmpinfo =
259 (struct transObjInfo *)(qitem->objectptr);
260 if(tmpinfo->objptr == obj) {
261 // the same object in the queue, which should be enqueued
262 // recently. Current one is outdate, do not re-enqueue it
263 RUNFREE(objInfo->queues);
268 } // if(tmpinfo->objptr == obj)
269 qitem = getNextQueueItem(prev);
270 } // while(qitem != NULL)
271 // try to execute active tasks already enqueued first
272 addNewItem_I(&objqueue, objInfo);
274 //isInterrupt = true;
277 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
279 BAMBOO_DEBUGPRINT(0xf000);
283 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
285 BAMBOO_DEBUGPRINT(0xf000);
287 } // while(!isEmpty(&objqueue))
290 #ifdef ACCURATEPROFILE
298 BAMBOO_DEBUGPRINT(0xee02);
303 inline __attribute__((always_inline))
304 void checkCoreStatus() {
305 bool allStall = false;
309 (waitconfirm && (numconfirm == 0))) {
311 BAMBOO_DEBUGPRINT(0xee04);
312 BAMBOO_DEBUGPRINT_REG(waitconfirm);
314 BAMBOO_START_CRITICAL_SECTION_STATUS();
316 BAMBOO_DEBUGPRINT(0xf001);
318 corestatus[BAMBOO_NUM_OF_CORE] = 0;
319 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
320 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
321 // check the status of all cores
324 BAMBOO_DEBUGPRINT_REG(NUMCORES);
326 for(i = 0; i < NUMCORES; ++i) {
328 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
330 if(corestatus[i] != 0) {
334 } // for(i = 0; i < NUMCORES; ++i)
336 // check if the sum of send objs and receive obj are the same
337 // yes->check if the info is the latest; no->go on executing
339 for(i = 0; i < NUMCORES; ++i) {
340 sumsendobj += numsendobjs[i];
342 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
344 } // for(i = 0; i < NUMCORES; ++i)
345 for(i = 0; i < NUMCORES; ++i) {
346 sumsendobj -= numreceiveobjs[i];
348 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
350 } // for(i = 0; i < NUMCORES; ++i)
351 if(0 == sumsendobj) {
353 // the first time found all cores stall
354 // send out status confirm msg to all other cores
355 // reset the corestatus array too
357 BAMBOO_DEBUGPRINT(0xee05);
359 corestatus[BAMBOO_NUM_OF_CORE] = 1;
360 for(i = 1; i < NUMCORES; ++i) {
362 // send status confirm msg to core i
363 send_msg_1(i, STATUSCONFIRM);
364 } // for(i = 1; i < NUMCORES; ++i)
366 numconfirm = NUMCORES - 1;
368 // all the core status info are the latest
369 // terminate; for profiling mode, send request to all
370 // other cores to pour out profiling data
372 BAMBOO_DEBUGPRINT(0xee06);
376 totalexetime = BAMBOO_GET_EXE_TIME();
378 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
379 BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
380 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
382 // profile mode, send msgs to other cores to request pouring
383 // out progiling data
385 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
387 BAMBOO_DEBUGPRINT(0xf000);
389 for(i = 1; i < NUMCORES; ++i) {
390 // send profile request msg to core i
391 send_msg_2(i, PROFILEOUTPUT, totalexetime);
392 } // for(i = 1; i < NUMCORES; ++i)
393 // pour profiling data on startup core
396 BAMBOO_START_CRITICAL_SECTION_STATUS();
398 BAMBOO_DEBUGPRINT(0xf001);
400 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
401 // check the status of all cores
404 BAMBOO_DEBUGPRINT_REG(NUMCORES);
406 for(i = 0; i < NUMCORES; ++i) {
408 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
410 if(profilestatus[i] != 0) {
414 } // for(i = 0; i < NUMCORES; ++i)
417 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
419 BAMBOO_DEBUGPRINT(0xf000);
429 terminate(); // All done.
430 } // if(!waitconfirm)
432 // still some objects on the fly on the network
433 // reset the waitconfirm and numconfirm
435 BAMBOO_DEBUGPRINT(0xee07);
439 } // if(0 == sumsendobj)
441 // not all cores are stall, keep on waiting
443 BAMBOO_DEBUGPRINT(0xee08);
448 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
450 BAMBOO_DEBUGPRINT(0xf000);
452 } // if((!waitconfirm) ||
455 // main function for each core
456 inline void run(void * arg) {
460 bool sendStall = false;
462 bool tocontinue = false;
464 corenum = BAMBOO_GET_NUM_OF_CORE();
466 BAMBOO_DEBUGPRINT(0xeeee);
467 BAMBOO_DEBUGPRINT_REG(corenum);
468 BAMBOO_DEBUGPRINT(STARTUPCORE);
471 // initialize runtime data structures
474 // other architecture related initialization
478 initializeexithandler();
480 // main process of the execution module
481 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
482 // non-executing cores, only processing communications
485 BAMBOO_DEBUGPRINT(0xee01);
486 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
487 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
488 profileTaskStart("msg handling");
492 //isInterrupt = false;
496 /* Create queue of active tasks */
498 genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
499 (int(*) (void *,void *)) &comparetpd);
501 /* Process task information */
504 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
505 /* Create startup object */
506 createstartupobject(argc, argv);
510 BAMBOO_DEBUGPRINT(0xee00);
515 // check if need to do GC
519 // check if there are new active tasks can be executed
526 while(receiveObject() != -1) {
531 BAMBOO_DEBUGPRINT(0xee01);
534 // check if there are some pending objects,
535 // if yes, enqueue them and executetasks again
536 tocontinue = checkObjQueue();
540 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
543 BAMBOO_DEBUGPRINT(0xee03);
551 BAMBOO_DEBUGPRINT(0xee09);
557 // wait for some time
560 BAMBOO_DEBUGPRINT(0xee0a);
566 // send StallMsg to startup core
568 BAMBOO_DEBUGPRINT(0xee0b);
571 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
572 self_numsendobjs, self_numreceiveobjs);
584 BAMBOO_DEBUGPRINT(0xee0c);
587 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
590 } // if(BAMBOO_NUM_OF_CORE > NUMCORES - 1)
594 struct ___createstartupobject____I_locals {
597 struct ___StartupObject___ * ___startupobject___;
598 struct ArrayObject * ___stringarray___;
599 }; // struct ___createstartupobject____I_locals
601 void createstartupobject(int argc,
605 /* Allocate startup object */
607 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
608 struct ___StartupObject___ *startupobject=
609 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
610 ___locals___.___startupobject___ = startupobject;
611 struct ArrayObject * stringarray=
612 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
613 ___locals___.___stringarray___ = stringarray;
615 struct ___StartupObject___ *startupobject=
616 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
617 struct ArrayObject * stringarray=
618 allocate_newarray(STRINGARRAYTYPE, argc-1);
620 /* Build array of strings */
621 startupobject->___parameters___=stringarray;
622 for(i=1; i<argc; i++) {
623 int length=strlen(argv[i]);
625 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
627 struct ___String___ *newstring=NewString(argv[i],length);
629 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
633 startupobject->version = 0;
634 startupobject->lock = NULL;
636 /* Set initialized flag for startup object */
637 flagorandinit(startupobject,1,0xFFFFFFFF);
638 enqueueObject(startupobject, NULL, 0);
640 BAMBOO_CACHE_FLUSH_ALL();
644 int hashCodetpd(struct taskparamdescriptor *ftd) {
645 int hash=(int)ftd->task;
647 for(i=0; i<ftd->numParameters; i++) {
648 hash^=(int)ftd->parameterArray[i];
653 int comparetpd(struct taskparamdescriptor *ftd1,
654 struct taskparamdescriptor *ftd2) {
656 if (ftd1->task!=ftd2->task)
658 for(i=0; i<ftd1->numParameters; i++)
659 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
664 /* This function sets a tag. */
666 void tagset(void *ptr,
667 struct ___Object___ * obj,
668 struct ___TagDescriptor___ * tagd) {
670 void tagset(struct ___Object___ * obj,
671 struct ___TagDescriptor___ * tagd) {
673 struct ArrayObject * ao=NULL;
674 struct ___Object___ * tagptr=obj->___tags___;
676 obj->___tags___=(struct ___Object___ *)tagd;
678 /* Have to check if it is already set */
679 if (tagptr->type==TAGTYPE) {
680 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
685 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
686 struct ArrayObject * ao=
687 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
688 obj=(struct ___Object___ *)ptrarray[2];
689 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
690 td=(struct ___TagDescriptor___ *) obj->___tags___;
692 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
695 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
696 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
697 obj->___tags___=(struct ___Object___ *) ao;
698 ao->___cachedCode___=2;
702 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
703 for(i=0; i<ao->___cachedCode___; i++) {
704 struct ___TagDescriptor___ * td=
705 ARRAYGET(ao, struct ___TagDescriptor___*, i);
710 if (ao->___cachedCode___<ao->___length___) {
711 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
712 ao->___cachedCode___++;
715 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
716 struct ArrayObject * aonew=
717 allocate_newarray(&ptrarray,TAGARRAYTYPE,
718 TAGARRAYINTERVAL+ao->___length___);
719 obj=(struct ___Object___ *)ptrarray[2];
720 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
721 ao=(struct ArrayObject *)obj->___tags___;
723 struct ArrayObject * aonew=
724 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
727 aonew->___cachedCode___=ao->___length___+1;
728 for(i=0; i<ao->___length___; i++) {
729 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
730 ARRAYGET(ao, struct ___TagDescriptor___*, i));
732 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
738 struct ___Object___ * tagset=tagd->flagptr;
741 } else if (tagset->type!=OBJECTARRAYTYPE) {
743 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
744 struct ArrayObject * ao=
745 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
746 obj=(struct ___Object___ *)ptrarray[2];
747 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
749 struct ArrayObject * ao=
750 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
752 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
753 ARRAYSET(ao, struct ___Object___ *, 1, obj);
754 ao->___cachedCode___=2;
755 tagd->flagptr=(struct ___Object___ *)ao;
757 struct ArrayObject *ao=(struct ArrayObject *) tagset;
758 if (ao->___cachedCode___<ao->___length___) {
759 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
763 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
764 struct ArrayObject * aonew=
765 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
766 OBJECTARRAYINTERVAL+ao->___length___);
767 obj=(struct ___Object___ *)ptrarray[2];
768 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
769 ao=(struct ArrayObject *)tagd->flagptr;
771 struct ArrayObject * aonew=
772 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
774 aonew->___cachedCode___=ao->___cachedCode___+1;
775 for(i=0; i<ao->___length___; i++) {
776 ARRAYSET(aonew, struct ___Object___*, i,
777 ARRAYGET(ao, struct ___Object___*, i));
779 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
780 tagd->flagptr=(struct ___Object___ *) aonew;
786 /* This function clears a tag. */
788 void tagclear(void *ptr,
789 struct ___Object___ * obj,
790 struct ___TagDescriptor___ * tagd) {
792 void tagclear(struct ___Object___ * obj,
793 struct ___TagDescriptor___ * tagd) {
795 /* We'll assume that tag is alway there.
796 Need to statically check for this of course. */
797 struct ___Object___ * tagptr=obj->___tags___;
799 if (tagptr->type==TAGTYPE) {
800 if ((struct ___TagDescriptor___ *)tagptr==tagd)
801 obj->___tags___=NULL;
803 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
805 for(i=0; i<ao->___cachedCode___; i++) {
806 struct ___TagDescriptor___ * td=
807 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
809 ao->___cachedCode___--;
810 if (i<ao->___cachedCode___)
811 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
812 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
813 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
814 if (ao->___cachedCode___==0)
815 obj->___tags___=NULL;
822 struct ___Object___ *tagset=tagd->flagptr;
823 if (tagset->type!=OBJECTARRAYTYPE) {
827 struct ArrayObject *ao=(struct ArrayObject *) tagset;
829 for(i=0; i<ao->___cachedCode___; i++) {
830 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
832 ao->___cachedCode___--;
833 if (i<ao->___cachedCode___)
834 ARRAYSET(ao, struct ___Object___ *, i,
835 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
836 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
837 if (ao->___cachedCode___==0)
848 /* This function allocates a new tag. */
850 struct ___TagDescriptor___ * allocate_tag(void *ptr,
852 struct ___TagDescriptor___ * v=
853 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
856 struct ___TagDescriptor___ * allocate_tag(int index) {
857 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
866 /* This function updates the flag for object ptr. It or's the flag
867 with the or mask and and's it with the andmask. */
869 void flagbody(struct ___Object___ *ptr,
871 struct parameterwrapper ** queues,
875 int flagcomp(const int *val1, const int *val2) {
876 return (*val1)-(*val2);
879 void flagorand(void * ptr,
882 struct parameterwrapper ** queues,
885 int oldflag=((int *)ptr)[1];
886 int flag=ormask|oldflag;
888 flagbody(ptr, flag, queues, length, false);
892 bool intflagorand(void * ptr,
896 int oldflag=((int *)ptr)[1];
897 int flag=ormask|oldflag;
899 if (flag==oldflag) /* Don't do anything */
902 flagbody(ptr, flag, NULL, 0, false);
908 void flagorandinit(void * ptr,
911 int oldflag=((int *)ptr)[1];
912 int flag=ormask|oldflag;
914 flagbody(ptr,flag,NULL,0,true);
917 void flagbody(struct ___Object___ *ptr,
919 struct parameterwrapper ** vqueues,
922 struct parameterwrapper * flagptr = NULL;
924 struct parameterwrapper ** queues = vqueues;
925 int length = vlength;
928 int * enterflags = NULL;
929 if((!isnew) && (queues == NULL)) {
930 if(BAMBOO_NUM_OF_CORE < NUMCORES) {
931 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
932 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
939 /*Remove object from all queues */
940 for(i = 0; i < length; ++i) {
942 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
943 (int *) &enterflags, &UNUSED, &UNUSED2);
944 ObjectHashremove(flagptr->objectset, (int)ptr);
945 if (enterflags!=NULL)
950 void enqueueObject(void * vptr,
951 struct parameterwrapper ** vqueues,
953 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
956 //struct QueueItem *tmpptr;
957 struct parameterwrapper * parameter=NULL;
960 struct parameterwrapper * prevptr=NULL;
961 struct ___Object___ *tagptr=NULL;
962 struct parameterwrapper ** queues = vqueues;
963 int length = vlength;
964 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
968 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
969 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
971 tagptr=ptr->___tags___;
973 /* Outer loop iterates through all parameter queues an object of
974 this type could be in. */
975 for(j = 0; j < length; ++j) {
976 parameter = queues[j];
978 if (parameter->numbertags>0) {
980 goto nextloop; //that means the object has no tag
981 //but that param needs tag
982 else if(tagptr->type==TAGTYPE) { //one tag
983 //struct ___TagDescriptor___ * tag=
984 //(struct ___TagDescriptor___*) tagptr;
985 for(i=0; i<parameter->numbertags; i++) {
986 //slotid is parameter->tagarray[2*i];
987 int tagid=parameter->tagarray[2*i+1];
988 if (tagid!=tagptr->flag)
989 goto nextloop; /*We don't have this tag */
991 } else { //multiple tags
992 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
993 for(i=0; i<parameter->numbertags; i++) {
994 //slotid is parameter->tagarray[2*i];
995 int tagid=parameter->tagarray[2*i+1];
997 for(j=0; j<ao->___cachedCode___; j++) {
998 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1009 for(i=0; i<parameter->numberofterms; i++) {
1010 int andmask=parameter->intarray[i*2];
1011 int checkmask=parameter->intarray[i*2+1];
1012 if ((ptr->flag&andmask)==checkmask) {
1013 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1024 void enqueueObject_I(void * vptr,
1025 struct parameterwrapper ** vqueues,
1027 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1030 //struct QueueItem *tmpptr;
1031 struct parameterwrapper * parameter=NULL;
1034 struct parameterwrapper * prevptr=NULL;
1035 struct ___Object___ *tagptr=NULL;
1036 struct parameterwrapper ** queues = vqueues;
1037 int length = vlength;
1038 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1041 if(queues == NULL) {
1042 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1043 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1045 tagptr=ptr->___tags___;
1047 /* Outer loop iterates through all parameter queues an object of
1048 this type could be in. */
1049 for(j = 0; j < length; ++j) {
1050 parameter = queues[j];
1052 if (parameter->numbertags>0) {
1054 goto nextloop; //that means the object has no tag
1055 //but that param needs tag
1056 else if(tagptr->type==TAGTYPE) { //one tag
1057 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1058 for(i=0; i<parameter->numbertags; i++) {
1059 //slotid is parameter->tagarray[2*i];
1060 int tagid=parameter->tagarray[2*i+1];
1061 if (tagid!=tagptr->flag)
1062 goto nextloop; /*We don't have this tag */
1064 } else { //multiple tags
1065 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1066 for(i=0; i<parameter->numbertags; i++) {
1067 //slotid is parameter->tagarray[2*i];
1068 int tagid=parameter->tagarray[2*i+1];
1070 for(j=0; j<ao->___cachedCode___; j++) {
1071 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1082 for(i=0; i<parameter->numberofterms; i++) {
1083 int andmask=parameter->intarray[i*2];
1084 int checkmask=parameter->intarray[i*2+1];
1085 if ((ptr->flag&andmask)==checkmask) {
1086 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1098 int * getAliasLock(void ** ptrs,
1100 struct RuntimeHash * tbl) {
1102 return (int*)(RUNMALLOC(sizeof(int)));
1107 bool redirect = false;
1108 int redirectlock = 0;
1109 for(; i < length; i++) {
1110 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1113 if(ptr->lock == NULL) {
1116 lock = (int)(ptr->lock);
1119 if(lock != redirectlock) {
1120 RuntimeHashadd(tbl, lock, redirectlock);
1123 if(RuntimeHashcontainskey(tbl, lock)) {
1124 // already redirected
1126 RuntimeHashget(tbl, lock, &redirectlock);
1127 for(; j < locklen; j++) {
1128 if(locks[j] != redirectlock) {
1129 RuntimeHashadd(tbl, locks[j], redirectlock);
1134 for(j = 0; j < locklen; j++) {
1135 if(locks[j] == lock) {
1138 } else if(locks[j] > lock) {
1145 locks[h] = locks[h-1];
1154 return (int *)redirectlock;
1156 return (int *)(locks[0]);
1161 void addAliasLock(void * ptr,
1163 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1164 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1165 // originally no alias lock associated or have a different alias lock
1166 // flush it as the new one
1167 obj->lock = (int *)lock;
1172 inline void setTaskExitIndex(int index) {
1173 taskInfoArray[taskInfoIndex]->exitIndex = index;
1176 inline void addNewObjInfo(void * nobj) {
1177 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1178 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1180 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1185 struct freeMemItem * findFreeMemChunk(int coren,
1188 struct freeMemItem * freemem = bamboo_free_mem_list->head;
1189 struct freeMemItem * prev = NULL;
1192 *tofindb = gc_core2block[2*coren+i]+124*j;
1193 // check available shared mem chunks
1196 switch(bamboo_smem_mode) {
1198 int startb = freemem->startblock;
1199 int endb = freemem->endblock;
1200 while(startb > *tofindb) {
1206 *tofindb = gc_core2block[2*coren+i]+124*j;
1207 } // while(startb > tofindb)
1208 if(startb <= *tofindb) {
1209 if((endb >= *tofindb) && (freemem->size >= isize)) {
1211 } else if(*tofindb > gcnumblock-1) {
1212 // no more local mem
1214 } // if(endb >= tofindb)
1215 } // if(startb <= tofindb)
1220 int startb = freemem->startblock;
1221 int endb = freemem->endblock;
1222 if(startb <= *tofindb) {
1223 if((endb >= *tofindb) && (freemem->size >= isize)) {
1227 // use the global mem
1228 if(((startb > NUMCORES-1) && (freemem->size >= isize)) ||
1229 ((endb > NUMCORES-1) && ((freemem->size-
1230 (gcbaseva+BAMBOO_LARGE_SMEM_BOUND-freemem->ptr))>=isize))) {
1238 // TODO not supported yet
1239 BAMBOO_EXIT(0xe001);
1244 foundsmem = (freemem->size >= isize);
1251 if(1 == foundsmem) {
1254 } else if (2 == foundsmem) {
1255 // terminate, no more mem
1260 freemem = freemem->next;
1261 } while(freemem != NULL);
1264 } // struct freeMemItem * findFreeMemChunk(int, int, int *)
1266 void * localmalloc(int tofindb,
1268 struct freeMemItem * freemem,
1271 int startb = freemem->startblock;
1272 int endb = freemem->endblock;
1273 int tmpptr = gcbaseva+((tofindb<NUMCORES)?tofindb*BAMBOO_SMEM_SIZE_L
1274 :BAMBOO_LARGE_SMEM_BOUND+(tofindb-NUMCORES)*BAMBOO_SMEM_SIZE);
1275 if((freemem->size+freemem->ptr-tmpptr)>=isize) {
1276 mem = (tmpptr>freemem->ptr)?((void *)tmpptr):(freemem->ptr);
1278 mem = (void *)(freemem->size+freemem->ptr-isize);
1280 // check the remaining space in this block
1281 int remain = (int)(mem-gcbaseva);
1282 int bound = (BAMBOO_SMEM_SIZE);
1283 if(remain < BAMBOO_LARGE_SMEM_BOUND) {
1284 bound = (BAMBOO_SMEM_SIZE_L);
1286 remain = bound - remain%bound;
1287 if(remain < isize) {
1288 // this object acrosses blocks
1291 // round the asigned block to the end of the current block
1292 *allocsize = remain;
1294 if(freemem->ptr == (int)mem) {
1295 freemem->ptr = ((void*)freemem->ptr) + (*allocsize);
1296 freemem->size -= *allocsize;
1297 BLOCKINDEX(freemem->ptr, &(freemem->startblock));
1298 } else if((freemem->ptr+freemem->size) == ((int)mem+(*allocsize))) {
1299 freemem->size -= *allocsize;
1300 BLOCKINDEX(((int)mem)-1, &(freemem->endblock));
1302 struct freeMemItem * tmp =
1303 (struct freeMemItem *)RUNMALLOC(sizeof(struct freeMemItem));
1304 tmp->ptr = (int)mem+*allocsize;
1305 tmp->size = freemem->ptr+freemem->size-(int)mem-*allocsize;
1306 BLOCKINDEX(tmp->ptr, &(tmp->startblock));
1307 tmp->endblock = freemem->endblock;
1308 tmp->next = freemem->next;
1309 freemem->next = tmp;
1310 freemem->size = (int)mem - freemem->ptr;
1311 BLOCKINDEX(((int)mem-1), &(freemem->endblock));
1314 } // void * localmalloc(int, int, struct freeMemItem *, int *)
1316 void * globalmalloc(int isize,
1317 struct freeMemItem * freemem,
1319 void * mem = (void *)(freemem->ptr);
1320 // check the remaining space in this block
1321 int remain = (int)(mem-(BAMBOO_BASE_VA));
1322 int bound = (BAMBOO_SMEM_SIZE);
1323 if(remain < BAMBOO_LARGE_SMEM_BOUND) {
1324 bound = (BAMBOO_SMEM_SIZE_L);
1326 remain = bound - remain%bound;
1327 if(remain < isize) {
1328 // this object acrosses blocks
1331 // round the asigned block to the end of the current block
1332 *allocsize = remain;
1334 freemem->ptr = ((void*)freemem->ptr) + (*allocsize);
1335 freemem->size -= *allocsize;
1337 } // void * globalmalloc(int, struct freeMemItem *, int *)
1340 // malloc from the shared memory
1341 void * smemalloc(int coren,
1345 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1346 int toallocate = ((size+(BAMBOO_CACHE_LINE_SIZE))>(BAMBOO_SMEM_SIZE)) ?
1347 (size+(BAMBOO_CACHE_LINE_SIZE)):(BAMBOO_SMEM_SIZE);
1349 // go through free mem list for suitable chunks
1351 struct freeMemItem * freemem = findFreeMemChunk(coren, isize, &tofindb);
1353 // allocate shared mem if available
1354 if(freemem != NULL) {
1355 switch(bamboo_smem_mode) {
1357 mem = localmalloc(tofindb, isize, freemem, allocsize);
1362 int startb = freemem->startblock;
1363 int endb = freemem->endblock;
1364 if(startb > tofindb) {
1365 // malloc on global mem
1366 mem = globalmalloc(isize, freemem, allocsize);
1368 // malloc on local mem
1369 mem = localmalloc(tofindb, isize, freemem, allocsize);
1375 // TODO not supported yet
1376 BAMBOO_EXIT(0xe002);
1381 mem = globalmalloc(isize,freemem, allocsize);
1390 mem = mspace_calloc(bamboo_free_msp, 1, isize);
1394 // no enough shared global memory
1400 BAMBOO_DEBUGPRINT(0xa001);
1401 BAMBOO_EXIT(0xa001);
1405 } // void * smemalloc(int, int, int)
1407 // receive object transferred from other cores
1408 // or the terminate message from other cores
1409 // Should be invoked in critical sections!!
1410 // NOTICE: following format is for threadsimulate version only
1411 // RAW version please see previous description
1412 // format: type + object
1413 // type: -1--stall msg
1415 // return value: 0--received an object
1416 // 1--received nothing
1417 // 2--received a Stall Msg
1418 // 3--received a lock Msg
1419 // RAW version: -1 -- received nothing
1420 // otherwise -- received msg type
1421 int receiveObject() {
1425 if(receiveMsg() == -1) {
1429 if(msgdataindex == msglength) {
1430 // received a whole msg
1435 // receive a object transfer msg
1436 struct transObjInfo * transObj =
1437 RUNMALLOC_I(sizeof(struct transObjInfo));
1441 BAMBOO_DEBUGPRINT(0xe880);
1444 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1446 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1448 BAMBOO_EXIT(0xa002);
1450 // store the object and its corresponding queue info, enqueue it later
1451 transObj->objptr = (void *)msgdata[2];
1452 transObj->length = (msglength - 3) / 2;
1453 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1454 for(k = 0; k < transObj->length; ++k) {
1455 transObj->queues[2*k] = msgdata[3+2*k];
1458 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1461 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1464 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1468 // check if there is an existing duplicate item
1470 struct QueueItem * qitem = getHead(&objqueue);
1471 struct QueueItem * prev = NULL;
1472 while(qitem != NULL) {
1473 struct transObjInfo * tmpinfo =
1474 (struct transObjInfo *)(qitem->objectptr);
1475 if(tmpinfo->objptr == transObj->objptr) {
1476 // the same object, remove outdate one
1477 removeItem(&objqueue, qitem);
1483 qitem = getHead(&objqueue);
1485 qitem = getNextQueueItem(prev);
1488 addNewItem_I(&objqueue, (void *)transObj);
1490 ++(self_numreceiveobjs);
1495 // receive a stall msg
1496 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1497 // non startup core can not receive stall msg
1499 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1501 BAMBOO_EXIT(0xa003);
1503 if(msgdata[1] < NUMCORES) {
1506 BAMBOO_DEBUGPRINT(0xe881);
1509 corestatus[msgdata[1]] = 0;
1510 numsendobjs[msgdata[1]] = msgdata[2];
1511 numreceiveobjs[msgdata[1]] = msgdata[3];
1516 // GC version have no lock msgs
1517 #ifndef MULTICORE_GC
1519 // receive lock request msg, handle it right now
1520 // check to see if there is a lock exist for the required obj
1521 // msgdata[1] -> lock type
1522 int data2 = msgdata[2]; // obj pointer
1523 int data3 = msgdata[3]; // lock
1524 int data4 = msgdata[4]; // request core
1525 // -1: redirected, 0: approved, 1: denied
1526 deny = processlockrequest(msgdata[1], data3, data2,
1527 data4, data4, true);
1529 // this lock request is redirected
1532 // send response msg
1533 // for 32 bit machine, the size is always 4 words
1534 int tmp = deny==1?LOCKDENY:LOCKGROUNT;
1536 cache_msg_4(data4, tmp, msgdata[1], data2, data3);
1538 send_msg_4(data4, tmp, msgdata[1], data2, data3);
1545 // receive lock grount msg
1546 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1548 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1550 BAMBOO_EXIT(0xa004);
1552 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1555 BAMBOO_DEBUGPRINT(0xe882);
1564 // conflicts on lockresults
1566 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1568 BAMBOO_EXIT(0xa005);
1574 // receive lock deny msg
1575 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1577 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1579 BAMBOO_EXIT(0xa006);
1581 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1584 BAMBOO_DEBUGPRINT(0xe883);
1593 // conflicts on lockresults
1595 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1597 BAMBOO_EXIT(0xa007);
1603 // receive lock release msg
1604 processlockrelease(msgdata[1], msgdata[2], 0, false);
1610 case PROFILEOUTPUT: {
1611 // receive an output profile data request msg
1612 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1613 // startup core can not receive profile output finish msg
1614 BAMBOO_EXIT(0xa008);
1618 BAMBOO_DEBUGPRINT(0xe885);
1622 totalexetime = msgdata[1];
1623 outputProfileData();
1625 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1627 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1632 case PROFILEFINISH: {
1633 // receive a profile output finish msg
1634 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1635 // non startup core can not receive profile output finish msg
1637 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1639 BAMBOO_EXIT(0xa009);
1643 BAMBOO_DEBUGPRINT(0xe886);
1646 profilestatus[msgdata[1]] = 0;
1651 // GC version has no lock msgs
1652 #ifndef MULTICORE_GC
1653 case REDIRECTLOCK: {
1654 // receive a redirect lock request msg, handle it right now
1655 // check to see if there is a lock exist for the required obj
1656 int data1 = msgdata[1]; // lock type
1657 int data2 = msgdata[2]; // obj pointer
1658 int data3 = msgdata[3]; // redirect lock
1659 int data4 = msgdata[4]; // root request core
1660 int data5 = msgdata[5]; // request core
1661 deny = processlockrequest(msgdata[1], data3, data2, data5, data4, true);
1663 // this lock request is redirected
1666 // send response msg
1667 // for 32 bit machine, the size is always 4 words
1669 cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1670 data1, data2, data3);
1672 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1673 data1, data2, data3);
1679 case REDIRECTGROUNT: {
1680 // receive a lock grant msg with redirect info
1681 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1683 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1685 BAMBOO_EXIT(0xa00a);
1687 if(lockobj == msgdata[2]) {
1690 BAMBOO_DEBUGPRINT(0xe891);
1695 RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1700 // conflicts on lockresults
1702 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1704 BAMBOO_EXIT(0xa00b);
1709 case REDIRECTDENY: {
1710 // receive a lock deny msg with redirect info
1711 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
1713 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1715 BAMBOO_EXIT(0xa00c);
1717 if(lockobj == msgdata[2]) {
1720 BAMBOO_DEBUGPRINT(0xe892);
1729 // conflicts on lockresults
1731 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1733 BAMBOO_EXIT(0xa00d);
1738 case REDIRECTRELEASE: {
1739 // receive a lock release msg with redirect info
1740 processlockrelease(msgdata[1], msgdata[2], msgdata[3], true);
1745 case STATUSCONFIRM: {
1746 // receive a status confirm info
1747 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1748 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
1749 // wrong core to receive such msg
1750 BAMBOO_EXIT(0xa00e);
1752 // send response msg
1755 BAMBOO_DEBUGPRINT(0xe887);
1759 cache_msg_5(STARTUPCORE, STATUSREPORT,
1760 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1761 self_numsendobjs, self_numreceiveobjs);
1763 send_msg_5(STARTUPCORE, STATUSREPORT,
1764 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1765 self_numsendobjs, self_numreceiveobjs);
1771 case STATUSREPORT: {
1772 // receive a status confirm info
1773 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1774 // wrong core to receive such msg
1776 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1778 BAMBOO_EXIT(0xa00f);
1782 BAMBOO_DEBUGPRINT(0xe888);
1788 corestatus[msgdata[2]] = msgdata[1];
1789 numsendobjs[msgdata[2]] = msgdata[3];
1790 numreceiveobjs[msgdata[2]] = msgdata[4];
1796 // receive a terminate msg
1799 BAMBOO_DEBUGPRINT(0xe889);
1808 // receive a shared memory request msg
1809 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1810 // wrong core to receive such msg
1812 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1814 BAMBOO_EXIT(0xa010);
1818 BAMBOO_DEBUGPRINT(0xe88a);
1823 // is currently doing gc, dump this msg
1828 void * mem = smemalloc(msgdata[2], msgdata[1], &allocsize);
1832 // send the start_va to request core
1834 cache_msg_3(msgdata[2], MEMRESPONSE, mem, allocsize);
1836 send_msg_3( msgdata[2], MEMRESPONSE, mem, allocsize);
1843 // receive a shared memory response msg
1846 BAMBOO_DEBUGPRINT(0xe88b);
1851 // is currently doing gc, dump this msg
1855 if(msgdata[2] == 0) {
1856 bamboo_smem_size = 0;
1859 // fill header to store the size of this mem block
1860 (*((int*)msgdata[1])) = msgdata[2];
1861 bamboo_smem_size = msgdata[2] - BAMBOO_CACHE_LINE_SIZE;
1863 bamboo_cur_msp = msgdata[1] + BAMBOO_CACHE_LINE_SIZE;
1866 create_mspace_with_base((void*)(msgdata[1]+BAMBOO_CACHE_LINE_SIZE),
1867 msgdata[2]-BAMBOO_CACHE_LINE_SIZE,
1879 gcphase = INITPHASE;
1881 // is waiting for response of mem request
1882 // let it return NULL and start gc
1883 bamboo_smem_size = 0;
1884 bamboo_cur_msp = NULL;
1891 // receive a start GC msg
1894 BAMBOO_DEBUGPRINT(0xe88c);
1898 gcphase = MARKPHASE;
1902 case GCSTARTCOMPACT: {
1903 // a compact phase start msg
1904 gcblock2fill = msgdata[1];
1905 gcphase = COMPACTPHASE;
1909 case GCSTARTFLUSH: {
1910 // received a flush phase start msg
1911 gcphase = FLUSHPHASE;
1915 case GCFINISHINIT: {
1916 // received a init phase finish msg
1917 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1918 // non startup core can not receive this msg
1920 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1922 BAMBOO_EXIT(0xb001);
1925 BAMBOO_DEBUGPRINT(0xe88c);
1926 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1928 if(msgdata[1] < NUMCORES) {
1929 gccorestatus[msgdata[1]] = 0;
1933 case GCFINISHMARK: {
1934 // received a mark phase finish msg
1935 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1936 // non startup core can not receive this msg
1938 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1940 BAMBOO_EXIT(0xb002);
1942 if(msgdata[1] < NUMCORES) {
1943 gccorestatus[msgdata[1]] = 0;
1944 gcnumsendobjs[msgdata[1]] = msgdata[2];
1945 gcnumreceiveobjs[msgdata[1]] = msgdata[3];
1950 case GCFINISHCOMPACT: {
1951 // received a compact phase finish msg
1952 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1953 // non startup core can not receive this msg
1956 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1958 BAMBOO_EXIT(0xb003);
1960 int cnum = msgdata[1];
1961 int filledblocks = msgdata[2];
1962 int heaptop = msgdata[3];
1963 int data4 = msgdata[4];
1964 if(cnum < NUMCORES) {
1965 if(COMPACTPHASE == gcphase) {
1966 gcfilledblocks[cnum] = filledblocks;
1967 gcloads[cnum] = heaptop;
1974 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
1976 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
1978 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
1982 gccorestatus[cnum] = 0;
1983 // check if there is pending move request
1984 /*if(gcmovepending > 0) {
1986 for(j = 0; j < NUMCORES; j++) {
1987 if(gcrequiredmems[j]>0) {
1995 gcrequiredmems[j] = assignSpareMem_I(cnum,
1999 if(STARTUPCORE == j) {
2002 gcmovestartaddr = startaddr;
2003 gcblock2fill = tomove;
2006 cache_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
2008 send_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
2010 } // if(STARTUPCORE == j)
2011 if(gcrequiredmems[j] == 0) {
2014 } // if(j < NUMCORES)
2015 } // if(gcmovepending > 0) */
2017 } // if(cnum < NUMCORES)
2021 case GCFINISHFLUSH: {
2022 // received a flush phase finish msg
2023 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2024 // non startup core can not receive this msg
2027 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2029 BAMBOO_EXIT(0xb004);
2031 if(msgdata[1] < NUMCORES) {
2032 gccorestatus[msgdata[1]] = 0;
2038 // received a GC finish msg
2039 gcphase = FINISHPHASE;
2043 case GCMARKCONFIRM: {
2044 // received a marked phase finish confirm request msg
2045 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2046 || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
2047 // wrong core to receive such msg
2048 BAMBOO_EXIT(0xb005);
2050 // send response msg
2052 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2053 gcbusystatus, gcself_numsendobjs,
2054 gcself_numreceiveobjs);
2056 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2057 gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
2063 case GCMARKREPORT: {
2064 // received a marked phase finish confirm response msg
2065 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2066 // wrong core to receive such msg
2068 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2070 BAMBOO_EXIT(0xb006);
2075 gccorestatus[msgdata[1]] = msgdata[2];
2076 gcnumsendobjs[msgdata[1]] = msgdata[3];
2077 gcnumreceiveobjs[msgdata[1]] = msgdata[4];
2083 // received a markedObj msg
2084 gc_enqueue_I(msgdata[1]);
2085 gcself_numreceiveobjs++;
2086 gcbusystatus = true;
2091 // received a start moving objs msg
2093 gcdstcore = msgdata[1];
2094 gcmovestartaddr = msgdata[2];
2095 gcblock2fill = msgdata[3];
2099 case GCMAPREQUEST: {
2100 // received a mapping info request msg
2101 void * dstptr = NULL;
2102 RuntimeHashget(gcpointertbl, msgdata[1], &dstptr);
2103 if(NULL == dstptr) {
2104 // no such pointer in this core, something is wrong
2106 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2107 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2109 BAMBOO_EXIT(0xb007);
2111 // send back the mapping info
2113 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
2115 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
2122 // received a mapping info response msg
2123 if(msgdata[1] != gcobj2map) {
2124 // obj not matched, something is wrong
2126 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2127 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2129 BAMBOO_EXIT(0xb008);
2131 gcmappedobj = msgdata[2];
2132 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2138 case GCLOBJREQUEST: {
2139 // received a large objs info request msg
2140 transferMarkResults_I();
2145 // received a large objs info response msg
2148 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2150 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2152 BAMBOO_EXIT(0xb009);
2154 // store the mark result info
2155 int cnum = msgdata[2];
2156 gcloads[cnum] = msgdata[3];
2157 if(gcheaptop < msgdata[4]) {
2158 gcheaptop = msgdata[4];
2160 // large obj info here
2161 for(int k = 5; k < msgdata[1];) {
2162 int lobj = msgdata[k++];
2163 int length = msgdata[k++];
2164 gc_lobjenqueue_I(lobj, length, cnum);
2166 } // for(int k = 5; k < msgdata[1];)
2170 case GCLOBJMAPPING: {
2171 // received a large obj mapping info msg
2172 RuntimeHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2181 for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
2182 msgdata[msgdataindex] = -1;
2188 BAMBOO_DEBUGPRINT(0xe88d);
2192 if(BAMBOO_MSG_AVAIL() != 0) {
2205 BAMBOO_DEBUGPRINT(0xe88e);
2209 /* if(isInterrupt) {
2217 int enqueuetasks(struct parameterwrapper *parameter,
2218 struct parameterwrapper *prevptr,
2219 struct ___Object___ *ptr,
2221 int numenterflags) {
2222 void * taskpointerarray[MAXTASKPARAMS];
2224 //int numparams=parameter->task->numParameters;
2225 int numiterators=parameter->task->numTotal-1;
2228 struct taskdescriptor * task=parameter->task;
2230 //this add the object to parameterwrapper
2231 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
2232 numenterflags, enterflags==NULL);
2234 /* Add enqueued object to parameter vector */
2235 taskpointerarray[parameter->slot]=ptr;
2237 /* Reset iterators */
2238 for(j=0; j<numiterators; j++) {
2239 toiReset(¶meter->iterators[j]);
2242 /* Find initial state */
2243 for(j=0; j<numiterators; j++) {
2245 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2246 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2248 /* Need to backtrack */
2249 toiReset(¶meter->iterators[j]);
2253 /* Nothing to enqueue */
2259 /* Enqueue current state */
2261 struct taskparamdescriptor *tpd=
2262 RUNMALLOC(sizeof(struct taskparamdescriptor));
2264 tpd->numParameters=numiterators+1;
2265 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2267 for(j=0; j<=numiterators; j++) {
2268 //store the actual parameters
2269 tpd->parameterArray[j]=taskpointerarray[j];
2272 if ((/*!gencontains(failedtasks, tpd)&&*/
2273 !gencontains(activetasks,tpd))) {
2274 genputtable(activetasks, tpd, tpd);
2276 RUNFREE(tpd->parameterArray);
2280 /* This loop iterates to the next parameter combination */
2281 if (numiterators==0)
2284 for(j=numiterators-1; j<numiterators; j++) {
2286 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2287 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2289 /* Need to backtrack */
2290 toiReset(¶meter->iterators[j]);
2294 /* Nothing more to enqueue */
2302 int enqueuetasks_I(struct parameterwrapper *parameter,
2303 struct parameterwrapper *prevptr,
2304 struct ___Object___ *ptr,
2306 int numenterflags) {
2307 void * taskpointerarray[MAXTASKPARAMS];
2309 //int numparams=parameter->task->numParameters;
2310 int numiterators=parameter->task->numTotal-1;
2315 struct taskdescriptor * task=parameter->task;
2317 //this add the object to parameterwrapper
2318 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2319 numenterflags, enterflags==NULL);
2321 /* Add enqueued object to parameter vector */
2322 taskpointerarray[parameter->slot]=ptr;
2324 /* Reset iterators */
2325 for(j=0; j<numiterators; j++) {
2326 toiReset(¶meter->iterators[j]);
2329 /* Find initial state */
2330 for(j=0; j<numiterators; j++) {
2332 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2333 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2335 /* Need to backtrack */
2336 toiReset(¶meter->iterators[j]);
2340 /* Nothing to enqueue */
2346 /* Enqueue current state */
2348 struct taskparamdescriptor *tpd=
2349 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2351 tpd->numParameters=numiterators+1;
2352 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2354 for(j=0; j<=numiterators; j++) {
2355 //store the actual parameters
2356 tpd->parameterArray[j]=taskpointerarray[j];
2359 if ((/*!gencontains(failedtasks, tpd)&&*/
2360 !gencontains(activetasks,tpd))) {
2361 genputtable_I(activetasks, tpd, tpd);
2363 RUNFREE(tpd->parameterArray);
2367 /* This loop iterates to the next parameter combination */
2368 if (numiterators==0)
2371 for(j=numiterators-1; j<numiterators; j++) {
2373 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2374 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2376 /* Need to backtrack */
2377 toiReset(¶meter->iterators[j]);
2381 /* Nothing more to enqueue */
2395 int containstag(struct ___Object___ *ptr,
2396 struct ___TagDescriptor___ *tag);
2398 #ifndef MULTICORE_GC
2399 void releasewritelock_r(void * lock, void * redirectlock) {
2401 int reallock = (int)lock;
2402 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2405 BAMBOO_DEBUGPRINT(0xe671);
2406 BAMBOO_DEBUGPRINT_REG((int)lock);
2407 BAMBOO_DEBUGPRINT_REG(reallock);
2408 BAMBOO_DEBUGPRINT_REG(targetcore);
2411 if(targetcore == BAMBOO_NUM_OF_CORE) {
2412 BAMBOO_START_CRITICAL_SECTION_LOCK();
2414 BAMBOO_DEBUGPRINT(0xf001);
2416 // reside on this core
2417 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2418 // no locks for this object, something is wrong
2419 BAMBOO_EXIT(0xa011);
2422 struct LockValue * lockvalue = NULL;
2424 BAMBOO_DEBUGPRINT(0xe672);
2426 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2427 lockvalue = (struct LockValue *)rwlock_obj;
2429 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2432 lockvalue->redirectlock = (int)redirectlock;
2434 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2437 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2439 BAMBOO_DEBUGPRINT(0xf000);
2443 // send lock release with redirect info msg
2444 // for 32 bit machine, the size is always 4 words
2445 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
2450 void executetasks() {
2451 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2454 struct ___Object___ * tmpparam = NULL;
2455 struct parameterdescriptor * pd=NULL;
2456 struct parameterwrapper *pw=NULL;
2461 struct LockValue locks[MAXTASKPARAMS];
2468 while(hashsize(activetasks)>0) {
2473 BAMBOO_DEBUGPRINT(0xe990);
2476 /* See if there are any active tasks */
2477 if (hashsize(activetasks)>0) {
2480 #ifdef ACCURATEPROFILE
2481 profileTaskStart("tpd checking");
2485 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2486 genfreekey(activetasks, currtpd);
2488 numparams=currtpd->task->numParameters;
2489 numtotal=currtpd->task->numTotal;
2491 // clear the lockRedirectTbl
2492 // (TODO, this table should be empty after all locks are released)
2494 for(j = 0; j < MAXTASKPARAMS; j++) {
2495 locks[j].redirectlock = 0;
2498 // get all required locks
2500 // check which locks are needed
2501 for(i = 0; i < numparams; i++) {
2502 void * param = currtpd->parameterArray[i];
2506 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2508 taskpointerarray[i+OFFSET]=param;
2511 if(((struct ___Object___ *)param)->lock == NULL) {
2512 tmplock = (int)param;
2514 tmplock = (int)(((struct ___Object___ *)param)->lock);
2516 // insert into the locks array
2517 for(j = 0; j < locklen; j++) {
2518 if(locks[j].value == tmplock) {
2521 } else if(locks[j].value > tmplock) {
2528 locks[h].redirectlock = locks[h-1].redirectlock;
2529 locks[h].value = locks[h-1].value;
2531 locks[j].value = tmplock;
2532 locks[j].redirectlock = (int)param;
2535 } // line 2713: for(i = 0; i < numparams; i++)
2536 // grab these required locks
2538 BAMBOO_DEBUGPRINT(0xe991);
2540 for(i = 0; i < locklen; i++) {
2541 int * lock = (int *)(locks[i].redirectlock);
2543 // require locks for this parameter if it is not a startup object
2545 BAMBOO_DEBUGPRINT_REG((int)lock);
2546 BAMBOO_DEBUGPRINT_REG((int)(locks[i].value));
2549 BAMBOO_START_CRITICAL_SECTION();
2551 BAMBOO_DEBUGPRINT(0xf001);
2554 //isInterrupt = false;
2557 BAMBOO_WAITING_FOR_LOCK();
2561 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2565 grount = lockresult;
2575 //isInterrupt = true;
2577 BAMBOO_CLOSE_CRITICAL_SECTION();
2579 BAMBOO_DEBUGPRINT(0xf000);
2585 BAMBOO_DEBUGPRINT(0xe992);
2587 // can not get the lock, try later
2588 // releas all grabbed locks for previous parameters
2589 for(j = 0; j < i; ++j) {
2590 lock = (int*)(locks[j].redirectlock);
2591 releasewritelock(lock);
2593 genputtable(activetasks, currtpd, currtpd);
2594 if(hashsize(activetasks) == 1) {
2595 // only one task right now, wait a little while before next try
2601 #ifdef ACCURATEPROFILE
2602 // fail, set the end of the checkTaskInfo
2607 } // line 2794: if(grount == 0)
2608 } // line 2752: for(i = 0; i < locklen; i++)
2611 BAMBOO_DEBUGPRINT(0xe993);
2613 /* Make sure that the parameters are still in the queues */
2614 for(i=0; i<numparams; i++) {
2615 void * parameter=currtpd->parameterArray[i];
2619 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
2620 classsize[((struct ___Object___ *)parameter)->type]);
2622 tmpparam = (struct ___Object___ *)parameter;
2623 pd=currtpd->task->descriptorarray[i];
2624 pw=(struct parameterwrapper *) pd->queue;
2625 /* Check that object is still in queue */
2627 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2629 BAMBOO_DEBUGPRINT(0xe994);
2631 // release grabbed locks
2632 for(j = 0; j < locklen; ++j) {
2633 int * lock = (int *)(locks[j].redirectlock);
2634 releasewritelock(lock);
2636 RUNFREE(currtpd->parameterArray);
2642 /* Check if the object's flags still meets requirements */
2646 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2647 andmask=pw->intarray[tmpi*2];
2648 checkmask=pw->intarray[tmpi*2+1];
2649 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2655 // flags are never suitable
2656 // remove this obj from the queue
2658 int UNUSED, UNUSED2;
2661 BAMBOO_DEBUGPRINT(0xe995);
2663 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
2664 (int *) &enterflags, &UNUSED, &UNUSED2);
2665 ObjectHashremove(pw->objectset, (int)parameter);
2666 if (enterflags!=NULL)
2667 RUNFREE(enterflags);
2668 // release grabbed locks
2669 for(j = 0; j < locklen; ++j) {
2670 int * lock = (int *)(locks[j].redirectlock);
2671 releasewritelock(lock);
2673 RUNFREE(currtpd->parameterArray);
2677 #ifdef ACCURATEPROFILE
2678 // fail, set the end of the checkTaskInfo
2683 } // line 2878: if (!ismet)
2687 /* Check that object still has necessary tags */
2688 for(j=0; j<pd->numbertags; j++) {
2689 int slotid=pd->tagarray[2*j]+numparams;
2690 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2691 if (!containstag(parameter, tagd)) {
2693 BAMBOO_DEBUGPRINT(0xe996);
2696 // release grabbed locks
2698 for(tmpj = 0; tmpj < locklen; ++tmpj) {
2699 int * lock = (int *)(locks[tmpj].redirectlock);
2700 releasewritelock(lock);
2703 RUNFREE(currtpd->parameterArray);
2707 } // line2911: if (!containstag(parameter, tagd))
2708 } // line 2808: for(j=0; j<pd->numbertags; j++)
2710 taskpointerarray[i+OFFSET]=parameter;
2711 } // line 2824: for(i=0; i<numparams; i++)
2713 for(; i<numtotal; i++) {
2714 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2719 /* Actually call task */
2721 ((int *)taskpointerarray)[0]=currtpd->numParameters;
2722 taskpointerarray[1]=NULL;
2725 #ifdef ACCURATEPROFILE
2726 // check finish, set the end of the checkTaskInfo
2729 profileTaskStart(currtpd->task->name);
2733 BAMBOO_DEBUGPRINT(0xe997);
2735 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2737 #ifdef ACCURATEPROFILE
2738 // task finish, set the end of the checkTaskInfo
2740 // new a PostTaskInfo for the post-task execution
2741 profileTaskStart("post task execution");
2745 BAMBOO_DEBUGPRINT(0xe998);
2746 BAMBOO_DEBUGPRINT_REG(islock);
2751 BAMBOO_DEBUGPRINT(0xe999);
2753 for(i = 0; i < locklen; ++i) {
2754 void * ptr = (void *)(locks[i].redirectlock);
2755 int * lock = (int *)(locks[i].value);
2757 BAMBOO_DEBUGPRINT_REG((int)ptr);
2758 BAMBOO_DEBUGPRINT_REG((int)lock);
2760 #ifndef MULTICORE_GC
2761 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2763 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2764 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2765 releasewritelock_r(lock, (int *)redirectlock);
2770 releasewritelock(ptr);
2773 } // line 3015: if(islock)
2776 // post task execution finish, set the end of the postTaskInfo
2780 // Free up task parameter descriptor
2781 RUNFREE(currtpd->parameterArray);
2785 BAMBOO_DEBUGPRINT(0xe99a);
2788 } // if (hashsize(activetasks)>0)
2789 } // while(hashsize(activetasks)>0)
2791 BAMBOO_DEBUGPRINT(0xe99b);
2795 /* This function processes an objects tags */
2796 void processtags(struct parameterdescriptor *pd,
2798 struct parameterwrapper *parameter,
2799 int * iteratorcount,
2804 for(i=0; i<pd->numbertags; i++) {
2805 int slotid=pd->tagarray[2*i];
2806 int tagid=pd->tagarray[2*i+1];
2808 if (statusarray[slotid+numparams]==0) {
2809 parameter->iterators[*iteratorcount].istag=1;
2810 parameter->iterators[*iteratorcount].tagid=tagid;
2811 parameter->iterators[*iteratorcount].slot=slotid+numparams;
2812 parameter->iterators[*iteratorcount].tagobjectslot=index;
2813 statusarray[slotid+numparams]=1;
2820 void processobject(struct parameterwrapper *parameter,
2822 struct parameterdescriptor *pd,
2828 struct ObjectHash * objectset=
2829 ((struct parameterwrapper *)pd->queue)->objectset;
2831 parameter->iterators[*iteratorcount].istag=0;
2832 parameter->iterators[*iteratorcount].slot=index;
2833 parameter->iterators[*iteratorcount].objectset=objectset;
2834 statusarray[index]=1;
2836 for(i=0; i<pd->numbertags; i++) {
2837 int slotid=pd->tagarray[2*i];
2838 //int tagid=pd->tagarray[2*i+1];
2839 if (statusarray[slotid+numparams]!=0) {
2840 /* This tag has already been enqueued, use it to narrow search */
2841 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
2846 parameter->iterators[*iteratorcount].numtags=tagcount;
2851 /* This function builds the iterators for a task & parameter */
2853 void builditerators(struct taskdescriptor * task,
2855 struct parameterwrapper * parameter) {
2856 int statusarray[MAXTASKPARAMS];
2858 int numparams=task->numParameters;
2859 int iteratorcount=0;
2860 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
2862 statusarray[index]=1; /* Initial parameter */
2863 /* Process tags for initial iterator */
2865 processtags(task->descriptorarray[index], index, parameter,
2866 &iteratorcount, statusarray, numparams);
2870 /* Check for objects with existing tags */
2871 for(i=0; i<numparams; i++) {
2872 if (statusarray[i]==0) {
2873 struct parameterdescriptor *pd=task->descriptorarray[i];
2875 for(j=0; j<pd->numbertags; j++) {
2876 int slotid=pd->tagarray[2*j];
2877 if(statusarray[slotid+numparams]!=0) {
2878 processobject(parameter, i, pd, &iteratorcount, statusarray,
2880 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2887 /* Next do objects w/ unbound tags*/
2889 for(i=0; i<numparams; i++) {
2890 if (statusarray[i]==0) {
2891 struct parameterdescriptor *pd=task->descriptorarray[i];
2892 if (pd->numbertags>0) {
2893 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2894 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2900 /* Nothing with a tag enqueued */
2902 for(i=0; i<numparams; i++) {
2903 if (statusarray[i]==0) {
2904 struct parameterdescriptor *pd=task->descriptorarray[i];
2905 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2906 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2919 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2922 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2923 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2925 printf("%s\n", task->name);
2927 for(j=0; j<task->numParameters; j++) {
2928 struct parameterdescriptor *param=task->descriptorarray[j];
2929 struct parameterwrapper *parameter=param->queue;
2930 struct ObjectHash * set=parameter->objectset;
2931 struct ObjectIterator objit;
2933 printf(" Parameter %d\n", j);
2935 ObjectHashiterator(set, &objit);
2936 while(ObjhasNext(&objit)) {
2937 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
2938 struct ___Object___ * tagptr=obj->___tags___;
2939 int nonfailed=Objdata4(&objit);
2940 int numflags=Objdata3(&objit);
2941 int flags=Objdata2(&objit);
2944 printf(" Contains %lx\n", obj);
2945 printf(" flag=%d\n", obj->flag);
2948 } else if (tagptr->type==TAGTYPE) {
2950 printf(" tag=%lx\n",tagptr);
2956 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
2957 for(; tagindex<ao->___cachedCode___; tagindex++) {
2959 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
2972 /* This function processes the task information to create queues for
2973 each parameter type. */
2975 void processtasks() {
2977 if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
2980 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2981 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2984 /* Build objectsets */
2985 for(j=0; j<task->numParameters; j++) {
2986 struct parameterdescriptor *param=task->descriptorarray[j];
2987 struct parameterwrapper *parameter=param->queue;
2988 parameter->objectset=allocateObjectHash(10);
2989 parameter->task=task;
2992 /* Build iterators for parameters */
2993 for(j=0; j<task->numParameters; j++) {
2994 struct parameterdescriptor *param=task->descriptorarray[j];
2995 struct parameterwrapper *parameter=param->queue;
2996 builditerators(task, j, parameter);
3001 void toiReset(struct tagobjectiterator * it) {
3004 } else if (it->numtags>0) {
3007 ObjectHashiterator(it->objectset, &it->it);
3011 int toiHasNext(struct tagobjectiterator *it,
3012 void ** objectarray OPTARG(int * failed)) {
3015 /* Get object with tags */
3016 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3017 struct ___Object___ *tagptr=obj->___tags___;
3018 if (tagptr->type==TAGTYPE) {
3019 if ((it->tagobjindex==0)&& /* First object */
3020 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3025 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3026 int tagindex=it->tagobjindex;
3027 for(; tagindex<ao->___cachedCode___; tagindex++) {
3028 struct ___TagDescriptor___ *td=
3029 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3030 if (td->flag==it->tagid) {
3031 it->tagobjindex=tagindex; /* Found right type of tag */
3037 } else if (it->numtags>0) {
3038 /* Use tags to locate appropriate objects */
3039 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3040 struct ___Object___ *objptr=tag->flagptr;
3042 if (objptr->type!=OBJECTARRAYTYPE) {
3043 if (it->tagobjindex>0)
3045 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3047 for(i=1; i<it->numtags; i++) {
3048 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3049 if (!containstag(objptr,tag2))
3054 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3057 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
3058 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3059 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3061 for(i=1; i<it->numtags; i++) {
3062 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3063 if (!containstag(objptr,tag2))
3066 it->tagobjindex=tagindex;
3071 it->tagobjindex=tagindex;
3075 return ObjhasNext(&it->it);
3079 int containstag(struct ___Object___ *ptr,
3080 struct ___TagDescriptor___ *tag) {
3082 struct ___Object___ * objptr=tag->flagptr;
3083 if (objptr->type==OBJECTARRAYTYPE) {
3084 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3085 for(j=0; j<ao->___cachedCode___; j++) {
3086 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3096 void toiNext(struct tagobjectiterator *it,
3097 void ** objectarray OPTARG(int * failed)) {
3098 /* hasNext has all of the intelligence */
3101 /* Get object with tags */
3102 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3103 struct ___Object___ *tagptr=obj->___tags___;
3104 if (tagptr->type==TAGTYPE) {
3106 objectarray[it->slot]=tagptr;
3108 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3109 objectarray[it->slot]=
3110 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3112 } else if (it->numtags>0) {
3113 /* Use tags to locate appropriate objects */
3114 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3115 struct ___Object___ *objptr=tag->flagptr;
3116 if (objptr->type!=OBJECTARRAYTYPE) {
3118 objectarray[it->slot]=objptr;
3120 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3121 objectarray[it->slot]=
3122 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3125 /* Iterate object */
3126 objectarray[it->slot]=(void *)Objkey(&it->it);