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 < NUMCORESACTIVE; ++i) {
50 numreceiveobjs[i] = 0;
52 // initialize the profile data arrays
55 } // for(i = 0; i < NUMCORESACTIVE; ++i)
57 for(i = 0; i < NUMCORES4GC; ++i) {
60 gcnumreceiveobjs[i] = 0;
62 gcrequiredmems[i] = 0;
64 gcfilledblocks[i] = 0;
65 } // for(i = 0; i < NUMCORES4GC; ++i)
76 self_numreceiveobjs = 0;
78 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
82 msglength = BAMBOO_MSG_BUF_LENGTH;
83 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
93 bamboo_cur_msp = NULL;
95 totransobjqueue = createQueue();
100 gcphase = FINISHPHASE;
102 gcself_numsendobjs = 0;
103 gcself_numreceiveobjs = 0;
104 gcmarkedptrbound = 0;
105 //mgchashCreate(2000, 0.75);
106 gcpointertbl = allocateRuntimeHash(20);
107 //gcpointertbl = allocateMGCHash(20);
119 gcsbstarttbl = BAMBOO_BASE_VA;
120 gcsmemtbl = RUNMALLOC_I(sizeof(int)*gcnumblock);
122 // create the lock table, lockresult table and obj queue
125 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
126 /* Set allocation blocks*/
127 locktable.listhead=NULL;
128 locktable.listtail=NULL;
130 locktable.numelements = 0;
135 lockRedirectTbl = allocateRuntimeHash(20);
136 objRedirectLockTbl = allocateRuntimeHash(20);
141 objqueue.head = NULL;
142 objqueue.tail = NULL;
148 //isInterrupt = true;
151 taskInfoOverflow = false;
152 /*interruptInfoIndex = 0;
153 interruptInfoOverflow = false;*/
156 for(i = 0; i < MAXTASKPARAMS; i++) {
157 runtime_locks[i].redirectlock = 0;
158 runtime_locks[i].value = 0;
163 inline __attribute__((always_inline))
164 void disruntimedata() {
167 freeRuntimeHash(gcpointertbl);
168 //freeMGCHash(gcpointertbl);
169 if(gcsmemtbl != NULL) {
173 freeRuntimeHash(lockRedirectTbl);
174 freeRuntimeHash(objRedirectLockTbl);
175 RUNFREE(locktable.bucket);
177 if(activetasks != NULL) {
178 genfreehashtable(activetasks);
180 if(currtpd != NULL) {
181 RUNFREE(currtpd->parameterArray);
187 inline __attribute__((always_inline))
188 bool checkObjQueue() {
190 struct transObjInfo * objInfo = NULL;
194 #ifdef ACCURATEPROFILE
195 bool isChecking = false;
196 if(!isEmpty(&objqueue)) {
197 profileTaskStart("objqueue checking");
199 } // if(!isEmpty(&objqueue))
203 while(!isEmpty(&objqueue)) {
205 BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE();
207 BAMBOO_DEBUGPRINT(0xf001);
210 //isInterrupt = false;
213 BAMBOO_DEBUGPRINT(0xeee1);
216 objInfo = (struct transObjInfo *)getItem(&objqueue);
217 obj = objInfo->objptr;
219 BAMBOO_DEBUGPRINT_REG((int)obj);
221 // grab lock and flush the obj
225 BAMBOO_WAITING_FOR_LOCK();
226 } // while(!lockflag)
229 BAMBOO_DEBUGPRINT_REG(grount);
244 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
245 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
246 classsize[((struct ___Object___ *)obj)->type]);
248 // enqueue the object
249 for(k = 0; k < objInfo->length; ++k) {
250 int taskindex = objInfo->queues[2 * k];
251 int paramindex = objInfo->queues[2 * k + 1];
252 struct parameterwrapper ** queues =
253 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
255 BAMBOO_DEBUGPRINT_REG(taskindex);
256 BAMBOO_DEBUGPRINT_REG(paramindex);
257 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
258 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
259 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
260 (long)obj, tmpptr->flag);
262 enqueueObject_I(obj, queues, 1);
264 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
266 } // for(k = 0; k < objInfo->length; ++k)
267 releasewritelock_I(obj);
268 RUNFREE(objInfo->queues);
272 // put it at the end of the queue if no update version in the queue
273 struct QueueItem * qitem = getHead(&objqueue);
274 struct QueueItem * prev = NULL;
275 while(qitem != NULL) {
276 struct transObjInfo * tmpinfo =
277 (struct transObjInfo *)(qitem->objectptr);
278 if(tmpinfo->objptr == obj) {
279 // the same object in the queue, which should be enqueued
280 // recently. Current one is outdate, do not re-enqueue it
281 RUNFREE(objInfo->queues);
286 } // if(tmpinfo->objptr == obj)
287 qitem = getNextQueueItem(prev);
288 } // while(qitem != NULL)
289 // try to execute active tasks already enqueued first
290 addNewItem_I(&objqueue, objInfo);
292 //isInterrupt = true;
295 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
297 BAMBOO_DEBUGPRINT(0xf000);
301 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
303 BAMBOO_DEBUGPRINT(0xf000);
305 } // while(!isEmpty(&objqueue))
308 #ifdef ACCURATEPROFILE
316 BAMBOO_DEBUGPRINT(0xee02);
321 inline __attribute__((always_inline))
322 void checkCoreStatus() {
323 bool allStall = false;
327 (waitconfirm && (numconfirm == 0))) {
329 BAMBOO_DEBUGPRINT(0xee04);
330 BAMBOO_DEBUGPRINT_REG(waitconfirm);
332 BAMBOO_START_CRITICAL_SECTION_STATUS();
334 BAMBOO_DEBUGPRINT(0xf001);
336 corestatus[BAMBOO_NUM_OF_CORE] = 0;
337 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
338 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
339 // check the status of all cores
342 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
344 for(i = 0; i < NUMCORESACTIVE; ++i) {
346 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
348 if(corestatus[i] != 0) {
352 } // for(i = 0; i < NUMCORESACTIVE; ++i)
354 // check if the sum of send objs and receive obj are the same
355 // yes->check if the info is the latest; no->go on executing
357 for(i = 0; i < NUMCORESACTIVE; ++i) {
358 sumsendobj += numsendobjs[i];
360 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
362 } // for(i = 0; i < NUMCORESACTIVE; ++i)
363 for(i = 0; i < NUMCORESACTIVE; ++i) {
364 sumsendobj -= numreceiveobjs[i];
366 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
368 } // for(i = 0; i < NUMCORESACTIVE; ++i)
369 if(0 == sumsendobj) {
371 // the first time found all cores stall
372 // send out status confirm msg to all other cores
373 // reset the corestatus array too
375 BAMBOO_DEBUGPRINT(0xee05);
377 corestatus[BAMBOO_NUM_OF_CORE] = 1;
378 for(i = 1; i < NUMCORESACTIVE; ++i) {
380 // send status confirm msg to core i
381 send_msg_1(i, STATUSCONFIRM);
382 } // for(i = 1; i < NUMCORESACTIVE; ++i)
384 numconfirm = NUMCORESACTIVE - 1;
386 // all the core status info are the latest
387 // terminate; for profiling mode, send request to all
388 // other cores to pour out profiling data
390 BAMBOO_DEBUGPRINT(0xee06);
394 totalexetime = BAMBOO_GET_EXE_TIME();
396 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
397 BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
398 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
400 // profile mode, send msgs to other cores to request pouring
401 // out progiling data
403 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
405 BAMBOO_DEBUGPRINT(0xf000);
407 for(i = 1; i < NUMCORESACTIVE; ++i) {
408 // send profile request msg to core i
409 send_msg_2(i, PROFILEOUTPUT, totalexetime);
410 } // for(i = 1; i < NUMCORESACTIVE; ++i)
411 // pour profiling data on startup core
414 BAMBOO_START_CRITICAL_SECTION_STATUS();
416 BAMBOO_DEBUGPRINT(0xf001);
418 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
419 // check the status of all cores
422 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
424 for(i = 0; i < NUMCORESACTIVE; ++i) {
426 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
428 if(profilestatus[i] != 0) {
432 } // for(i = 0; i < NUMCORESACTIVE; ++i)
435 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
437 BAMBOO_DEBUGPRINT(0xf000);
447 terminate(); // All done.
448 } // if(!waitconfirm)
450 // still some objects on the fly on the network
451 // reset the waitconfirm and numconfirm
453 BAMBOO_DEBUGPRINT(0xee07);
457 } // if(0 == sumsendobj)
459 // not all cores are stall, keep on waiting
461 BAMBOO_DEBUGPRINT(0xee08);
466 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
468 BAMBOO_DEBUGPRINT(0xf000);
470 } // if((!waitconfirm) ||
473 // main function for each core
474 inline void run(void * arg) {
478 bool sendStall = false;
480 bool tocontinue = false;
482 corenum = BAMBOO_GET_NUM_OF_CORE();
484 BAMBOO_DEBUGPRINT(0xeeee);
485 BAMBOO_DEBUGPRINT_REG(corenum);
486 BAMBOO_DEBUGPRINT(STARTUPCORE);
489 // initialize runtime data structures
492 // other architecture related initialization
496 initializeexithandler();
498 // main process of the execution module
499 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
500 // non-executing cores, only processing communications
503 BAMBOO_DEBUGPRINT(0xee01);
504 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
505 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
506 profileTaskStart("msg handling");
510 //isInterrupt = false;
514 /* Create queue of active tasks */
516 genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
517 (int(*) (void *,void *)) &comparetpd);
519 /* Process task information */
522 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
523 /* Create startup object */
524 createstartupobject(argc, argv);
528 BAMBOO_DEBUGPRINT(0xee00);
533 // check if need to do GC
537 // check if there are new active tasks can be executed
544 while(receiveObject() != -1) {
549 BAMBOO_DEBUGPRINT(0xee01);
552 // check if there are some pending objects,
553 // if yes, enqueue them and executetasks again
554 tocontinue = checkObjQueue();
558 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
561 BAMBOO_DEBUGPRINT(0xee03);
569 BAMBOO_DEBUGPRINT(0xee09);
575 // wait for some time
578 BAMBOO_DEBUGPRINT(0xee0a);
584 // send StallMsg to startup core
586 BAMBOO_DEBUGPRINT(0xee0b);
589 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
590 self_numsendobjs, self_numreceiveobjs);
602 BAMBOO_DEBUGPRINT(0xee0c);
605 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
608 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
612 struct ___createstartupobject____I_locals {
615 struct ___StartupObject___ * ___startupobject___;
616 struct ArrayObject * ___stringarray___;
617 }; // struct ___createstartupobject____I_locals
619 void createstartupobject(int argc,
623 /* Allocate startup object */
625 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
626 struct ___StartupObject___ *startupobject=
627 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
628 ___locals___.___startupobject___ = startupobject;
629 struct ArrayObject * stringarray=
630 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
631 ___locals___.___stringarray___ = stringarray;
633 struct ___StartupObject___ *startupobject=
634 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
635 struct ArrayObject * stringarray=
636 allocate_newarray(STRINGARRAYTYPE, argc-1);
638 /* Build array of strings */
639 startupobject->___parameters___=stringarray;
640 for(i=1; i<argc; i++) {
641 int length=strlen(argv[i]);
643 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
645 struct ___String___ *newstring=NewString(argv[i],length);
647 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
651 startupobject->version = 0;
652 startupobject->lock = NULL;
654 /* Set initialized flag for startup object */
655 flagorandinit(startupobject,1,0xFFFFFFFF);
656 enqueueObject(startupobject, NULL, 0);
658 BAMBOO_CACHE_FLUSH_ALL();
662 int hashCodetpd(struct taskparamdescriptor *ftd) {
663 int hash=(int)ftd->task;
665 for(i=0; i<ftd->numParameters; i++) {
666 hash^=(int)ftd->parameterArray[i];
671 int comparetpd(struct taskparamdescriptor *ftd1,
672 struct taskparamdescriptor *ftd2) {
674 if (ftd1->task!=ftd2->task)
676 for(i=0; i<ftd1->numParameters; i++)
677 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
682 /* This function sets a tag. */
684 void tagset(void *ptr,
685 struct ___Object___ * obj,
686 struct ___TagDescriptor___ * tagd) {
688 void tagset(struct ___Object___ * obj,
689 struct ___TagDescriptor___ * tagd) {
691 struct ArrayObject * ao=NULL;
692 struct ___Object___ * tagptr=obj->___tags___;
694 obj->___tags___=(struct ___Object___ *)tagd;
696 /* Have to check if it is already set */
697 if (tagptr->type==TAGTYPE) {
698 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
703 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
704 struct ArrayObject * ao=
705 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
706 obj=(struct ___Object___ *)ptrarray[2];
707 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
708 td=(struct ___TagDescriptor___ *) obj->___tags___;
710 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
713 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
714 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
715 obj->___tags___=(struct ___Object___ *) ao;
716 ao->___cachedCode___=2;
720 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
721 for(i=0; i<ao->___cachedCode___; i++) {
722 struct ___TagDescriptor___ * td=
723 ARRAYGET(ao, struct ___TagDescriptor___*, i);
728 if (ao->___cachedCode___<ao->___length___) {
729 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
730 ao->___cachedCode___++;
733 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
734 struct ArrayObject * aonew=
735 allocate_newarray(&ptrarray,TAGARRAYTYPE,
736 TAGARRAYINTERVAL+ao->___length___);
737 obj=(struct ___Object___ *)ptrarray[2];
738 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
739 ao=(struct ArrayObject *)obj->___tags___;
741 struct ArrayObject * aonew=
742 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
745 aonew->___cachedCode___=ao->___length___+1;
746 for(i=0; i<ao->___length___; i++) {
747 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
748 ARRAYGET(ao, struct ___TagDescriptor___*, i));
750 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
756 struct ___Object___ * tagset=tagd->flagptr;
759 } else if (tagset->type!=OBJECTARRAYTYPE) {
761 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
762 struct ArrayObject * ao=
763 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
764 obj=(struct ___Object___ *)ptrarray[2];
765 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
767 struct ArrayObject * ao=
768 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
770 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
771 ARRAYSET(ao, struct ___Object___ *, 1, obj);
772 ao->___cachedCode___=2;
773 tagd->flagptr=(struct ___Object___ *)ao;
775 struct ArrayObject *ao=(struct ArrayObject *) tagset;
776 if (ao->___cachedCode___<ao->___length___) {
777 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
781 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
782 struct ArrayObject * aonew=
783 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
784 OBJECTARRAYINTERVAL+ao->___length___);
785 obj=(struct ___Object___ *)ptrarray[2];
786 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
787 ao=(struct ArrayObject *)tagd->flagptr;
789 struct ArrayObject * aonew=
790 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
792 aonew->___cachedCode___=ao->___cachedCode___+1;
793 for(i=0; i<ao->___length___; i++) {
794 ARRAYSET(aonew, struct ___Object___*, i,
795 ARRAYGET(ao, struct ___Object___*, i));
797 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
798 tagd->flagptr=(struct ___Object___ *) aonew;
804 /* This function clears a tag. */
806 void tagclear(void *ptr,
807 struct ___Object___ * obj,
808 struct ___TagDescriptor___ * tagd) {
810 void tagclear(struct ___Object___ * obj,
811 struct ___TagDescriptor___ * tagd) {
813 /* We'll assume that tag is alway there.
814 Need to statically check for this of course. */
815 struct ___Object___ * tagptr=obj->___tags___;
817 if (tagptr->type==TAGTYPE) {
818 if ((struct ___TagDescriptor___ *)tagptr==tagd)
819 obj->___tags___=NULL;
821 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
823 for(i=0; i<ao->___cachedCode___; i++) {
824 struct ___TagDescriptor___ * td=
825 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
827 ao->___cachedCode___--;
828 if (i<ao->___cachedCode___)
829 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
830 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
831 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
832 if (ao->___cachedCode___==0)
833 obj->___tags___=NULL;
840 struct ___Object___ *tagset=tagd->flagptr;
841 if (tagset->type!=OBJECTARRAYTYPE) {
845 struct ArrayObject *ao=(struct ArrayObject *) tagset;
847 for(i=0; i<ao->___cachedCode___; i++) {
848 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
850 ao->___cachedCode___--;
851 if (i<ao->___cachedCode___)
852 ARRAYSET(ao, struct ___Object___ *, i,
853 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
854 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
855 if (ao->___cachedCode___==0)
866 /* This function allocates a new tag. */
868 struct ___TagDescriptor___ * allocate_tag(void *ptr,
870 struct ___TagDescriptor___ * v=
871 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
874 struct ___TagDescriptor___ * allocate_tag(int index) {
875 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
884 /* This function updates the flag for object ptr. It or's the flag
885 with the or mask and and's it with the andmask. */
887 void flagbody(struct ___Object___ *ptr,
889 struct parameterwrapper ** queues,
893 int flagcomp(const int *val1, const int *val2) {
894 return (*val1)-(*val2);
897 void flagorand(void * ptr,
900 struct parameterwrapper ** queues,
903 int oldflag=((int *)ptr)[1];
904 int flag=ormask|oldflag;
906 flagbody(ptr, flag, queues, length, false);
910 bool intflagorand(void * ptr,
914 int oldflag=((int *)ptr)[1];
915 int flag=ormask|oldflag;
917 if (flag==oldflag) /* Don't do anything */
920 flagbody(ptr, flag, NULL, 0, false);
926 void flagorandinit(void * ptr,
929 int oldflag=((int *)ptr)[1];
930 int flag=ormask|oldflag;
932 flagbody(ptr,flag,NULL,0,true);
935 void flagbody(struct ___Object___ *ptr,
937 struct parameterwrapper ** vqueues,
940 struct parameterwrapper * flagptr = NULL;
942 struct parameterwrapper ** queues = vqueues;
943 int length = vlength;
946 int * enterflags = NULL;
947 if((!isnew) && (queues == NULL)) {
948 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
949 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
950 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
957 /*Remove object from all queues */
958 for(i = 0; i < length; ++i) {
960 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
961 (int *) &enterflags, &UNUSED, &UNUSED2);
962 ObjectHashremove(flagptr->objectset, (int)ptr);
963 if (enterflags!=NULL)
968 void enqueueObject(void * vptr,
969 struct parameterwrapper ** vqueues,
971 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
974 //struct QueueItem *tmpptr;
975 struct parameterwrapper * parameter=NULL;
978 struct parameterwrapper * prevptr=NULL;
979 struct ___Object___ *tagptr=NULL;
980 struct parameterwrapper ** queues = vqueues;
981 int length = vlength;
982 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
986 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
987 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
989 tagptr=ptr->___tags___;
991 /* Outer loop iterates through all parameter queues an object of
992 this type could be in. */
993 for(j = 0; j < length; ++j) {
994 parameter = queues[j];
996 if (parameter->numbertags>0) {
998 goto nextloop; //that means the object has no tag
999 //but that param needs tag
1000 else if(tagptr->type==TAGTYPE) { //one tag
1001 //struct ___TagDescriptor___ * tag=
1002 //(struct ___TagDescriptor___*) tagptr;
1003 for(i=0; i<parameter->numbertags; i++) {
1004 //slotid is parameter->tagarray[2*i];
1005 int tagid=parameter->tagarray[2*i+1];
1006 if (tagid!=tagptr->flag)
1007 goto nextloop; /*We don't have this tag */
1009 } else { //multiple tags
1010 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1011 for(i=0; i<parameter->numbertags; i++) {
1012 //slotid is parameter->tagarray[2*i];
1013 int tagid=parameter->tagarray[2*i+1];
1015 for(j=0; j<ao->___cachedCode___; j++) {
1016 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1027 for(i=0; i<parameter->numberofterms; i++) {
1028 int andmask=parameter->intarray[i*2];
1029 int checkmask=parameter->intarray[i*2+1];
1030 if ((ptr->flag&andmask)==checkmask) {
1031 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1042 void enqueueObject_I(void * vptr,
1043 struct parameterwrapper ** vqueues,
1045 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1048 //struct QueueItem *tmpptr;
1049 struct parameterwrapper * parameter=NULL;
1052 struct parameterwrapper * prevptr=NULL;
1053 struct ___Object___ *tagptr=NULL;
1054 struct parameterwrapper ** queues = vqueues;
1055 int length = vlength;
1056 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1059 if(queues == NULL) {
1060 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1061 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1063 tagptr=ptr->___tags___;
1065 /* Outer loop iterates through all parameter queues an object of
1066 this type could be in. */
1067 for(j = 0; j < length; ++j) {
1068 parameter = queues[j];
1070 if (parameter->numbertags>0) {
1072 goto nextloop; //that means the object has no tag
1073 //but that param needs tag
1074 else if(tagptr->type==TAGTYPE) { //one tag
1075 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1076 for(i=0; i<parameter->numbertags; i++) {
1077 //slotid is parameter->tagarray[2*i];
1078 int tagid=parameter->tagarray[2*i+1];
1079 if (tagid!=tagptr->flag)
1080 goto nextloop; /*We don't have this tag */
1082 } else { //multiple tags
1083 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1084 for(i=0; i<parameter->numbertags; i++) {
1085 //slotid is parameter->tagarray[2*i];
1086 int tagid=parameter->tagarray[2*i+1];
1088 for(j=0; j<ao->___cachedCode___; j++) {
1089 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1100 for(i=0; i<parameter->numberofterms; i++) {
1101 int andmask=parameter->intarray[i*2];
1102 int checkmask=parameter->intarray[i*2+1];
1103 if ((ptr->flag&andmask)==checkmask) {
1104 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1116 int * getAliasLock(void ** ptrs,
1118 struct RuntimeHash * tbl) {
1120 return (int*)(RUNMALLOC(sizeof(int)));
1125 bool redirect = false;
1126 int redirectlock = 0;
1127 for(; i < length; i++) {
1128 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1131 if(ptr->lock == NULL) {
1134 lock = (int)(ptr->lock);
1137 if(lock != redirectlock) {
1138 RuntimeHashadd(tbl, lock, redirectlock);
1141 if(RuntimeHashcontainskey(tbl, lock)) {
1142 // already redirected
1144 RuntimeHashget(tbl, lock, &redirectlock);
1145 for(; j < locklen; j++) {
1146 if(locks[j] != redirectlock) {
1147 RuntimeHashadd(tbl, locks[j], redirectlock);
1152 for(j = 0; j < locklen; j++) {
1153 if(locks[j] == lock) {
1156 } else if(locks[j] > lock) {
1163 locks[h] = locks[h-1];
1172 return (int *)redirectlock;
1174 return (int *)(locks[0]);
1179 void addAliasLock(void * ptr,
1181 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1182 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1183 // originally no alias lock associated or have a different alias lock
1184 // flush it as the new one
1185 obj->lock = (int *)lock;
1190 inline void setTaskExitIndex(int index) {
1191 taskInfoArray[taskInfoIndex]->exitIndex = index;
1194 inline void addNewObjInfo(void * nobj) {
1195 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1196 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1198 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1203 struct freeMemItem * findFreeMemChunk_I(int coren,
1206 struct freeMemItem * freemem = bamboo_free_mem_list->head;
1207 struct freeMemItem * prev = NULL;
1210 *tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1211 // check available shared mem chunks
1214 switch(bamboo_smem_mode) {
1216 int startb = freemem->startblock;
1217 int endb = freemem->endblock;
1218 while(startb > *tofindb) {
1224 *tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1225 } // while(startb > tofindb)
1226 if(startb <= *tofindb) {
1227 if((endb >= *tofindb) && (freemem->size >= isize)) {
1229 } else if(*tofindb > gcnumblock-1) {
1230 // no more local mem
1232 } // if(endb >= tofindb)
1233 } // if(startb <= tofindb)
1238 int startb = freemem->startblock;
1239 int endb = freemem->endblock;
1240 if(startb <= *tofindb) {
1241 if((endb >= *tofindb) && (freemem->size >= isize)) {
1245 // use the global mem
1246 if(((startb > NUMCORES4GC-1) && (freemem->size >= isize)) ||
1247 ((endb > NUMCORES4GC-1) && ((freemem->size-
1248 (gcbaseva+BAMBOO_LARGE_SMEM_BOUND-freemem->ptr))>=isize))) {
1256 // TODO not supported yet
1257 BAMBOO_EXIT(0xe001);
1262 foundsmem = (freemem->size >= isize);
1269 if(1 == foundsmem) {
1272 } else if (2 == foundsmem) {
1273 // terminate, no more mem
1277 if(freemem->size == 0) {
1278 // an empty item, remove it
1279 struct freeMemItem * toremove = freemem;
1280 freemem = freemem->next;
1283 bamboo_free_mem_list->head = freemem;
1285 prev->next = freemem;
1287 // put it to the tail of the list for reuse
1288 if(bamboo_free_mem_list->backuplist == NULL) {
1289 //toremove->next = bamboo_free_mem_list->backuplist;
1290 bamboo_free_mem_list->backuplist = toremove;
1291 bamboo_free_mem_list->backuplist->next = NULL;
1298 freemem = freemem->next;
1300 } while(freemem != NULL);
1303 } // struct freeMemItem * findFreeMemChunk_I(int, int, int *)
1305 void * localmalloc_I(int tofindb,
1307 struct freeMemItem * freemem,
1310 int startb = freemem->startblock;
1311 int endb = freemem->endblock;
1312 int tmpptr = gcbaseva+((tofindb<NUMCORES4GC)?tofindb*BAMBOO_SMEM_SIZE_L
1313 :BAMBOO_LARGE_SMEM_BOUND+(tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE);
1314 if((freemem->size+freemem->ptr-tmpptr)>=isize) {
1315 mem = (tmpptr>freemem->ptr)?((void *)tmpptr):(freemem->ptr);
1317 mem = (void *)(freemem->size+freemem->ptr-isize);
1319 // check the remaining space in this block
1320 int remain = (int)(mem-gcbaseva);
1321 int bound = (BAMBOO_SMEM_SIZE);
1322 if(remain < BAMBOO_LARGE_SMEM_BOUND) {
1323 bound = (BAMBOO_SMEM_SIZE_L);
1325 remain = bound - remain%bound;
1326 if(remain < isize) {
1327 // this object acrosses blocks
1330 // round the asigned block to the end of the current block
1331 *allocsize = remain;
1333 if(freemem->ptr == (int)mem) {
1334 freemem->ptr = ((void*)freemem->ptr) + (*allocsize);
1335 freemem->size -= *allocsize;
1336 BLOCKINDEX(freemem->ptr, &(freemem->startblock));
1337 } else if((freemem->ptr+freemem->size) == ((int)mem+(*allocsize))) {
1338 freemem->size -= *allocsize;
1339 BLOCKINDEX(((int)mem)-1, &(freemem->endblock));
1341 struct freeMemItem * tmp =
1342 (struct freeMemItem *)RUNMALLOC_I(sizeof(struct freeMemItem));
1343 tmp->ptr = (int)mem+*allocsize;
1344 tmp->size = freemem->ptr+freemem->size-(int)mem-*allocsize;
1345 BLOCKINDEX(tmp->ptr, &(tmp->startblock));
1346 tmp->endblock = freemem->endblock;
1347 tmp->next = freemem->next;
1348 freemem->next = tmp;
1349 freemem->size = (int)mem - freemem->ptr;
1350 BLOCKINDEX(((int)mem-1), &(freemem->endblock));
1353 } // void * localmalloc_I(int, int, struct freeMemItem *, int *)
1355 void * globalmalloc_I(int isize,
1356 struct freeMemItem * freemem,
1358 void * mem = (void *)(freemem->ptr);
1359 // check the remaining space in this block
1360 int remain = (int)(mem-(BAMBOO_BASE_VA));
1361 int bound = (BAMBOO_SMEM_SIZE);
1362 if(remain < BAMBOO_LARGE_SMEM_BOUND) {
1363 bound = (BAMBOO_SMEM_SIZE_L);
1365 remain = bound - remain%bound;
1366 if(remain < isize) {
1367 // this object acrosses blocks
1370 // round the asigned block to the end of the current block
1371 *allocsize = remain;
1373 freemem->ptr = ((void*)freemem->ptr) + (*allocsize);
1374 freemem->size -= *allocsize;
1376 } // void * globalmalloc_I(int, struct freeMemItem *, int *)
1379 // malloc from the shared memory
1380 void * smemalloc_I(int coren,
1385 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1386 int toallocate = (isize>(BAMBOO_SMEM_SIZE)) ? (isize):(BAMBOO_SMEM_SIZE);
1387 // go through free mem list for suitable chunks
1389 struct freeMemItem * freemem = findFreeMemChunk_I(coren, isize, &tofindb);
1391 // allocate shared mem if available
1392 if(freemem != NULL) {
1393 switch(bamboo_smem_mode) {
1395 mem = localmalloc_I(tofindb, isize, freemem, allocsize);
1400 int startb = freemem->startblock;
1401 int endb = freemem->endblock;
1402 if(startb > tofindb) {
1403 // malloc on global mem
1404 mem = globalmalloc_I(isize, freemem, allocsize);
1406 // malloc on local mem
1407 mem = localmalloc_I(tofindb, isize, freemem, allocsize);
1413 // TODO not supported yet
1414 BAMBOO_EXIT(0xe002);
1419 mem = globalmalloc_I(isize,freemem, allocsize);
1428 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size):(BAMBOO_SMEM_SIZE);
1429 mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1430 *allocsize = toallocate;
1433 // no enough shared global memory
1439 BAMBOO_DEBUGPRINT(0xa001);
1440 BAMBOO_EXIT(0xa001);
1444 } // void * smemalloc_I(int, int, int)
1446 // receive object transferred from other cores
1447 // or the terminate message from other cores
1448 // Should be invoked in critical sections!!
1449 // NOTICE: following format is for threadsimulate version only
1450 // RAW version please see previous description
1451 // format: type + object
1452 // type: -1--stall msg
1454 // return value: 0--received an object
1455 // 1--received nothing
1456 // 2--received a Stall Msg
1457 // 3--received a lock Msg
1458 // RAW version: -1 -- received nothing
1459 // otherwise -- received msg type
1460 int receiveObject() {
1464 if(receiveMsg() == -1) {
1468 if(msgdataindex == msglength) {
1469 // received a whole msg
1474 // receive a object transfer msg
1475 struct transObjInfo * transObj =
1476 RUNMALLOC_I(sizeof(struct transObjInfo));
1480 BAMBOO_DEBUGPRINT(0xe880);
1483 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1485 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1487 BAMBOO_EXIT(0xa002);
1489 // store the object and its corresponding queue info, enqueue it later
1490 transObj->objptr = (void *)msgdata[2];
1491 transObj->length = (msglength - 3) / 2;
1492 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1493 for(k = 0; k < transObj->length; ++k) {
1494 transObj->queues[2*k] = msgdata[3+2*k];
1497 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1500 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1503 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1507 // check if there is an existing duplicate item
1509 struct QueueItem * qitem = getHead(&objqueue);
1510 struct QueueItem * prev = NULL;
1511 while(qitem != NULL) {
1512 struct transObjInfo * tmpinfo =
1513 (struct transObjInfo *)(qitem->objectptr);
1514 if(tmpinfo->objptr == transObj->objptr) {
1515 // the same object, remove outdate one
1516 RUNFREE(tmpinfo->queues);
1518 removeItem(&objqueue, qitem);
1524 qitem = getHead(&objqueue);
1526 qitem = getNextQueueItem(prev);
1529 addNewItem_I(&objqueue, (void *)transObj);
1531 ++(self_numreceiveobjs);
1536 // receive a stall msg
1537 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1538 // non startup core can not receive stall msg
1540 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1542 BAMBOO_EXIT(0xa003);
1544 if(msgdata[1] < NUMCORESACTIVE) {
1547 BAMBOO_DEBUGPRINT(0xe881);
1550 corestatus[msgdata[1]] = 0;
1551 numsendobjs[msgdata[1]] = msgdata[2];
1552 numreceiveobjs[msgdata[1]] = msgdata[3];
1557 // GC version have no lock msgs
1558 #ifndef MULTICORE_GC
1560 // receive lock request msg, handle it right now
1561 // check to see if there is a lock exist for the required obj
1562 // msgdata[1] -> lock type
1563 int data2 = msgdata[2]; // obj pointer
1564 int data3 = msgdata[3]; // lock
1565 int data4 = msgdata[4]; // request core
1566 // -1: redirected, 0: approved, 1: denied
1567 deny = processlockrequest(msgdata[1], data3, data2,
1568 data4, data4, true);
1570 // this lock request is redirected
1573 // send response msg
1574 // for 32 bit machine, the size is always 4 words
1575 int tmp = deny==1?LOCKDENY:LOCKGROUNT;
1577 cache_msg_4(data4, tmp, msgdata[1], data2, data3);
1579 send_msg_4(data4, tmp, msgdata[1], data2, data3);
1586 // receive lock grount msg
1587 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1589 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1591 BAMBOO_EXIT(0xa004);
1593 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1596 BAMBOO_DEBUGPRINT(0xe882);
1605 // conflicts on lockresults
1607 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1609 BAMBOO_EXIT(0xa005);
1615 // receive lock deny msg
1616 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1618 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1620 BAMBOO_EXIT(0xa006);
1622 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1625 BAMBOO_DEBUGPRINT(0xe883);
1634 // conflicts on lockresults
1636 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1638 BAMBOO_EXIT(0xa007);
1644 // receive lock release msg
1645 processlockrelease(msgdata[1], msgdata[2], 0, false);
1651 case PROFILEOUTPUT: {
1652 // receive an output profile data request msg
1653 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1654 // startup core can not receive profile output finish msg
1655 BAMBOO_EXIT(0xa008);
1659 BAMBOO_DEBUGPRINT(0xe885);
1663 totalexetime = msgdata[1];
1664 outputProfileData();
1666 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1668 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1673 case PROFILEFINISH: {
1674 // receive a profile output finish msg
1675 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1676 // non startup core can not receive profile output finish msg
1678 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1680 BAMBOO_EXIT(0xa009);
1684 BAMBOO_DEBUGPRINT(0xe886);
1687 profilestatus[msgdata[1]] = 0;
1692 // GC version has no lock msgs
1693 #ifndef MULTICORE_GC
1694 case REDIRECTLOCK: {
1695 // receive a redirect lock request msg, handle it right now
1696 // check to see if there is a lock exist for the required obj
1697 int data1 = msgdata[1]; // lock type
1698 int data2 = msgdata[2]; // obj pointer
1699 int data3 = msgdata[3]; // redirect lock
1700 int data4 = msgdata[4]; // root request core
1701 int data5 = msgdata[5]; // request core
1702 deny = processlockrequest(msgdata[1], data3, data2, data5, data4, true);
1704 // this lock request is redirected
1707 // send response msg
1708 // for 32 bit machine, the size is always 4 words
1710 cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1711 data1, data2, data3);
1713 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1714 data1, data2, data3);
1720 case REDIRECTGROUNT: {
1721 // receive a lock grant msg with redirect info
1722 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1724 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1726 BAMBOO_EXIT(0xa00a);
1728 if(lockobj == msgdata[2]) {
1731 BAMBOO_DEBUGPRINT(0xe891);
1736 RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1741 // conflicts on lockresults
1743 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1745 BAMBOO_EXIT(0xa00b);
1750 case REDIRECTDENY: {
1751 // receive a lock deny msg with redirect info
1752 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1754 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1756 BAMBOO_EXIT(0xa00c);
1758 if(lockobj == msgdata[2]) {
1761 BAMBOO_DEBUGPRINT(0xe892);
1770 // conflicts on lockresults
1772 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1774 BAMBOO_EXIT(0xa00d);
1779 case REDIRECTRELEASE: {
1780 // receive a lock release msg with redirect info
1781 processlockrelease(msgdata[1], msgdata[2], msgdata[3], true);
1786 case STATUSCONFIRM: {
1787 // receive a status confirm info
1788 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1789 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1790 // wrong core to receive such msg
1791 BAMBOO_EXIT(0xa00e);
1793 // send response msg
1796 BAMBOO_DEBUGPRINT(0xe887);
1800 cache_msg_5(STARTUPCORE, STATUSREPORT,
1801 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1802 self_numsendobjs, self_numreceiveobjs);
1804 send_msg_5(STARTUPCORE, STATUSREPORT,
1805 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1806 self_numsendobjs, self_numreceiveobjs);
1812 case STATUSREPORT: {
1813 // receive a status confirm info
1814 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1815 // wrong core to receive such msg
1817 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1819 BAMBOO_EXIT(0xa00f);
1823 BAMBOO_DEBUGPRINT(0xe888);
1829 corestatus[msgdata[2]] = msgdata[1];
1830 numsendobjs[msgdata[2]] = msgdata[3];
1831 numreceiveobjs[msgdata[2]] = msgdata[4];
1837 // receive a terminate msg
1840 BAMBOO_DEBUGPRINT(0xe889);
1849 // receive a shared memory request msg
1850 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1851 // wrong core to receive such msg
1853 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1855 BAMBOO_EXIT(0xa010);
1859 BAMBOO_DEBUGPRINT(0xe88a);
1864 // is currently doing gc, dump this msg
1869 void * mem = smemalloc_I(msgdata[2], msgdata[1], &allocsize);
1873 // send the start_va to request core
1875 cache_msg_3(msgdata[2], MEMRESPONSE, mem, allocsize);
1877 send_msg_3( msgdata[2], MEMRESPONSE, mem, allocsize);
1884 // receive a shared memory response msg
1887 BAMBOO_DEBUGPRINT(0xe88b);
1892 // is currently doing gc, dump this msg
1896 if(msgdata[2] == 0) {
1897 bamboo_smem_size = 0;
1901 // fill header to store the size of this mem block
1902 (*((int*)msgdata[1])) = msgdata[2];
1903 bamboo_smem_size = msgdata[2] - BAMBOO_CACHE_LINE_SIZE;
1904 bamboo_cur_msp = msgdata[1] + BAMBOO_CACHE_LINE_SIZE;
1906 bamboo_smem_size = msgdata[2];
1907 bamboo_cur_msp =(void*)(msgdata[1]);
1918 gcphase = INITPHASE;
1920 // is waiting for response of mem request
1921 // let it return NULL and start gc
1922 bamboo_smem_size = 0;
1923 bamboo_cur_msp = NULL;
1930 // receive a start GC msg
1933 BAMBOO_DEBUGPRINT(0xe88c);
1937 gcphase = MARKPHASE;
1941 case GCSTARTCOMPACT: {
1942 // a compact phase start msg
1943 gcblock2fill = msgdata[1];
1944 gcphase = COMPACTPHASE;
1948 case GCSTARTFLUSH: {
1949 // received a flush phase start msg
1950 gcphase = FLUSHPHASE;
1954 case GCFINISHINIT: {
1955 // received a init phase finish msg
1956 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1957 // non startup core can not receive this msg
1959 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1961 BAMBOO_EXIT(0xb001);
1964 BAMBOO_DEBUGPRINT(0xe88c);
1965 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1967 if(msgdata[1] < NUMCORES4GC) {
1968 gccorestatus[msgdata[1]] = 0;
1972 case GCFINISHMARK: {
1973 // received a mark phase finish msg
1974 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1975 // non startup core can not receive this msg
1977 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1979 BAMBOO_EXIT(0xb002);
1981 if(msgdata[1] < NUMCORES4GC) {
1982 gccorestatus[msgdata[1]] = 0;
1983 gcnumsendobjs[msgdata[1]] = msgdata[2];
1984 gcnumreceiveobjs[msgdata[1]] = msgdata[3];
1989 case GCFINISHCOMPACT: {
1990 // received a compact phase finish msg
1991 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1992 // non startup core can not receive this msg
1995 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1997 BAMBOO_EXIT(0xb003);
1999 int cnum = msgdata[1];
2000 int filledblocks = msgdata[2];
2001 int heaptop = msgdata[3];
2002 int data4 = msgdata[4];
2003 if(cnum < NUMCORES4GC) {
2004 if(COMPACTPHASE == gcphase) {
2005 gcfilledblocks[cnum] = filledblocks;
2006 gcloads[cnum] = heaptop;
2013 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2015 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2017 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2021 gccorestatus[cnum] = 0;
2022 // check if there is pending move request
2023 /*if(gcmovepending > 0) {
2025 for(j = 0; j < NUMCORES4GC; j++) {
2026 if(gcrequiredmems[j]>0) {
2030 if(j < NUMCORES4GC) {
2034 gcrequiredmems[j] = assignSpareMem_I(cnum,
2038 if(STARTUPCORE == j) {
2041 gcmovestartaddr = startaddr;
2042 gcblock2fill = tomove;
2045 cache_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
2047 send_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
2049 } // if(STARTUPCORE == j)
2050 if(gcrequiredmems[j] == 0) {
2053 } // if(j < NUMCORES4GC)
2054 } // if(gcmovepending > 0) */
2056 } // if(cnum < NUMCORES4GC)
2060 case GCFINISHFLUSH: {
2061 // received a flush phase finish msg
2062 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2063 // non startup core can not receive this msg
2066 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2068 BAMBOO_EXIT(0xb004);
2070 if(msgdata[1] < NUMCORES4GC) {
2071 gccorestatus[msgdata[1]] = 0;
2077 // received a GC finish msg
2078 gcphase = FINISHPHASE;
2082 case GCMARKCONFIRM: {
2083 // received a marked phase finish confirm request msg
2084 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2085 || (BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1)) {
2086 // wrong core to receive such msg
2087 BAMBOO_EXIT(0xb005);
2089 // send response msg
2091 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2092 gcbusystatus, gcself_numsendobjs,
2093 gcself_numreceiveobjs);
2095 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2096 gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
2102 case GCMARKREPORT: {
2103 // received a marked phase finish confirm response msg
2104 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2105 // wrong core to receive such msg
2107 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2109 BAMBOO_EXIT(0xb006);
2114 gccorestatus[msgdata[1]] = msgdata[2];
2115 gcnumsendobjs[msgdata[1]] = msgdata[3];
2116 gcnumreceiveobjs[msgdata[1]] = msgdata[4];
2122 // received a markedObj msg
2123 if(((int *)msgdata[1])[6] == INIT) {
2124 // this is the first time that this object is discovered,
2125 // set the flag as DISCOVERED
2126 ((int *)msgdata[1])[6] = DISCOVERED;
2127 gc_enqueue_I(msgdata[1]);
2129 gcself_numreceiveobjs++;
2130 gcbusystatus = true;
2135 // received a start moving objs msg
2137 gcdstcore = msgdata[1];
2138 gcmovestartaddr = msgdata[2];
2139 gcblock2fill = msgdata[3];
2143 case GCMAPREQUEST: {
2144 // received a mapping info request msg
2145 void * dstptr = NULL;
2146 //dstptr = mgchashSearch(msgdata[1]);
2147 RuntimeHashget(gcpointertbl, msgdata[1], &dstptr);
2148 //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2149 if(NULL == dstptr) {
2150 // no such pointer in this core, something is wrong
2152 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2153 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2155 BAMBOO_EXIT(0xb007);
2156 //assume that the object was not moved, use the original address
2157 /*if(isMsgSending) {
2158 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2160 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2163 // send back the mapping info
2165 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
2167 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
2174 // received a mapping info response msg
2175 if(msgdata[1] != gcobj2map) {
2176 // obj not matched, something is wrong
2178 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2179 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2181 BAMBOO_EXIT(0xb008);
2183 gcmappedobj = msgdata[2];
2184 //mgchashInsert_I(gcobj2map, gcmappedobj);
2185 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2186 //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2192 case GCLOBJREQUEST: {
2193 // received a large objs info request msg
2194 transferMarkResults_I();
2199 // received a large objs info response msg
2202 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2204 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2206 BAMBOO_EXIT(0xb009);
2208 // store the mark result info
2209 int cnum = msgdata[2];
2210 gcloads[cnum] = msgdata[3];
2211 if(gcheaptop < msgdata[4]) {
2212 gcheaptop = msgdata[4];
2214 // large obj info here
2215 for(int k = 5; k < msgdata[1];) {
2216 int lobj = msgdata[k++];
2217 int length = msgdata[k++];
2218 gc_lobjenqueue_I(lobj, length, cnum);
2220 } // for(int k = 5; k < msgdata[1];)
2224 case GCLOBJMAPPING: {
2225 // received a large obj mapping info msg
2226 //mgchashInsert_I(msgdata[1], msgdata[2]);
2227 RuntimeHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2228 //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2237 for(; msgdataindex > 0; --msgdataindex) {
2238 msgdata[msgdataindex-1] = -1;
2240 msglength = BAMBOO_MSG_BUF_LENGTH;
2243 BAMBOO_DEBUGPRINT(0xe88d);
2247 if(BAMBOO_MSG_AVAIL() != 0) {
2260 BAMBOO_DEBUGPRINT(0xe88e);
2264 /* if(isInterrupt) {
2272 int enqueuetasks(struct parameterwrapper *parameter,
2273 struct parameterwrapper *prevptr,
2274 struct ___Object___ *ptr,
2276 int numenterflags) {
2277 void * taskpointerarray[MAXTASKPARAMS];
2279 //int numparams=parameter->task->numParameters;
2280 int numiterators=parameter->task->numTotal-1;
2283 struct taskdescriptor * task=parameter->task;
2285 //this add the object to parameterwrapper
2286 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
2287 numenterflags, enterflags==NULL);
2289 /* Add enqueued object to parameter vector */
2290 taskpointerarray[parameter->slot]=ptr;
2292 /* Reset iterators */
2293 for(j=0; j<numiterators; j++) {
2294 toiReset(¶meter->iterators[j]);
2297 /* Find initial state */
2298 for(j=0; j<numiterators; j++) {
2300 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2301 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2303 /* Need to backtrack */
2304 toiReset(¶meter->iterators[j]);
2308 /* Nothing to enqueue */
2314 /* Enqueue current state */
2316 struct taskparamdescriptor *tpd=
2317 RUNMALLOC(sizeof(struct taskparamdescriptor));
2319 tpd->numParameters=numiterators+1;
2320 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2322 for(j=0; j<=numiterators; j++) {
2323 //store the actual parameters
2324 tpd->parameterArray[j]=taskpointerarray[j];
2327 if ((/*!gencontains(failedtasks, tpd)&&*/
2328 !gencontains(activetasks,tpd))) {
2329 genputtable(activetasks, tpd, tpd);
2331 RUNFREE(tpd->parameterArray);
2335 /* This loop iterates to the next parameter combination */
2336 if (numiterators==0)
2339 for(j=numiterators-1; j<numiterators; j++) {
2341 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2342 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2344 /* Need to backtrack */
2345 toiReset(¶meter->iterators[j]);
2349 /* Nothing more to enqueue */
2357 int enqueuetasks_I(struct parameterwrapper *parameter,
2358 struct parameterwrapper *prevptr,
2359 struct ___Object___ *ptr,
2361 int numenterflags) {
2362 void * taskpointerarray[MAXTASKPARAMS];
2364 //int numparams=parameter->task->numParameters;
2365 int numiterators=parameter->task->numTotal-1;
2370 struct taskdescriptor * task=parameter->task;
2372 //this add the object to parameterwrapper
2373 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2374 numenterflags, enterflags==NULL);
2376 /* Add enqueued object to parameter vector */
2377 taskpointerarray[parameter->slot]=ptr;
2379 /* Reset iterators */
2380 for(j=0; j<numiterators; j++) {
2381 toiReset(¶meter->iterators[j]);
2384 /* Find initial state */
2385 for(j=0; j<numiterators; j++) {
2387 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2388 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2390 /* Need to backtrack */
2391 toiReset(¶meter->iterators[j]);
2395 /* Nothing to enqueue */
2401 /* Enqueue current state */
2403 struct taskparamdescriptor *tpd=
2404 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2406 tpd->numParameters=numiterators+1;
2407 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2409 for(j=0; j<=numiterators; j++) {
2410 //store the actual parameters
2411 tpd->parameterArray[j]=taskpointerarray[j];
2414 if ((/*!gencontains(failedtasks, tpd)&&*/
2415 !gencontains(activetasks,tpd))) {
2416 genputtable_I(activetasks, tpd, tpd);
2418 RUNFREE(tpd->parameterArray);
2422 /* This loop iterates to the next parameter combination */
2423 if (numiterators==0)
2426 for(j=numiterators-1; j<numiterators; j++) {
2428 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2429 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2431 /* Need to backtrack */
2432 toiReset(¶meter->iterators[j]);
2436 /* Nothing more to enqueue */
2450 int containstag(struct ___Object___ *ptr,
2451 struct ___TagDescriptor___ *tag);
2453 #ifndef MULTICORE_GC
2454 void releasewritelock_r(void * lock, void * redirectlock) {
2456 int reallock = (int)lock;
2457 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2460 BAMBOO_DEBUGPRINT(0xe671);
2461 BAMBOO_DEBUGPRINT_REG((int)lock);
2462 BAMBOO_DEBUGPRINT_REG(reallock);
2463 BAMBOO_DEBUGPRINT_REG(targetcore);
2466 if(targetcore == BAMBOO_NUM_OF_CORE) {
2467 BAMBOO_START_CRITICAL_SECTION_LOCK();
2469 BAMBOO_DEBUGPRINT(0xf001);
2471 // reside on this core
2472 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2473 // no locks for this object, something is wrong
2474 BAMBOO_EXIT(0xa011);
2477 struct LockValue * lockvalue = NULL;
2479 BAMBOO_DEBUGPRINT(0xe672);
2481 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2482 lockvalue = (struct LockValue *)rwlock_obj;
2484 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2487 lockvalue->redirectlock = (int)redirectlock;
2489 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2492 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2494 BAMBOO_DEBUGPRINT(0xf000);
2498 // send lock release with redirect info msg
2499 // for 32 bit machine, the size is always 4 words
2500 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
2505 void executetasks() {
2506 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2509 struct ___Object___ * tmpparam = NULL;
2510 struct parameterdescriptor * pd=NULL;
2511 struct parameterwrapper *pw=NULL;
2521 while(hashsize(activetasks)>0) {
2526 BAMBOO_DEBUGPRINT(0xe990);
2529 /* See if there are any active tasks */
2530 //if (hashsize(activetasks)>0) {
2533 #ifdef ACCURATEPROFILE
2534 profileTaskStart("tpd checking");
2538 //clock1 = BAMBOO_GET_EXE_TIME();
2541 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2542 genfreekey(activetasks, currtpd);
2544 numparams=currtpd->task->numParameters;
2545 numtotal=currtpd->task->numTotal;
2547 // clear the lockRedirectTbl
2548 // (TODO, this table should be empty after all locks are released)
2550 /*for(j = 0; j < MAXTASKPARAMS; j++) {
2551 runtime_locks[j].redirectlock = 0;
2552 runtime_locks[j].value = 0;
2554 // get all required locks
2555 runtime_locklen = 0;
2556 // check which locks are needed
2557 for(i = 0; i < numparams; i++) {
2558 void * param = currtpd->parameterArray[i];
2562 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2564 taskpointerarray[i+OFFSET]=param;
2567 if(((struct ___Object___ *)param)->lock == NULL) {
2568 tmplock = (int)param;
2570 tmplock = (int)(((struct ___Object___ *)param)->lock);
2572 // insert into the locks array
2573 for(j = 0; j < runtime_locklen; j++) {
2574 if(runtime_locks[j].value == tmplock) {
2577 } else if(runtime_locks[j].value > tmplock) {
2582 int h = runtime_locklen;
2584 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
2585 runtime_locks[h].value = runtime_locks[h-1].value;
2587 runtime_locks[j].value = tmplock;
2588 runtime_locks[j].redirectlock = (int)param;
2591 } // line 2713: for(i = 0; i < numparams; i++)
2592 // grab these required locks
2594 BAMBOO_DEBUGPRINT(0xe991);
2597 //clock2 = BAMBOO_GET_EXE_TIME();
2599 for(i = 0; i < runtime_locklen; i++) {
2600 /*for(i = 0; i < numparams; i++) {
2601 void * param = currtpd->parameterArray[i];
2604 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2606 taskpointerarray[i+OFFSET]=param;
2609 if(((struct ___Object___ *)param)->lock == NULL) {
2610 lock = (int *)param;
2612 lock = (int *)(((struct ___Object___ *)param)->lock);
2616 int * lock = (int *)(runtime_locks[i].redirectlock);
2618 // require locks for this parameter if it is not a startup object
2620 BAMBOO_DEBUGPRINT_REG((int)lock);
2621 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
2624 BAMBOO_START_CRITICAL_SECTION();
2626 BAMBOO_DEBUGPRINT(0xf001);
2629 //isInterrupt = false;
2632 BAMBOO_WAITING_FOR_LOCK();
2636 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2640 grount = lockresult;
2650 //isInterrupt = true;
2652 BAMBOO_CLOSE_CRITICAL_SECTION();
2654 BAMBOO_DEBUGPRINT(0xf000);
2659 BAMBOO_DEBUGPRINT(0xe992);
2660 BAMBOO_DEBUGPRINT_REG(lock);
2662 // check if has the lock already
2663 /*bool giveup = true;
2664 for(j = 0; j < runtime_locklen; j++) {
2665 if(runtime_locks[j].value == lock) {
2671 // can not get the lock, try later
2672 // release all grabbed locks for previous parameters
2673 for(j = 0; j < i; ++j) {
2674 //for(j = 0; j < runtime_locklen; ++j) {
2675 lock = (int*)(runtime_locks[j].redirectlock);
2676 releasewritelock(lock);
2678 genputtable(activetasks, currtpd, currtpd);
2679 if(hashsize(activetasks) == 1) {
2680 // only one task right now, wait a little while before next try
2686 #ifdef ACCURATEPROFILE
2687 // fail, set the end of the checkTaskInfo
2693 }/* else { // line 2794: if(grount == 0)
2695 runtime_locks[runtime_locklen].value = (int)lock;
2696 runtime_locks[runtime_locklen].redirectlock = (int)param;
2699 } // line 2752: for(i = 0; i < runtime_locklen; i++)
2702 clock3 = BAMBOO_GET_EXE_TIME();
2703 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
2706 BAMBOO_DEBUGPRINT(0xe993);
2708 /* Make sure that the parameters are still in the queues */
2709 for(i=0; i<numparams; i++) {
2710 void * parameter=currtpd->parameterArray[i];
2714 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
2715 classsize[((struct ___Object___ *)parameter)->type]);
2717 tmpparam = (struct ___Object___ *)parameter;
2718 pd=currtpd->task->descriptorarray[i];
2719 pw=(struct parameterwrapper *) pd->queue;
2720 /* Check that object is still in queue */
2722 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2724 BAMBOO_DEBUGPRINT(0xe994);
2725 BAMBOO_DEBUGPRINT_REG(parameter);
2727 // release grabbed locks
2728 for(j = 0; j < runtime_locklen; ++j) {
2729 int * lock = (int *)(runtime_locks[j].redirectlock);
2730 releasewritelock(lock);
2732 RUNFREE(currtpd->parameterArray);
2738 /* Check if the object's flags still meets requirements */
2742 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2743 andmask=pw->intarray[tmpi*2];
2744 checkmask=pw->intarray[tmpi*2+1];
2745 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2751 // flags are never suitable
2752 // remove this obj from the queue
2754 int UNUSED, UNUSED2;
2757 BAMBOO_DEBUGPRINT(0xe995);
2758 BAMBOO_DEBUGPRINT_REG(parameter);
2760 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
2761 (int *) &enterflags, &UNUSED, &UNUSED2);
2762 ObjectHashremove(pw->objectset, (int)parameter);
2763 if (enterflags!=NULL)
2764 RUNFREE(enterflags);
2765 // release grabbed locks
2766 for(j = 0; j < runtime_locklen; ++j) {
2767 int * lock = (int *)(runtime_locks[j].redirectlock);
2768 releasewritelock(lock);
2770 RUNFREE(currtpd->parameterArray);
2774 #ifdef ACCURATEPROFILE
2775 // fail, set the end of the checkTaskInfo
2780 } // line 2878: if (!ismet)
2784 /* Check that object still has necessary tags */
2785 for(j=0; j<pd->numbertags; j++) {
2786 int slotid=pd->tagarray[2*j]+numparams;
2787 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2788 if (!containstag(parameter, tagd)) {
2790 BAMBOO_DEBUGPRINT(0xe996);
2793 // release grabbed locks
2795 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
2796 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
2797 releasewritelock(lock);
2800 RUNFREE(currtpd->parameterArray);
2804 } // line2911: if (!containstag(parameter, tagd))
2805 } // line 2808: for(j=0; j<pd->numbertags; j++)
2807 taskpointerarray[i+OFFSET]=parameter;
2808 } // line 2824: for(i=0; i<numparams; i++)
2810 for(; i<numtotal; i++) {
2811 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2816 /* Actually call task */
2818 ((int *)taskpointerarray)[0]=currtpd->numParameters;
2819 taskpointerarray[1]=NULL;
2822 #ifdef ACCURATEPROFILE
2823 // check finish, set the end of the checkTaskInfo
2826 profileTaskStart(currtpd->task->name);
2830 //clock4 = BAMBOO_GET_EXE_TIME();
2831 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
2834 BAMBOO_DEBUGPRINT(0xe997);
2836 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2839 //clock5 = BAMBOO_GET_EXE_TIME();
2840 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
2843 #ifdef ACCURATEPROFILE
2844 // task finish, set the end of the checkTaskInfo
2846 // new a PostTaskInfo for the post-task execution
2847 profileTaskStart("post task execution");
2851 BAMBOO_DEBUGPRINT(0xe998);
2852 BAMBOO_DEBUGPRINT_REG(islock);
2857 BAMBOO_DEBUGPRINT(0xe999);
2859 for(i = 0; i < runtime_locklen; ++i) {
2860 void * ptr = (void *)(runtime_locks[i].redirectlock);
2861 int * lock = (int *)(runtime_locks[i].value);
2863 BAMBOO_DEBUGPRINT_REG((int)ptr);
2864 BAMBOO_DEBUGPRINT_REG((int)lock);
2865 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
2867 #ifndef MULTICORE_GC
2868 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2870 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2871 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2872 releasewritelock_r(lock, (int *)redirectlock);
2877 releasewritelock(ptr);
2880 } // line 3015: if(islock)
2883 //clock6 = BAMBOO_GET_EXE_TIME();
2884 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
2887 // post task execution finish, set the end of the postTaskInfo
2891 // Free up task parameter descriptor
2892 RUNFREE(currtpd->parameterArray);
2896 BAMBOO_DEBUGPRINT(0xe99a);
2899 //clock7 = BAMBOO_GET_EXE_TIME();
2900 //tprintf("sort: %d, grab: %d, check: %d, release: %d, other %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3), (int)(clock6-clock5), (int)(clock7-clock6));
2903 //} // if (hashsize(activetasks)>0)
2904 } // while(hashsize(activetasks)>0)
2906 BAMBOO_DEBUGPRINT(0xe99b);
2910 /* This function processes an objects tags */
2911 void processtags(struct parameterdescriptor *pd,
2913 struct parameterwrapper *parameter,
2914 int * iteratorcount,
2919 for(i=0; i<pd->numbertags; i++) {
2920 int slotid=pd->tagarray[2*i];
2921 int tagid=pd->tagarray[2*i+1];
2923 if (statusarray[slotid+numparams]==0) {
2924 parameter->iterators[*iteratorcount].istag=1;
2925 parameter->iterators[*iteratorcount].tagid=tagid;
2926 parameter->iterators[*iteratorcount].slot=slotid+numparams;
2927 parameter->iterators[*iteratorcount].tagobjectslot=index;
2928 statusarray[slotid+numparams]=1;
2935 void processobject(struct parameterwrapper *parameter,
2937 struct parameterdescriptor *pd,
2943 struct ObjectHash * objectset=
2944 ((struct parameterwrapper *)pd->queue)->objectset;
2946 parameter->iterators[*iteratorcount].istag=0;
2947 parameter->iterators[*iteratorcount].slot=index;
2948 parameter->iterators[*iteratorcount].objectset=objectset;
2949 statusarray[index]=1;
2951 for(i=0; i<pd->numbertags; i++) {
2952 int slotid=pd->tagarray[2*i];
2953 //int tagid=pd->tagarray[2*i+1];
2954 if (statusarray[slotid+numparams]!=0) {
2955 /* This tag has already been enqueued, use it to narrow search */
2956 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
2961 parameter->iterators[*iteratorcount].numtags=tagcount;
2966 /* This function builds the iterators for a task & parameter */
2968 void builditerators(struct taskdescriptor * task,
2970 struct parameterwrapper * parameter) {
2971 int statusarray[MAXTASKPARAMS];
2973 int numparams=task->numParameters;
2974 int iteratorcount=0;
2975 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
2977 statusarray[index]=1; /* Initial parameter */
2978 /* Process tags for initial iterator */
2980 processtags(task->descriptorarray[index], index, parameter,
2981 &iteratorcount, statusarray, numparams);
2985 /* Check for objects with existing tags */
2986 for(i=0; i<numparams; i++) {
2987 if (statusarray[i]==0) {
2988 struct parameterdescriptor *pd=task->descriptorarray[i];
2990 for(j=0; j<pd->numbertags; j++) {
2991 int slotid=pd->tagarray[2*j];
2992 if(statusarray[slotid+numparams]!=0) {
2993 processobject(parameter, i, pd, &iteratorcount, statusarray,
2995 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3002 /* Next do objects w/ unbound tags*/
3004 for(i=0; i<numparams; i++) {
3005 if (statusarray[i]==0) {
3006 struct parameterdescriptor *pd=task->descriptorarray[i];
3007 if (pd->numbertags>0) {
3008 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3009 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3015 /* Nothing with a tag enqueued */
3017 for(i=0; i<numparams; i++) {
3018 if (statusarray[i]==0) {
3019 struct parameterdescriptor *pd=task->descriptorarray[i];
3020 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3021 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3034 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3037 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3038 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3040 printf("%s\n", task->name);
3042 for(j=0; j<task->numParameters; j++) {
3043 struct parameterdescriptor *param=task->descriptorarray[j];
3044 struct parameterwrapper *parameter=param->queue;
3045 struct ObjectHash * set=parameter->objectset;
3046 struct ObjectIterator objit;
3048 printf(" Parameter %d\n", j);
3050 ObjectHashiterator(set, &objit);
3051 while(ObjhasNext(&objit)) {
3052 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3053 struct ___Object___ * tagptr=obj->___tags___;
3054 int nonfailed=Objdata4(&objit);
3055 int numflags=Objdata3(&objit);
3056 int flags=Objdata2(&objit);
3059 printf(" Contains %lx\n", obj);
3060 printf(" flag=%d\n", obj->flag);
3063 } else if (tagptr->type==TAGTYPE) {
3065 printf(" tag=%lx\n",tagptr);
3071 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3072 for(; tagindex<ao->___cachedCode___; tagindex++) {
3074 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3087 /* This function processes the task information to create queues for
3088 each parameter type. */
3090 void processtasks() {
3092 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3095 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3096 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3099 /* Build objectsets */
3100 for(j=0; j<task->numParameters; j++) {
3101 struct parameterdescriptor *param=task->descriptorarray[j];
3102 struct parameterwrapper *parameter=param->queue;
3103 parameter->objectset=allocateObjectHash(10);
3104 parameter->task=task;
3107 /* Build iterators for parameters */
3108 for(j=0; j<task->numParameters; j++) {
3109 struct parameterdescriptor *param=task->descriptorarray[j];
3110 struct parameterwrapper *parameter=param->queue;
3111 builditerators(task, j, parameter);
3116 void toiReset(struct tagobjectiterator * it) {
3119 } else if (it->numtags>0) {
3122 ObjectHashiterator(it->objectset, &it->it);
3126 int toiHasNext(struct tagobjectiterator *it,
3127 void ** objectarray OPTARG(int * failed)) {
3130 /* Get object with tags */
3131 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3132 struct ___Object___ *tagptr=obj->___tags___;
3133 if (tagptr->type==TAGTYPE) {
3134 if ((it->tagobjindex==0)&& /* First object */
3135 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3140 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3141 int tagindex=it->tagobjindex;
3142 for(; tagindex<ao->___cachedCode___; tagindex++) {
3143 struct ___TagDescriptor___ *td=
3144 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3145 if (td->flag==it->tagid) {
3146 it->tagobjindex=tagindex; /* Found right type of tag */
3152 } else if (it->numtags>0) {
3153 /* Use tags to locate appropriate objects */
3154 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3155 struct ___Object___ *objptr=tag->flagptr;
3157 if (objptr->type!=OBJECTARRAYTYPE) {
3158 if (it->tagobjindex>0)
3160 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3162 for(i=1; i<it->numtags; i++) {
3163 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3164 if (!containstag(objptr,tag2))
3169 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3172 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
3173 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3174 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3176 for(i=1; i<it->numtags; i++) {
3177 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3178 if (!containstag(objptr,tag2))
3181 it->tagobjindex=tagindex;
3186 it->tagobjindex=tagindex;
3190 return ObjhasNext(&it->it);
3194 int containstag(struct ___Object___ *ptr,
3195 struct ___TagDescriptor___ *tag) {
3197 struct ___Object___ * objptr=tag->flagptr;
3198 if (objptr->type==OBJECTARRAYTYPE) {
3199 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3200 for(j=0; j<ao->___cachedCode___; j++) {
3201 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3211 void toiNext(struct tagobjectiterator *it,
3212 void ** objectarray OPTARG(int * failed)) {
3213 /* hasNext has all of the intelligence */
3216 /* Get object with tags */
3217 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3218 struct ___Object___ *tagptr=obj->___tags___;
3219 if (tagptr->type==TAGTYPE) {
3221 objectarray[it->slot]=tagptr;
3223 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3224 objectarray[it->slot]=
3225 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3227 } else if (it->numtags>0) {
3228 /* Use tags to locate appropriate objects */
3229 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3230 struct ___Object___ *objptr=tag->flagptr;
3231 if (objptr->type!=OBJECTARRAYTYPE) {
3233 objectarray[it->slot]=objptr;
3235 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3236 objectarray[it->slot]=
3237 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3240 /* Iterate object */
3241 objectarray[it->slot]=(void *)Objkey(&it->it);