3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5 #include "GenericHashtable.h"
8 #define INLINE inline __attribute__((always_inline))
9 #endif // #ifndef INLINE
11 // data structures for task invocation
12 struct genhashtable * activetasks;
13 struct taskparamdescriptor * currtpd;
14 struct LockValue runtime_locks[MAXTASKPARAMS];
17 // specific functions used inside critical sections
18 void enqueueObject_I(void * ptr,
19 struct parameterwrapper ** queues,
21 int enqueuetasks_I(struct parameterwrapper *parameter,
22 struct parameterwrapper *prevptr,
23 struct ___Object___ *ptr,
28 inline __attribute__((always_inline))
29 void setupsmemmode(void) {
31 bamboo_smem_mode = SMEMLOCAL;
33 bamboo_smem_mode = SMEMFIXED;
35 bamboo_smem_mode = SMEMMIXED;
37 bamboo_smem_mode = SMEMGLOBAL;
39 // defaultly using local mode
40 //bamboo_smem_mode = SMEMLOCAL;
41 bamboo_smem_mode = SMEMGLOBAL;
43 } // void setupsmemmode(void)
46 inline __attribute__((always_inline))
47 void initruntimedata() {
49 // initialize the arrays
50 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
51 // startup core to initialize corestatus[]
52 for(i = 0; i < NUMCORESACTIVE; ++i) {
55 numreceiveobjs[i] = 0;
57 // initialize the profile data arrays
63 gcnumreceiveobjs[i] = 0;
65 } // for(i = 0; i < NUMCORESACTIVE; ++i)
67 for(i = 0; i < NUMCORES4GC; ++i) {
69 gcrequiredmems[i] = 0;
71 gcfilledblocks[i] = 0;
72 } // for(i = 0; i < NUMCORES4GC; ++i)
75 gc_infoOverflow = false;
87 self_numreceiveobjs = 0;
89 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
94 msglength = BAMBOO_MSG_BUF_LENGTH;
96 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
102 isMsgHanging = false;
103 isMsgSending = false;
106 bamboo_cur_msp = NULL;
107 bamboo_smem_size = 0;
108 totransobjqueue = createQueue_I();
112 gcprocessing = false;
113 gcphase = FINISHPHASE;
115 gcself_numsendobjs = 0;
116 gcself_numreceiveobjs = 0;
117 gcmarkedptrbound = 0;
118 //mgchashCreate(2000, 0.75);
119 gcpointertbl = allocateRuntimeHash_I(20);
120 //gcpointertbl = allocateMGCHash(20);
121 gcforwardobjtbl = allocateMGCHash_I(20, 3);
133 gcsbstarttbl = BAMBOO_BASE_VA;
134 bamboo_smemtbl = (void *)gcsbstarttbl
135 + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
137 // create the lock table, lockresult table and obj queue
140 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
141 /* Set allocation blocks*/
142 locktable.listhead=NULL;
143 locktable.listtail=NULL;
145 locktable.numelements = 0;
150 lockRedirectTbl = allocateRuntimeHash_I(20);
151 objRedirectLockTbl = allocateRuntimeHash_I(20);
156 objqueue.head = NULL;
157 objqueue.tail = NULL;
163 //isInterrupt = true;
167 taskInfoOverflow = false;
169 interruptInfoIndex = 0;
170 interruptInfoOverflow = false;
173 for(i = 0; i < MAXTASKPARAMS; i++) {
174 runtime_locks[i].redirectlock = 0;
175 runtime_locks[i].value = 0;
180 inline __attribute__((always_inline))
181 void disruntimedata() {
184 freeRuntimeHash(gcpointertbl);
185 //freeMGCHash(gcpointertbl);
186 freeMGCHash(gcforwardobjtbl);
188 freeRuntimeHash(lockRedirectTbl);
189 freeRuntimeHash(objRedirectLockTbl);
190 RUNFREE(locktable.bucket);
192 if(activetasks != NULL) {
193 genfreehashtable(activetasks);
195 if(currtpd != NULL) {
196 RUNFREE(currtpd->parameterArray);
200 BAMBOO_LOCAL_MEM_CLOSE();
201 BAMBOO_SHARE_MEM_CLOSE();
204 inline __attribute__((always_inline))
205 bool checkObjQueue() {
207 struct transObjInfo * objInfo = NULL;
211 #ifdef ACCURATEPROFILE
212 bool isChecking = false;
213 if(!isEmpty(&objqueue)) {
214 profileTaskStart("objqueue checking");
216 } // if(!isEmpty(&objqueue))
220 while(!isEmpty(&objqueue)) {
222 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
224 BAMBOO_DEBUGPRINT(0xf001);
227 //isInterrupt = false;
230 BAMBOO_DEBUGPRINT(0xeee1);
233 objInfo = (struct transObjInfo *)getItem(&objqueue);
234 obj = objInfo->objptr;
236 BAMBOO_DEBUGPRINT_REG((int)obj);
238 // grab lock and flush the obj
242 BAMBOO_WAITING_FOR_LOCK(0);
243 // check for outgoing sends
245 extern inline void send_hanging_msg(bool);
246 send_hanging_msg(true);
248 } // while(!lockflag)
251 BAMBOO_DEBUGPRINT_REG(grount);
266 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
267 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
268 classsize[((struct ___Object___ *)obj)->type]);
270 // enqueue the object
271 for(k = 0; k < objInfo->length; ++k) {
272 int taskindex = objInfo->queues[2 * k];
273 int paramindex = objInfo->queues[2 * k + 1];
274 struct parameterwrapper ** queues =
275 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
277 BAMBOO_DEBUGPRINT_REG(taskindex);
278 BAMBOO_DEBUGPRINT_REG(paramindex);
279 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
280 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
281 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
282 (long)obj, tmpptr->flag);
284 enqueueObject_I(obj, queues, 1);
286 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
288 } // for(k = 0; k < objInfo->length; ++k)
289 releasewritelock_I(obj);
290 RUNFREE(objInfo->queues);
294 // put it at the end of the queue if no update version in the queue
295 struct QueueItem * qitem = getHead(&objqueue);
296 struct QueueItem * prev = NULL;
297 while(qitem != NULL) {
298 struct transObjInfo * tmpinfo =
299 (struct transObjInfo *)(qitem->objectptr);
300 if(tmpinfo->objptr == obj) {
301 // the same object in the queue, which should be enqueued
302 // recently. Current one is outdate, do not re-enqueue it
303 RUNFREE(objInfo->queues);
308 } // if(tmpinfo->objptr == obj)
309 qitem = getNextQueueItem(prev);
310 } // while(qitem != NULL)
311 // try to execute active tasks already enqueued first
312 addNewItem_I(&objqueue, objInfo);
314 //isInterrupt = true;
317 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
319 BAMBOO_DEBUGPRINT(0xf000);
323 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
325 BAMBOO_DEBUGPRINT(0xf000);
327 } // while(!isEmpty(&objqueue))
330 #ifdef ACCURATEPROFILE
338 BAMBOO_DEBUGPRINT(0xee02);
343 inline __attribute__((always_inline))
344 void checkCoreStatus() {
345 bool allStall = false;
349 (waitconfirm && (numconfirm == 0))) {
351 BAMBOO_DEBUGPRINT(0xee04);
352 BAMBOO_DEBUGPRINT_REG(waitconfirm);
354 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
356 BAMBOO_DEBUGPRINT(0xf001);
358 corestatus[BAMBOO_NUM_OF_CORE] = 0;
359 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
360 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
361 // check the status of all cores
364 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
366 for(i = 0; i < NUMCORESACTIVE; ++i) {
368 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
370 if(corestatus[i] != 0) {
374 } // for(i = 0; i < NUMCORESACTIVE; ++i)
376 // check if the sum of send objs and receive obj are the same
377 // yes->check if the info is the latest; no->go on executing
379 for(i = 0; i < NUMCORESACTIVE; ++i) {
380 sumsendobj += numsendobjs[i];
382 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
384 } // for(i = 0; i < NUMCORESACTIVE; ++i)
385 for(i = 0; i < NUMCORESACTIVE; ++i) {
386 sumsendobj -= numreceiveobjs[i];
388 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
390 } // for(i = 0; i < NUMCORESACTIVE; ++i)
391 if(0 == sumsendobj) {
393 // the first time found all cores stall
394 // send out status confirm msg to all other cores
395 // reset the corestatus array too
397 BAMBOO_DEBUGPRINT(0xee05);
399 corestatus[BAMBOO_NUM_OF_CORE] = 1;
401 numconfirm = NUMCORESACTIVE - 1;
402 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
403 for(i = 1; i < NUMCORESACTIVE; ++i) {
405 // send status confirm msg to core i
406 send_msg_1(i, STATUSCONFIRM);
407 } // for(i = 1; i < NUMCORESACTIVE; ++i)
410 // all the core status info are the latest
411 // terminate; for profiling mode, send request to all
412 // other cores to pour out profiling data
414 BAMBOO_DEBUGPRINT(0xee06);
418 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
421 //BAMBOO_DEBUGPRINT_REG(interrupttime);
424 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
425 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
426 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
428 // profile mode, send msgs to other cores to request pouring
429 // out progiling data
431 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
433 BAMBOO_DEBUGPRINT(0xf000);
435 for(i = 1; i < NUMCORESACTIVE; ++i) {
436 // send profile request msg to core i
437 send_msg_2(i, PROFILEOUTPUT, totalexetime);
438 } // for(i = 1; i < NUMCORESACTIVE; ++i)
439 // pour profiling data on startup core
442 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
444 BAMBOO_DEBUGPRINT(0xf001);
446 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
447 // check the status of all cores
450 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
452 for(i = 0; i < NUMCORESACTIVE; ++i) {
454 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
456 if(profilestatus[i] != 0) {
460 } // for(i = 0; i < NUMCORESACTIVE; ++i)
463 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
465 BAMBOO_DEBUGPRINT(0xf000);
470 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
476 // gc_profile mode, ourput gc prfiling data
479 gc_outputProfileData();
480 #endif // #ifdef GC_PROFILE
481 #endif // #ifdef MULTICORE_GC
483 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
484 terminate(); // All done.
485 } // if(!waitconfirm)
487 // still some objects on the fly on the network
488 // reset the waitconfirm and numconfirm
490 BAMBOO_DEBUGPRINT(0xee07);
494 } // if(0 == sumsendobj)
496 // not all cores are stall, keep on waiting
498 BAMBOO_DEBUGPRINT(0xee08);
503 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
505 BAMBOO_DEBUGPRINT(0xf000);
507 } // if((!waitconfirm) ||
510 // main function for each core
511 inline void run(void * arg) {
515 bool sendStall = false;
517 bool tocontinue = false;
519 corenum = BAMBOO_GET_NUM_OF_CORE();
521 BAMBOO_DEBUGPRINT(0xeeee);
522 BAMBOO_DEBUGPRINT_REG(corenum);
523 BAMBOO_DEBUGPRINT(STARTUPCORE);
526 // initialize runtime data structures
529 // other architecture related initialization
533 initializeexithandler();
535 // main process of the execution module
536 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
537 // non-executing cores, only processing communications
540 BAMBOO_DEBUGPRINT(0xee01);
541 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
542 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
543 profileTaskStart("msg handling");
547 //isInterrupt = false;
551 /* Create queue of active tasks */
553 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
554 (int (*)(void *,void *)) &comparetpd);
556 /* Process task information */
559 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
560 /* Create startup object */
561 createstartupobject(argc, argv);
565 BAMBOO_DEBUGPRINT(0xee00);
570 // check if need to do GC
574 // check if there are new active tasks can be executed
581 while(receiveObject() != -1) {
586 BAMBOO_DEBUGPRINT(0xee01);
589 // check if there are some pending objects,
590 // if yes, enqueue them and executetasks again
591 tocontinue = checkObjQueue();
595 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
598 BAMBOO_DEBUGPRINT(0xee03);
606 BAMBOO_DEBUGPRINT(0xee09);
612 // wait for some time
615 BAMBOO_DEBUGPRINT(0xee0a);
621 // send StallMsg to startup core
623 BAMBOO_DEBUGPRINT(0xee0b);
626 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
627 self_numsendobjs, self_numreceiveobjs);
639 BAMBOO_DEBUGPRINT(0xee0c);
642 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
645 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
649 struct ___createstartupobject____I_locals {
652 struct ___StartupObject___ * ___startupobject___;
653 struct ArrayObject * ___stringarray___;
654 }; // struct ___createstartupobject____I_locals
656 void createstartupobject(int argc,
660 /* Allocate startup object */
662 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
663 struct ___StartupObject___ *startupobject=
664 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
665 ___locals___.___startupobject___ = startupobject;
666 struct ArrayObject * stringarray=
667 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
668 ___locals___.___stringarray___ = stringarray;
670 struct ___StartupObject___ *startupobject=
671 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
672 struct ArrayObject * stringarray=
673 allocate_newarray(STRINGARRAYTYPE, argc-1);
675 /* Build array of strings */
676 startupobject->___parameters___=stringarray;
677 for(i=1; i<argc; i++) {
678 int length=strlen(argv[i]);
680 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
682 struct ___String___ *newstring=NewString(argv[i],length);
684 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
688 startupobject->version = 0;
689 startupobject->lock = NULL;
691 /* Set initialized flag for startup object */
692 flagorandinit(startupobject,1,0xFFFFFFFF);
693 enqueueObject(startupobject, NULL, 0);
695 BAMBOO_CACHE_FLUSH_ALL();
699 int hashCodetpd(struct taskparamdescriptor *ftd) {
700 int hash=(int)ftd->task;
702 for(i=0; i<ftd->numParameters; i++) {
703 hash^=(int)ftd->parameterArray[i];
708 int comparetpd(struct taskparamdescriptor *ftd1,
709 struct taskparamdescriptor *ftd2) {
711 if (ftd1->task!=ftd2->task)
713 for(i=0; i<ftd1->numParameters; i++)
714 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
719 /* This function sets a tag. */
721 void tagset(void *ptr,
722 struct ___Object___ * obj,
723 struct ___TagDescriptor___ * tagd) {
725 void tagset(struct ___Object___ * obj,
726 struct ___TagDescriptor___ * tagd) {
728 struct ArrayObject * ao=NULL;
729 struct ___Object___ * tagptr=obj->___tags___;
731 obj->___tags___=(struct ___Object___ *)tagd;
733 /* Have to check if it is already set */
734 if (tagptr->type==TAGTYPE) {
735 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
740 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
741 struct ArrayObject * ao=
742 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
743 obj=(struct ___Object___ *)ptrarray[2];
744 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
745 td=(struct ___TagDescriptor___ *) obj->___tags___;
747 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
750 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
751 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
752 obj->___tags___=(struct ___Object___ *) ao;
753 ao->___cachedCode___=2;
757 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
758 for(i=0; i<ao->___cachedCode___; i++) {
759 struct ___TagDescriptor___ * td=
760 ARRAYGET(ao, struct ___TagDescriptor___*, i);
765 if (ao->___cachedCode___<ao->___length___) {
766 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
767 ao->___cachedCode___++;
770 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
771 struct ArrayObject * aonew=
772 allocate_newarray(&ptrarray,TAGARRAYTYPE,
773 TAGARRAYINTERVAL+ao->___length___);
774 obj=(struct ___Object___ *)ptrarray[2];
775 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
776 ao=(struct ArrayObject *)obj->___tags___;
778 struct ArrayObject * aonew=
779 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
782 aonew->___cachedCode___=ao->___length___+1;
783 for(i=0; i<ao->___length___; i++) {
784 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
785 ARRAYGET(ao, struct ___TagDescriptor___*, i));
787 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
793 struct ___Object___ * tagset=tagd->flagptr;
796 } else if (tagset->type!=OBJECTARRAYTYPE) {
798 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
799 struct ArrayObject * ao=
800 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
801 obj=(struct ___Object___ *)ptrarray[2];
802 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
804 struct ArrayObject * ao=
805 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
807 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
808 ARRAYSET(ao, struct ___Object___ *, 1, obj);
809 ao->___cachedCode___=2;
810 tagd->flagptr=(struct ___Object___ *)ao;
812 struct ArrayObject *ao=(struct ArrayObject *) tagset;
813 if (ao->___cachedCode___<ao->___length___) {
814 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
818 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
819 struct ArrayObject * aonew=
820 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
821 OBJECTARRAYINTERVAL+ao->___length___);
822 obj=(struct ___Object___ *)ptrarray[2];
823 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
824 ao=(struct ArrayObject *)tagd->flagptr;
826 struct ArrayObject * aonew=
827 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
829 aonew->___cachedCode___=ao->___cachedCode___+1;
830 for(i=0; i<ao->___length___; i++) {
831 ARRAYSET(aonew, struct ___Object___*, i,
832 ARRAYGET(ao, struct ___Object___*, i));
834 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
835 tagd->flagptr=(struct ___Object___ *) aonew;
841 /* This function clears a tag. */
843 void tagclear(void *ptr,
844 struct ___Object___ * obj,
845 struct ___TagDescriptor___ * tagd) {
847 void tagclear(struct ___Object___ * obj,
848 struct ___TagDescriptor___ * tagd) {
850 /* We'll assume that tag is alway there.
851 Need to statically check for this of course. */
852 struct ___Object___ * tagptr=obj->___tags___;
854 if (tagptr->type==TAGTYPE) {
855 if ((struct ___TagDescriptor___ *)tagptr==tagd)
856 obj->___tags___=NULL;
858 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
860 for(i=0; i<ao->___cachedCode___; i++) {
861 struct ___TagDescriptor___ * td=
862 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
864 ao->___cachedCode___--;
865 if (i<ao->___cachedCode___)
866 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
867 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
868 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
869 if (ao->___cachedCode___==0)
870 obj->___tags___=NULL;
877 struct ___Object___ *tagset=tagd->flagptr;
878 if (tagset->type!=OBJECTARRAYTYPE) {
882 struct ArrayObject *ao=(struct ArrayObject *) tagset;
884 for(i=0; i<ao->___cachedCode___; i++) {
885 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
887 ao->___cachedCode___--;
888 if (i<ao->___cachedCode___)
889 ARRAYSET(ao, struct ___Object___ *, i,
890 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
891 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
892 if (ao->___cachedCode___==0)
903 /* This function allocates a new tag. */
905 struct ___TagDescriptor___ * allocate_tag(void *ptr,
907 struct ___TagDescriptor___ * v=
908 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
911 struct ___TagDescriptor___ * allocate_tag(int index) {
912 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
921 /* This function updates the flag for object ptr. It or's the flag
922 with the or mask and and's it with the andmask. */
924 void flagbody(struct ___Object___ *ptr,
926 struct parameterwrapper ** queues,
930 int flagcomp(const int *val1, const int *val2) {
931 return (*val1)-(*val2);
934 void flagorand(void * ptr,
937 struct parameterwrapper ** queues,
940 int oldflag=((int *)ptr)[1];
941 int flag=ormask|oldflag;
943 flagbody(ptr, flag, queues, length, false);
947 bool intflagorand(void * ptr,
951 int oldflag=((int *)ptr)[1];
952 int flag=ormask|oldflag;
954 if (flag==oldflag) /* Don't do anything */
957 flagbody(ptr, flag, NULL, 0, false);
963 void flagorandinit(void * ptr,
966 int oldflag=((int *)ptr)[1];
967 int flag=ormask|oldflag;
969 flagbody(ptr,flag,NULL,0,true);
972 void flagbody(struct ___Object___ *ptr,
974 struct parameterwrapper ** vqueues,
977 struct parameterwrapper * flagptr = NULL;
979 struct parameterwrapper ** queues = vqueues;
980 int length = vlength;
983 int * enterflags = NULL;
984 if((!isnew) && (queues == NULL)) {
985 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
986 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
987 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
994 /*Remove object from all queues */
995 for(i = 0; i < length; ++i) {
997 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
998 (int *) &enterflags, &UNUSED, &UNUSED2);
999 ObjectHashremove(flagptr->objectset, (int)ptr);
1000 if (enterflags!=NULL)
1001 RUNFREE(enterflags);
1005 void enqueueObject(void * vptr,
1006 struct parameterwrapper ** vqueues,
1008 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1011 //struct QueueItem *tmpptr;
1012 struct parameterwrapper * parameter=NULL;
1015 struct parameterwrapper * prevptr=NULL;
1016 struct ___Object___ *tagptr=NULL;
1017 struct parameterwrapper ** queues = vqueues;
1018 int length = vlength;
1019 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1022 if(queues == NULL) {
1023 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1024 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1026 tagptr=ptr->___tags___;
1028 /* Outer loop iterates through all parameter queues an object of
1029 this type could be in. */
1030 for(j = 0; j < length; ++j) {
1031 parameter = queues[j];
1033 if (parameter->numbertags>0) {
1035 goto nextloop; //that means the object has no tag
1036 //but that param needs tag
1037 else if(tagptr->type==TAGTYPE) { //one tag
1038 //struct ___TagDescriptor___ * tag=
1039 //(struct ___TagDescriptor___*) tagptr;
1040 for(i=0; i<parameter->numbertags; i++) {
1041 //slotid is parameter->tagarray[2*i];
1042 int tagid=parameter->tagarray[2*i+1];
1043 if (tagid!=tagptr->flag)
1044 goto nextloop; /*We don't have this tag */
1046 } else { //multiple tags
1047 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1048 for(i=0; i<parameter->numbertags; i++) {
1049 //slotid is parameter->tagarray[2*i];
1050 int tagid=parameter->tagarray[2*i+1];
1052 for(j=0; j<ao->___cachedCode___; j++) {
1053 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1064 for(i=0; i<parameter->numberofterms; i++) {
1065 int andmask=parameter->intarray[i*2];
1066 int checkmask=parameter->intarray[i*2+1];
1067 if ((ptr->flag&andmask)==checkmask) {
1068 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1079 void enqueueObject_I(void * vptr,
1080 struct parameterwrapper ** vqueues,
1082 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1085 //struct QueueItem *tmpptr;
1086 struct parameterwrapper * parameter=NULL;
1089 struct parameterwrapper * prevptr=NULL;
1090 struct ___Object___ *tagptr=NULL;
1091 struct parameterwrapper ** queues = vqueues;
1092 int length = vlength;
1093 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1096 if(queues == NULL) {
1097 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1098 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1100 tagptr=ptr->___tags___;
1102 /* Outer loop iterates through all parameter queues an object of
1103 this type could be in. */
1104 for(j = 0; j < length; ++j) {
1105 parameter = queues[j];
1107 if (parameter->numbertags>0) {
1109 goto nextloop; //that means the object has no tag
1110 //but that param needs tag
1111 else if(tagptr->type==TAGTYPE) { //one tag
1112 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1113 for(i=0; i<parameter->numbertags; i++) {
1114 //slotid is parameter->tagarray[2*i];
1115 int tagid=parameter->tagarray[2*i+1];
1116 if (tagid!=tagptr->flag)
1117 goto nextloop; /*We don't have this tag */
1119 } else { //multiple tags
1120 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1121 for(i=0; i<parameter->numbertags; i++) {
1122 //slotid is parameter->tagarray[2*i];
1123 int tagid=parameter->tagarray[2*i+1];
1125 for(j=0; j<ao->___cachedCode___; j++) {
1126 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1137 for(i=0; i<parameter->numberofterms; i++) {
1138 int andmask=parameter->intarray[i*2];
1139 int checkmask=parameter->intarray[i*2+1];
1140 if ((ptr->flag&andmask)==checkmask) {
1141 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1153 int * getAliasLock(void ** ptrs,
1155 struct RuntimeHash * tbl) {
1157 return (int*)(RUNMALLOC(sizeof(int)));
1162 bool redirect = false;
1163 int redirectlock = 0;
1164 for(; i < length; i++) {
1165 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1168 if(ptr->lock == NULL) {
1171 lock = (int)(ptr->lock);
1174 if(lock != redirectlock) {
1175 RuntimeHashadd(tbl, lock, redirectlock);
1178 if(RuntimeHashcontainskey(tbl, lock)) {
1179 // already redirected
1181 RuntimeHashget(tbl, lock, &redirectlock);
1182 for(; j < locklen; j++) {
1183 if(locks[j] != redirectlock) {
1184 RuntimeHashadd(tbl, locks[j], redirectlock);
1189 for(j = 0; j < locklen; j++) {
1190 if(locks[j] == lock) {
1193 } else if(locks[j] > lock) {
1200 locks[h] = locks[h-1];
1209 return (int *)redirectlock;
1211 return (int *)(locks[0]);
1216 void addAliasLock(void * ptr,
1218 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1219 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1220 // originally no alias lock associated or have a different alias lock
1221 // flush it as the new one
1222 obj->lock = (int *)lock;
1227 inline void setTaskExitIndex(int index) {
1228 taskInfoArray[taskInfoIndex]->exitIndex = index;
1231 inline void addNewObjInfo(void * nobj) {
1232 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1233 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1235 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1240 void * localmalloc_I(int coren,
1246 int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1247 int totest = tofindb;
1248 int bound = BAMBOO_SMEM_SIZE_L;
1252 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1253 int nsize = bamboo_smemtbl[totest];
1254 bool islocal = true;
1256 bool tocheck = true;
1257 // have some space in the block
1258 if(totest == tofindb) {
1259 // the first partition
1260 size = bound - nsize;
1261 } else if(nsize == 0) {
1262 // an empty partition, can be appended
1265 // not an empty partition, can not be appended
1266 // the last continuous block is not big enough, go to check the next
1270 } // if(totest == tofindb) else if(nsize == 0) else ...
1273 // have enough space in the block, malloc
1277 // no enough space yet, try to append next continuous block
1279 } // if(size > isize) else ...
1281 } // if(nsize < bound)
1283 // no space in the block, go to check the next block
1289 tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1292 } // if(islocal) else ...
1293 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1294 // no more local mem, do not find suitable block
1297 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1300 if(foundsmem == 1) {
1301 // find suitable block
1302 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1303 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1304 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1306 // set bamboo_smemtbl
1307 for(i = tofindb; i <= totest; i++) {
1308 bamboo_smemtbl[i]=(i<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1310 } else if(foundsmem == 2) {
1311 // no suitable block
1316 } // void * localmalloc_I(int, int, int *)
1318 void * globalmalloc_I(int coren,
1322 int tofindb = bamboo_free_block; //0;
1323 int totest = tofindb;
1324 int bound = BAMBOO_SMEM_SIZE_L;
1327 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1332 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1333 int nsize = bamboo_smemtbl[totest];
1334 bool isnext = false;
1336 bool tocheck = true;
1337 // have some space in the block
1338 if(totest == tofindb) {
1339 // the first partition
1340 size = bound - nsize;
1341 } else if(nsize == 0) {
1342 // an empty partition, can be appended
1345 // not an empty partition, can not be appended
1346 // the last continuous block is not big enough, start another block
1349 } // if(totest == tofindb) else if(nsize == 0) else ...
1352 // have enough space in the block, malloc
1355 } // if(size > isize)
1359 } // if(nsize < bound) else ...
1361 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1362 // no more local mem, do not find suitable block
1365 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1367 // start another block
1372 if(foundsmem == 1) {
1373 // find suitable block
1374 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1375 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1376 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1378 // set bamboo_smemtbl
1379 for(int i = tofindb; i <= totest; i++) {
1380 bamboo_smemtbl[i]=(i<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1382 if(tofindb == bamboo_free_block) {
1383 bamboo_free_block = totest+1;
1385 } else if(foundsmem == 2) {
1386 // no suitable block
1392 } // void * globalmalloc_I(int, int, int *)
1393 #endif // #ifdef MULTICORE_GC
1395 // malloc from the shared memory
1396 void * smemalloc_I(int coren,
1401 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1403 // go through the bamboo_smemtbl for suitable partitions
1404 switch(bamboo_smem_mode) {
1406 mem = localmalloc_I(coren, isize, allocsize);
1411 // TODO not supported yet
1412 BAMBOO_EXIT(0xe001);
1417 // TODO not supported yet
1418 BAMBOO_EXIT(0xe002);
1423 mem = globalmalloc_I(coren, isize, allocsize);
1435 /*if(!interruptInfoOverflow) {
1436 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1437 interruptInfoArray[interruptInfoIndex] = intInfo;
1438 intInfo->startTime = BAMBOO_GET_EXE_TIME();
1439 intInfo->endTime = -1;
1442 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1443 //mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1444 if(toallocate > bamboo_free_smem_size) {
1448 mem = (void *)bamboo_free_smemp;
1449 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1450 bamboo_free_smem_size -= toallocate;
1451 //BAMBOO_MEMSET_WH(mem, '\0', toallocate);
1453 *allocsize = toallocate;
1455 /*if(!interruptInfoOverflow) {
1456 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1457 interruptInfoIndex++;
1458 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1459 interruptInfoOverflow = true;
1464 #endif // MULTICORE_GC
1465 // no enough shared global memory
1471 BAMBOO_DEBUGPRINT(0xa001);
1472 BAMBOO_EXIT(0xa001);
1476 } // void * smemalloc_I(int, int, int)
1478 INLINE int checkMsgLength_I(int size) {
1481 BAMBOO_DEBUGPRINT(0xcccc);
1484 int type = msgdata[msgdataindex];
1504 case GCSTARTCOMPACT:
1530 case REDIRECTGROUNT:
1532 case REDIRECTRELEASE:
1545 case GCFINISHCOMPACT:
1559 case TRANSOBJ: // nonfixed size
1565 msglength = msgdata[msgdataindex+1];
1574 BAMBOO_DEBUGPRINT_REG(type);
1575 BAMBOO_DEBUGPRINT_REG(msgdataindex);
1578 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1580 BAMBOO_EXIT(0xd005);
1586 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1591 BAMBOO_DEBUGPRINT(0xffff);
1597 INLINE void processmsg_transobj_I() {
1599 struct transObjInfo * transObj = RUNMALLOC_I(sizeof(struct transObjInfo));
1603 BAMBOO_DEBUGPRINT(0xe880);
1606 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1608 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
1610 BAMBOO_EXIT(0xa002);
1612 // store the object and its corresponding queue info, enqueue it later
1613 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
1615 transObj->length = (msglength - 3) / 2;
1616 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1617 for(k = 0; k < transObj->length; ++k) {
1618 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
1622 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1625 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
1629 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1633 // check if there is an existing duplicate item
1635 struct QueueItem * qitem = getHead(&objqueue);
1636 struct QueueItem * prev = NULL;
1637 while(qitem != NULL) {
1638 struct transObjInfo * tmpinfo =
1639 (struct transObjInfo *)(qitem->objectptr);
1640 if(tmpinfo->objptr == transObj->objptr) {
1641 // the same object, remove outdate one
1642 RUNFREE(tmpinfo->queues);
1644 removeItem(&objqueue, qitem);
1650 qitem = getHead(&objqueue);
1652 qitem = getNextQueueItem(prev);
1655 addNewItem_I(&objqueue, (void *)transObj);
1657 ++(self_numreceiveobjs);
1660 INLINE void processmsg_transtall_I() {
1661 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1662 // non startup core can not receive stall msg
1664 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
1666 BAMBOO_EXIT(0xa003);
1668 int num_core = msgdata[msgdataindex]; //[1]
1670 if(num_core < NUMCORESACTIVE) {
1673 BAMBOO_DEBUGPRINT(0xe881);
1676 corestatus[num_core] = 0;
1677 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
1679 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
1684 #ifndef MULTICORE_GC
1685 INLINE void processmsg_lockrequest_I() {
1686 // check to see if there is a lock exist for the required obj
1687 // msgdata[1] -> lock type
1688 int locktype = msgdata[msgdataindex]; //[1];
1690 int data2 = msgdata[msgdataindex]; // obj pointer
1692 int data3 = msgdata[msgdataindex]; // lock
1694 int data4 = msgdata[msgdataindex]; // request core
1696 // -1: redirected, 0: approved, 1: denied
1697 int deny = processlockrequest(locktype, data3, data2, data4, data4, true);
1699 // this lock request is redirected
1702 // send response msg
1703 // for 32 bit machine, the size is always 4 words, cache the msg first
1704 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
1705 //if(isMsgSending) {
1706 cache_msg_4(data4, tmp, locktype, data2, data3);
1708 send_msg_4(data4, tmp, locktype, data2, data3);
1713 INLINE void processmsg_lockgrount_I() {
1715 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1717 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
1719 BAMBOO_EXIT(0xa004);
1721 int data2 = msgdata[msgdataindex];
1723 int data3 = msgdata[msgdataindex];
1725 if((lockobj == data2) && (lock2require == data3)) {
1728 BAMBOO_DEBUGPRINT(0xe882);
1737 // conflicts on lockresults
1739 BAMBOO_DEBUGPRINT_REG(data2);
1741 BAMBOO_EXIT(0xa005);
1745 INLINE void processmsg_lockdeny_I() {
1747 int data2 = msgdata[msgdataindex];
1749 int data3 = msgdata[msgdataindex];
1751 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1753 BAMBOO_DEBUGPRINT_REG(data2);
1755 BAMBOO_EXIT(0xa006);
1757 if((lockobj == data2) && (lock2require == data3)) {
1760 BAMBOO_DEBUGPRINT(0xe883);
1769 // conflicts on lockresults
1771 BAMBOO_DEBUGPRINT_REG(data2);
1773 BAMBOO_EXIT(0xa007);
1777 INLINE void processmsg_lockrelease_I() {
1778 int data1 = msgdata[msgdataindex];
1780 int data2 = msgdata[msgdataindex];
1782 // receive lock release msg
1783 processlockrelease(data1, data2, 0, false);
1786 INLINE void processmsg_redirectlock_I() {
1787 // check to see if there is a lock exist for the required obj
1788 int data1 = msgdata[msgdataindex];
1789 MSG_INDEXINC_I(); //msgdata[1]; // lock type
1790 int data2 = msgdata[msgdataindex];
1791 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
1792 int data3 = msgdata[msgdataindex];
1793 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
1794 int data4 = msgdata[msgdataindex];
1795 MSG_INDEXINC_I(); //msgdata[4]; // root request core
1796 int data5 = msgdata[msgdataindex];
1797 MSG_INDEXINC_I(); //msgdata[5]; // request core
1798 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
1800 // this lock request is redirected
1803 // send response msg
1804 // for 32 bit machine, the size is always 4 words, cache the msg first
1805 //if(isMsgSending) {
1806 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
1807 data1, data2, data3);
1809 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1810 data1, data2, data3);
1815 INLINE void processmsg_redirectgrount_I() {
1817 int data2 = msgdata[msgdataindex];
1819 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1821 BAMBOO_DEBUGPRINT_REG(data2);
1823 BAMBOO_EXIT(0xa00a);
1825 if(lockobj == data2) {
1828 BAMBOO_DEBUGPRINT(0xe891);
1831 int data3 = msgdata[msgdataindex];
1835 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
1840 // conflicts on lockresults
1842 BAMBOO_DEBUGPRINT_REG(data2);
1844 BAMBOO_EXIT(0xa00b);
1848 INLINE void processmsg_redirectdeny_I() {
1850 int data2 = msgdata[msgdataindex];
1852 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1854 BAMBOO_DEBUGPRINT_REG(data2);
1856 BAMBOO_EXIT(0xa00c);
1858 if(lockobj == data2) {
1861 BAMBOO_DEBUGPRINT(0xe892);
1870 // conflicts on lockresults
1872 BAMBOO_DEBUGPRINT_REG(data2);
1874 BAMBOO_EXIT(0xa00d);
1878 INLINE void processmsg_redirectrelease_I() {
1879 int data1 = msgdata[msgdataindex];
1881 int data2 = msgdata[msgdataindex];
1883 int data3 = msgdata[msgdataindex];
1885 processlockrelease(data1, data2, data3, true);
1887 #endif // #ifndef MULTICORE_GC
1890 INLINE void processmsg_profileoutput_I() {
1891 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1892 // startup core can not receive profile output finish msg
1893 BAMBOO_EXIT(0xa008);
1897 BAMBOO_DEBUGPRINT(0xe885);
1901 totalexetime = msgdata[msgdataindex]; //[1]
1903 outputProfileData();
1904 // cache the msg first
1905 //if(isMsgSending) {
1906 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1908 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1912 INLINE void processmsg_profilefinish_I() {
1913 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1914 // non startup core can not receive profile output finish msg
1916 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
1918 BAMBOO_EXIT(0xa009);
1922 BAMBOO_DEBUGPRINT(0xe886);
1925 int data1 = msgdata[msgdataindex];
1927 profilestatus[data1] = 0;
1929 #endif // #ifdef PROFILE
1931 INLINE void processmsg_statusconfirm_I() {
1932 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1933 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1934 // wrong core to receive such msg
1935 BAMBOO_EXIT(0xa00e);
1937 // send response msg
1940 BAMBOO_DEBUGPRINT(0xe887);
1943 // cache the msg first
1944 //if(isMsgSending) {
1945 cache_msg_5(STARTUPCORE, STATUSREPORT,
1946 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
1947 self_numsendobjs, self_numreceiveobjs);
1949 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
1950 BAMBOO_NUM_OF_CORE, self_numsendobjs,
1951 self_numreceiveobjs);
1956 INLINE void processmsg_statusreport_I() {
1957 int data1 = msgdata[msgdataindex];
1959 int data2 = msgdata[msgdataindex];
1961 int data3 = msgdata[msgdataindex];
1963 int data4 = msgdata[msgdataindex];
1965 // receive a status confirm info
1966 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1967 // wrong core to receive such msg
1969 BAMBOO_DEBUGPRINT_REG(data2);
1971 BAMBOO_EXIT(0xa00f);
1975 BAMBOO_DEBUGPRINT(0xe888);
1981 corestatus[data2] = data1;
1982 numsendobjs[data2] = data3;
1983 numreceiveobjs[data2] = data4;
1987 INLINE void processmsg_terminate_I() {
1990 BAMBOO_DEBUGPRINT(0xe889);
1997 INLINE void processmsg_memrequest_I() {
1999 if(!interruptInfoOverflow) {
2000 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2001 interruptInfoArray[interruptInfoIndex] = intInfo;
2002 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2003 intInfo->endTime = -1;
2006 int data1 = msgdata[msgdataindex];
2008 int data2 = msgdata[msgdataindex];
2010 // receive a shared memory request msg
2011 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2012 // wrong core to receive such msg
2014 BAMBOO_DEBUGPRINT_REG(data2);
2016 BAMBOO_EXIT(0xa010);
2020 BAMBOO_DEBUGPRINT(0xe88a);
2027 // is currently doing gc, dump this msg
2028 if(INITPHASE == gcphase) {
2029 // if still in the initphase of gc, send a startinit msg again,
2030 // cache the msg first
2031 //if(isMsgSending) {
2032 cache_msg_1(data2, GCSTARTINIT);
2034 send_msg_1(data2, GCSTARTINIT);
2039 mem = smemalloc_I(data2, data1, &allocsize);
2041 // send the start_va to request core, cache the msg first
2042 //if(isMsgSending) {
2043 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2045 send_msg_3(data2, MEMRESPONSE, mem, allocsize);
2047 } // if mem == NULL, the gcflag of the startup core has been set
2048 // and the gc should be started later, then a GCSTARTINIT msg
2049 // will be sent to the requesting core to notice it to start gc
2050 // and try malloc again
2056 if(!interruptInfoOverflow) {
2057 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2058 interruptInfoIndex++;
2059 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2060 interruptInfoOverflow = true;
2066 INLINE void processmsg_memresponse_I() {
2067 int data1 = msgdata[msgdataindex];
2069 int data2 = msgdata[msgdataindex];
2071 // receive a shared memory response msg
2074 BAMBOO_DEBUGPRINT(0xe88b);
2078 // if is currently doing gc, dump this msg
2082 bamboo_smem_size = 0;
2086 // fill header to store the size of this mem block
2087 memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2088 (*((int*)data1)) = data2;
2089 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2090 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2092 bamboo_smem_size = data2;
2093 bamboo_cur_msp =(void*)(data1);
2103 INLINE void processmsg_gcstartinit_I() {
2105 gcphase = INITPHASE;
2107 // is waiting for response of mem request
2108 // let it return NULL and start gc
2109 bamboo_smem_size = 0;
2110 bamboo_cur_msp = NULL;
2115 INLINE void processmsg_gcstart_I() {
2118 BAMBOO_DEBUGPRINT(0xe88c);
2122 gcphase = MARKPHASE;
2125 INLINE void processmsg_gcstartcompact_I() {
2126 gcblock2fill = msgdata[msgdataindex];
2127 MSG_INDEXINC_I(); //msgdata[1];
2128 gcphase = COMPACTPHASE;
2131 INLINE void processmsg_gcstartflush_I() {
2132 gcphase = FLUSHPHASE;
2135 INLINE void processmsg_gcfinishinit_I() {
2136 int data1 = msgdata[msgdataindex];
2138 // received a init phase finish msg
2139 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2140 // non startup core can not receive this msg
2142 BAMBOO_DEBUGPRINT_REG(data1);
2144 BAMBOO_EXIT(0xb001);
2147 BAMBOO_DEBUGPRINT(0xe88c);
2148 BAMBOO_DEBUGPRINT_REG(data1);
2150 // All cores should do init GC
2151 if(data1 < NUMCORESACTIVE) {
2152 gccorestatus[data1] = 0;
2156 INLINE void processmsg_gcfinishmark_I() {
2157 int data1 = msgdata[msgdataindex];
2159 int data2 = msgdata[msgdataindex];
2161 int data3 = msgdata[msgdataindex];
2163 // received a mark phase finish msg
2164 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2165 // non startup core can not receive this msg
2167 BAMBOO_DEBUGPRINT_REG(data1);
2169 BAMBOO_EXIT(0xb002);
2171 // all cores should do mark
2172 if(data1 < NUMCORESACTIVE) {
2173 gccorestatus[data1] = 0;
2174 gcnumsendobjs[data1] = data2;
2175 gcnumreceiveobjs[data1] = data3;
2179 INLINE void processmsg_gcfinishcompact_I() {
2180 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2181 // non startup core can not receive this msg
2184 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2186 BAMBOO_EXIT(0xb003);
2188 int cnum = msgdata[msgdataindex];
2189 MSG_INDEXINC_I(); //msgdata[1];
2190 int filledblocks = msgdata[msgdataindex];
2191 MSG_INDEXINC_I(); //msgdata[2];
2192 int heaptop = msgdata[msgdataindex];
2193 MSG_INDEXINC_I(); //msgdata[3];
2194 int data4 = msgdata[msgdataindex];
2195 MSG_INDEXINC_I(); //msgdata[4];
2196 // only gc cores need to do compact
2197 if(cnum < NUMCORES4GC) {
2198 if(COMPACTPHASE == gcphase) {
2199 gcfilledblocks[cnum] = filledblocks;
2200 gcloads[cnum] = heaptop;
2207 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2208 // cache the msg first
2209 //if(isMsgSending) {
2210 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2212 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2216 gccorestatus[cnum] = 0;
2218 } // if(cnum < NUMCORES4GC)
2221 INLINE void processmsg_gcfinishflush_I() {
2222 int data1 = msgdata[msgdataindex];
2224 // received a flush phase finish msg
2225 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2226 // non startup core can not receive this msg
2229 BAMBOO_DEBUGPRINT_REG(data1);
2231 BAMBOO_EXIT(0xb004);
2233 // all cores should do flush
2234 if(data1 < NUMCORESACTIVE) {
2235 gccorestatus[data1] = 0;
2239 INLINE void processmsg_gcmarkconfirm_I() {
2240 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2241 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2242 // wrong core to receive such msg
2243 BAMBOO_EXIT(0xb005);
2245 // send response msg, cahce the msg first
2246 //if(isMsgSending) {
2247 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2248 gcbusystatus, gcself_numsendobjs,
2249 gcself_numreceiveobjs);
2251 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2252 gcbusystatus, gcself_numsendobjs,
2253 gcself_numreceiveobjs);
2258 INLINE void processmsg_gcmarkreport_I() {
2259 int data1 = msgdata[msgdataindex];
2261 int data2 = msgdata[msgdataindex];
2263 int data3 = msgdata[msgdataindex];
2265 int data4 = msgdata[msgdataindex];
2267 // received a marked phase finish confirm response msg
2268 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2269 // wrong core to receive such msg
2271 BAMBOO_DEBUGPRINT_REG(data2);
2273 BAMBOO_EXIT(0xb006);
2278 gccorestatus[data1] = data2;
2279 gcnumsendobjs[data1] = data3;
2280 gcnumreceiveobjs[data1] = data4;
2284 INLINE void processmsg_gcmarkedobj_I() {
2285 int data1 = msgdata[msgdataindex];
2287 // received a markedObj msg
2288 if(((int *)data1)[6] == INIT) {
2289 // this is the first time that this object is discovered,
2290 // set the flag as DISCOVERED
2291 ((int *)data1)[6] = DISCOVERED;
2292 gc_enqueue_I(data1);
2294 gcself_numreceiveobjs++;
2295 gcbusystatus = true;
2298 INLINE void processmsg_gcmovestart_I() {
2300 gcdstcore = msgdata[msgdataindex];
2301 MSG_INDEXINC_I(); //msgdata[1];
2302 gcmovestartaddr = msgdata[msgdataindex];
2303 MSG_INDEXINC_I(); //msgdata[2];
2304 gcblock2fill = msgdata[msgdataindex];
2305 MSG_INDEXINC_I(); //msgdata[3];
2308 INLINE void processmsg_gcmaprequest_I() {
2310 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2312 void * dstptr = NULL;
2313 int data1 = msgdata[msgdataindex];
2315 //dstptr = mgchashSearch(msgdata[1]);
2317 unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2319 RuntimeHashget(gcpointertbl, data1, &dstptr);
2321 flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2323 int data2 = msgdata[msgdataindex];
2325 //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2327 unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2329 if(NULL == dstptr) {
2330 // no such pointer in this core, something is wrong
2332 BAMBOO_DEBUGPRINT_REG(data1);
2333 BAMBOO_DEBUGPRINT_REG(data2);
2335 BAMBOO_EXIT(0xb007);
2336 //assume that the object was not moved, use the original address
2337 /*if(isMsgSending) {
2338 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2340 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2343 // send back the mapping info, cache the msg first
2344 //if(isMsgSending) {
2345 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2347 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2351 flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2352 //num_mapinforequest_i++;
2356 INLINE void processmsg_gcmapinfo_I() {
2358 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2360 int data1 = msgdata[msgdataindex];
2362 if(data1 != gcobj2map) {
2363 // obj not matched, something is wrong
2365 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2366 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2368 BAMBOO_EXIT(0xb008);
2370 gcmappedobj = msgdata[msgdataindex]; // [2]
2372 //mgchashReplace_I(msgdata[1], msgdata[2]);
2373 //mgchashInsert_I(gcobj2map, gcmappedobj);
2374 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2375 //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2379 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2383 INLINE void processmsg_gclobjinfo_I() {
2386 int data1 = msgdata[msgdataindex];
2388 int data2 = msgdata[msgdataindex];
2390 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2392 BAMBOO_DEBUGPRINT_REG(data2);
2394 BAMBOO_EXIT(0xb009);
2396 // store the mark result info
2398 gcloads[cnum] = msgdata[msgdataindex];
2399 MSG_INDEXINC_I(); // msgdata[3];
2400 int data4 = msgdata[msgdataindex];
2402 if(gcheaptop < data4) {
2405 // large obj info here
2406 for(int k = 5; k < data1; ) {
2407 int lobj = msgdata[msgdataindex];
2408 MSG_INDEXINC_I(); //msgdata[k++];
2409 int length = msgdata[msgdataindex];
2410 MSG_INDEXINC_I(); //msgdata[k++];
2411 gc_lobjenqueue_I(lobj, length, cnum);
2413 } // for(int k = 5; k < msgdata[1];)
2416 INLINE void processmsg_gclobjmapping_I() {
2417 int data1 = msgdata[msgdataindex];
2419 int data2 = msgdata[msgdataindex];
2421 //mgchashInsert_I(msgdata[1], msgdata[2]);
2422 RuntimeHashadd_I(gcpointertbl, data1, data2);
2423 //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2425 #endif // #ifdef MULTICORE_GC
2427 // receive object transferred from other cores
2428 // or the terminate message from other cores
2429 // Should be invoked in critical sections!!
2430 // NOTICE: following format is for threadsimulate version only
2431 // RAW version please see previous description
2432 // format: type + object
2433 // type: -1--stall msg
2435 // return value: 0--received an object
2436 // 1--received nothing
2437 // 2--received a Stall Msg
2438 // 3--received a lock Msg
2439 // RAW version: -1 -- received nothing
2440 // otherwise -- received msg type
2441 int receiveObject(int send_port_pending) {
2443 // get the incoming msgs
2444 if(receiveMsg(send_port_pending) == -1) {
2448 // processing received msgs
2450 MSG_REMAINSIZE_I(&size);
2451 if((size == 0) || (checkMsgLength_I(size) == -1)) {
2453 // have new coming msg
2454 if(BAMBOO_MSG_AVAIL() != 0) {
2461 if(msglength <= size) {
2462 // have some whole msg
2463 //if(msgdataindex == msglength) {
2464 // received a whole msg
2466 type = msgdata[msgdataindex]; //[0]
2468 msgdatafull = false;
2470 //tprintf("msg type: %x\n", type);
2473 // receive a object transfer msg
2474 processmsg_transobj_I();
2479 // receive a stall msg
2480 processmsg_transtall_I();
2484 // GC version have no lock msgs
2485 #ifndef MULTICORE_GC
2487 // receive lock request msg, handle it right now
2488 processmsg_lockrequest_I();
2490 } // case LOCKREQUEST
2493 // receive lock grount msg
2494 processmsg_lockgrount_I();
2496 } // case LOCKGROUNT
2499 // receive lock deny msg
2500 processmsg_lockdeny_I();
2505 processmsg_lockrelease_I();
2507 } // case LOCKRELEASE
2508 #endif // #ifndef MULTICORE_GC
2511 case PROFILEOUTPUT: {
2512 // receive an output profile data request msg
2513 processmsg_profileoutput_I();
2515 } // case PROFILEOUTPUT
2517 case PROFILEFINISH: {
2518 // receive a profile output finish msg
2519 processmsg_profilefinish_I();
2521 } // case PROFILEFINISH
2522 #endif // #ifdef PROFILE
2524 // GC version has no lock msgs
2525 #ifndef MULTICORE_GC
2526 case REDIRECTLOCK: {
2527 // receive a redirect lock request msg, handle it right now
2528 processmsg_redirectlock_I();
2530 } // case REDIRECTLOCK
2532 case REDIRECTGROUNT: {
2533 // receive a lock grant msg with redirect info
2534 processmsg_redirectgrount_I();
2536 } // case REDIRECTGROUNT
2538 case REDIRECTDENY: {
2539 // receive a lock deny msg with redirect info
2540 processmsg_redirectdeny_I();
2542 } // case REDIRECTDENY
2544 case REDIRECTRELEASE: {
2545 // receive a lock release msg with redirect info
2546 processmsg_redirectrelease_I();
2548 } // case REDIRECTRELEASE
2549 #endif // #ifndef MULTICORE_GC
2551 case STATUSCONFIRM: {
2552 // receive a status confirm info
2553 processmsg_statusconfirm_I();
2555 } // case STATUSCONFIRM
2557 case STATUSREPORT: {
2558 processmsg_statusreport_I();
2560 } // case STATUSREPORT
2563 // receive a terminate msg
2564 processmsg_terminate_I();
2569 processmsg_memrequest_I();
2571 } // case MEMREQUEST
2574 processmsg_memresponse_I();
2576 } // case MEMRESPONSE
2581 processmsg_gcstartinit_I();
2583 } // case GCSTARTINIT
2586 // receive a start GC msg
2587 processmsg_gcstart_I();
2591 case GCSTARTCOMPACT: {
2592 // a compact phase start msg
2593 processmsg_gcstartcompact_I();
2595 } // case GCSTARTCOMPACT
2597 case GCSTARTFLUSH: {
2598 // received a flush phase start msg
2599 processmsg_gcstartflush_I();
2601 } // case GCSTARTFLUSH
2603 case GCFINISHINIT: {
2604 processmsg_gcfinishinit_I();
2606 } // case GCFINISHINIT
2608 case GCFINISHMARK: {
2609 processmsg_gcfinishmark_I();
2611 } // case GCFINISHMARK
2613 case GCFINISHCOMPACT: {
2614 // received a compact phase finish msg
2615 processmsg_gcfinishcompact_I();
2617 } // case GCFINISHCOMPACT
2619 case GCFINISHFLUSH: {
2620 processmsg_gcfinishflush_I();
2622 } // case GCFINISHFLUSH
2625 // received a GC finish msg
2626 gcphase = FINISHPHASE;
2630 case GCMARKCONFIRM: {
2631 // received a marked phase finish confirm request msg
2632 // all cores should do mark
2633 processmsg_gcmarkconfirm_I();
2635 } // case GCMARKCONFIRM
2637 case GCMARKREPORT: {
2638 processmsg_gcmarkreport_I();
2640 } // case GCMARKREPORT
2643 processmsg_gcmarkedobj_I();
2645 } // case GCMARKEDOBJ
2648 // received a start moving objs msg
2649 processmsg_gcmovestart_I();
2651 } // case GCMOVESTART
2653 case GCMAPREQUEST: {
2654 // received a mapping info request msg
2655 processmsg_gcmaprequest_I();
2657 } // case GCMAPREQUEST
2660 // received a mapping info response msg
2661 processmsg_gcmapinfo_I();
2665 case GCLOBJREQUEST: {
2666 // received a large objs info request msg
2667 transferMarkResults_I();
2669 } // case GCLOBJREQUEST
2672 // received a large objs info response msg
2673 processmsg_gclobjinfo_I();
2675 } // case GCLOBJINFO
2677 case GCLOBJMAPPING: {
2678 // received a large obj mapping info msg
2679 processmsg_gclobjmapping_I();
2681 } // case GCLOBJMAPPING
2683 #endif // #ifdef MULTICORE_GC
2688 //memset(msgdata, '\0', sizeof(int) * msgdataindex);
2690 msglength = BAMBOO_MSG_BUF_LENGTH;
2692 //printf("++ msg: %x \n", type);
2693 if(msgdataindex != msgdatalast) {
2694 // still have available msg
2699 BAMBOO_DEBUGPRINT(0xe88d);
2703 // have new coming msg
2704 if(BAMBOO_MSG_AVAIL() != 0) {
2718 BAMBOO_DEBUGPRINT(0xe88e);
2722 /* if(isInterrupt) {
2730 int enqueuetasks(struct parameterwrapper *parameter,
2731 struct parameterwrapper *prevptr,
2732 struct ___Object___ *ptr,
2734 int numenterflags) {
2735 void * taskpointerarray[MAXTASKPARAMS];
2737 //int numparams=parameter->task->numParameters;
2738 int numiterators=parameter->task->numTotal-1;
2741 struct taskdescriptor * task=parameter->task;
2743 //this add the object to parameterwrapper
2744 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
2745 numenterflags, enterflags==NULL);
2747 /* Add enqueued object to parameter vector */
2748 taskpointerarray[parameter->slot]=ptr;
2750 /* Reset iterators */
2751 for(j=0; j<numiterators; j++) {
2752 toiReset(¶meter->iterators[j]);
2755 /* Find initial state */
2756 for(j=0; j<numiterators; j++) {
2758 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2759 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2761 /* Need to backtrack */
2762 toiReset(¶meter->iterators[j]);
2766 /* Nothing to enqueue */
2772 /* Enqueue current state */
2774 struct taskparamdescriptor *tpd=
2775 RUNMALLOC(sizeof(struct taskparamdescriptor));
2777 tpd->numParameters=numiterators+1;
2778 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2780 for(j=0; j<=numiterators; j++) {
2781 //store the actual parameters
2782 tpd->parameterArray[j]=taskpointerarray[j];
2785 if (( /*!gencontains(failedtasks, tpd)&&*/
2786 !gencontains(activetasks,tpd))) {
2787 genputtable(activetasks, tpd, tpd);
2789 RUNFREE(tpd->parameterArray);
2793 /* This loop iterates to the next parameter combination */
2794 if (numiterators==0)
2797 for(j=numiterators-1; j<numiterators; j++) {
2799 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2800 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2802 /* Need to backtrack */
2803 toiReset(¶meter->iterators[j]);
2807 /* Nothing more to enqueue */
2815 int enqueuetasks_I(struct parameterwrapper *parameter,
2816 struct parameterwrapper *prevptr,
2817 struct ___Object___ *ptr,
2819 int numenterflags) {
2820 void * taskpointerarray[MAXTASKPARAMS];
2822 //int numparams=parameter->task->numParameters;
2823 int numiterators=parameter->task->numTotal-1;
2828 struct taskdescriptor * task=parameter->task;
2830 //this add the object to parameterwrapper
2831 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2832 numenterflags, enterflags==NULL);
2834 /* Add enqueued object to parameter vector */
2835 taskpointerarray[parameter->slot]=ptr;
2837 /* Reset iterators */
2838 for(j=0; j<numiterators; j++) {
2839 toiReset(¶meter->iterators[j]);
2842 /* Find initial state */
2843 for(j=0; j<numiterators; j++) {
2845 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2846 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2848 /* Need to backtrack */
2849 toiReset(¶meter->iterators[j]);
2853 /* Nothing to enqueue */
2859 /* Enqueue current state */
2861 struct taskparamdescriptor *tpd=
2862 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2864 tpd->numParameters=numiterators+1;
2865 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2867 for(j=0; j<=numiterators; j++) {
2868 //store the actual parameters
2869 tpd->parameterArray[j]=taskpointerarray[j];
2872 if (( /*!gencontains(failedtasks, tpd)&&*/
2873 !gencontains(activetasks,tpd))) {
2874 genputtable_I(activetasks, tpd, tpd);
2876 RUNFREE(tpd->parameterArray);
2880 /* This loop iterates to the next parameter combination */
2881 if (numiterators==0)
2884 for(j=numiterators-1; j<numiterators; j++) {
2886 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2887 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2889 /* Need to backtrack */
2890 toiReset(¶meter->iterators[j]);
2894 /* Nothing more to enqueue */
2908 int containstag(struct ___Object___ *ptr,
2909 struct ___TagDescriptor___ *tag);
2911 #ifndef MULTICORE_GC
2912 void releasewritelock_r(void * lock, void * redirectlock) {
2914 int reallock = (int)lock;
2915 targetcore = (reallock >> 5) % NUMCORES;
2918 BAMBOO_DEBUGPRINT(0xe671);
2919 BAMBOO_DEBUGPRINT_REG((int)lock);
2920 BAMBOO_DEBUGPRINT_REG(reallock);
2921 BAMBOO_DEBUGPRINT_REG(targetcore);
2924 if(targetcore == BAMBOO_NUM_OF_CORE) {
2925 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2927 BAMBOO_DEBUGPRINT(0xf001);
2929 // reside on this core
2930 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2931 // no locks for this object, something is wrong
2932 BAMBOO_EXIT(0xa011);
2935 struct LockValue * lockvalue = NULL;
2937 BAMBOO_DEBUGPRINT(0xe672);
2939 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2940 lockvalue = (struct LockValue *)rwlock_obj;
2942 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2945 lockvalue->redirectlock = (int)redirectlock;
2947 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2950 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2952 BAMBOO_DEBUGPRINT(0xf000);
2956 // send lock release with redirect info msg
2957 // for 32 bit machine, the size is always 4 words
2958 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
2964 void executetasks() {
2965 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2968 struct ___Object___ * tmpparam = NULL;
2969 struct parameterdescriptor * pd=NULL;
2970 struct parameterwrapper *pw=NULL;
2980 while(hashsize(activetasks)>0) {
2985 BAMBOO_DEBUGPRINT(0xe990);
2988 /* See if there are any active tasks */
2989 //if (hashsize(activetasks)>0) {
2992 #ifdef ACCURATEPROFILE
2993 profileTaskStart("tpd checking");
2997 //clock1 = BAMBOO_GET_EXE_TIME();
3000 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3001 genfreekey(activetasks, currtpd);
3003 numparams=currtpd->task->numParameters;
3004 numtotal=currtpd->task->numTotal;
3006 // clear the lockRedirectTbl
3007 // (TODO, this table should be empty after all locks are released)
3009 /*for(j = 0; j < MAXTASKPARAMS; j++) {
3010 runtime_locks[j].redirectlock = 0;
3011 runtime_locks[j].value = 0;
3013 // get all required locks
3014 runtime_locklen = 0;
3015 // check which locks are needed
3016 for(i = 0; i < numparams; i++) {
3017 void * param = currtpd->parameterArray[i];
3021 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3023 taskpointerarray[i+OFFSET]=param;
3026 if(((struct ___Object___ *)param)->lock == NULL) {
3027 tmplock = (int)param;
3029 tmplock = (int)(((struct ___Object___ *)param)->lock);
3031 // insert into the locks array
3032 for(j = 0; j < runtime_locklen; j++) {
3033 if(runtime_locks[j].value == tmplock) {
3036 } else if(runtime_locks[j].value > tmplock) {
3041 int h = runtime_locklen;
3043 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3044 runtime_locks[h].value = runtime_locks[h-1].value;
3046 runtime_locks[j].value = tmplock;
3047 runtime_locks[j].redirectlock = (int)param;
3050 } // line 2713: for(i = 0; i < numparams; i++)
3051 // grab these required locks
3053 BAMBOO_DEBUGPRINT(0xe991);
3056 //clock2 = BAMBOO_GET_EXE_TIME();
3058 for(i = 0; i < runtime_locklen; i++) {
3059 int * lock = (int *)(runtime_locks[i].redirectlock);
3061 // require locks for this parameter if it is not a startup object
3063 BAMBOO_DEBUGPRINT_REG((int)lock);
3064 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3067 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3069 BAMBOO_DEBUGPRINT(0xf001);
3072 //isInterrupt = false;
3075 BAMBOO_WAITING_FOR_LOCK(0);
3076 // check for outgoing sends
3078 extern inline void send_hanging_msg(bool);
3079 send_hanging_msg(true);
3084 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3085 // check for outgoing sends
3087 extern inline void send_hanging_msg(bool);
3088 send_hanging_msg(true);
3093 grount = lockresult;
3103 //isInterrupt = true;
3105 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3107 BAMBOO_DEBUGPRINT(0xf000);
3112 BAMBOO_DEBUGPRINT(0xe992);
3113 BAMBOO_DEBUGPRINT_REG(lock);
3115 // check if has the lock already
3116 // can not get the lock, try later
3117 // release all grabbed locks for previous parameters
3118 for(j = 0; j < i; ++j) {
3119 lock = (int*)(runtime_locks[j].redirectlock);
3120 releasewritelock(lock);
3122 genputtable(activetasks, currtpd, currtpd);
3123 if(hashsize(activetasks) == 1) {
3124 // only one task right now, wait a little while before next try
3130 #ifdef ACCURATEPROFILE
3131 // fail, set the end of the checkTaskInfo
3138 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3141 clock3 = BAMBOO_GET_EXE_TIME();
3142 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3145 BAMBOO_DEBUGPRINT(0xe993);
3147 /* Make sure that the parameters are still in the queues */
3148 for(i=0; i<numparams; i++) {
3149 void * parameter=currtpd->parameterArray[i];
3153 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3154 classsize[((struct ___Object___ *)parameter)->type]);
3156 tmpparam = (struct ___Object___ *)parameter;
3157 pd=currtpd->task->descriptorarray[i];
3158 pw=(struct parameterwrapper *) pd->queue;
3159 /* Check that object is still in queue */
3161 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3163 BAMBOO_DEBUGPRINT(0xe994);
3164 BAMBOO_DEBUGPRINT_REG(parameter);
3166 // release grabbed locks
3167 for(j = 0; j < runtime_locklen; ++j) {
3168 int * lock = (int *)(runtime_locks[j].redirectlock);
3169 releasewritelock(lock);
3171 RUNFREE(currtpd->parameterArray);
3177 /* Check if the object's flags still meets requirements */
3181 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3182 andmask=pw->intarray[tmpi*2];
3183 checkmask=pw->intarray[tmpi*2+1];
3184 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3190 // flags are never suitable
3191 // remove this obj from the queue
3193 int UNUSED, UNUSED2;
3196 BAMBOO_DEBUGPRINT(0xe995);
3197 BAMBOO_DEBUGPRINT_REG(parameter);
3199 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3200 (int *) &enterflags, &UNUSED, &UNUSED2);
3201 ObjectHashremove(pw->objectset, (int)parameter);
3202 if (enterflags!=NULL)
3203 RUNFREE(enterflags);
3204 // release grabbed locks
3205 for(j = 0; j < runtime_locklen; ++j) {
3206 int * lock = (int *)(runtime_locks[j].redirectlock);
3207 releasewritelock(lock);
3209 RUNFREE(currtpd->parameterArray);
3213 #ifdef ACCURATEPROFILE
3214 // fail, set the end of the checkTaskInfo
3219 } // line 2878: if (!ismet)
3223 /* Check that object still has necessary tags */
3224 for(j=0; j<pd->numbertags; j++) {
3225 int slotid=pd->tagarray[2*j]+numparams;
3226 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3227 if (!containstag(parameter, tagd)) {
3229 BAMBOO_DEBUGPRINT(0xe996);
3232 // release grabbed locks
3234 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3235 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3236 releasewritelock(lock);
3239 RUNFREE(currtpd->parameterArray);
3243 } // line2911: if (!containstag(parameter, tagd))
3244 } // line 2808: for(j=0; j<pd->numbertags; j++)
3246 taskpointerarray[i+OFFSET]=parameter;
3247 } // line 2824: for(i=0; i<numparams; i++)
3249 for(; i<numtotal; i++) {
3250 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3255 /* Actually call task */
3257 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3258 taskpointerarray[1]=NULL;
3261 #ifdef ACCURATEPROFILE
3262 // check finish, set the end of the checkTaskInfo
3265 profileTaskStart(currtpd->task->name);
3269 //clock4 = BAMBOO_GET_EXE_TIME();
3270 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3273 BAMBOO_DEBUGPRINT(0xe997);
3275 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3278 //clock5 = BAMBOO_GET_EXE_TIME();
3279 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3282 #ifdef ACCURATEPROFILE
3283 // task finish, set the end of the checkTaskInfo
3285 // new a PostTaskInfo for the post-task execution
3286 profileTaskStart("post task execution");
3290 BAMBOO_DEBUGPRINT(0xe998);
3291 BAMBOO_DEBUGPRINT_REG(islock);
3296 BAMBOO_DEBUGPRINT(0xe999);
3298 for(i = 0; i < runtime_locklen; ++i) {
3299 void * ptr = (void *)(runtime_locks[i].redirectlock);
3300 int * lock = (int *)(runtime_locks[i].value);
3302 BAMBOO_DEBUGPRINT_REG((int)ptr);
3303 BAMBOO_DEBUGPRINT_REG((int)lock);
3304 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3306 #ifndef MULTICORE_GC
3307 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3309 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3310 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3311 releasewritelock_r(lock, (int *)redirectlock);
3316 releasewritelock(ptr);
3319 } // line 3015: if(islock)
3322 //clock6 = BAMBOO_GET_EXE_TIME();
3323 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3326 // post task execution finish, set the end of the postTaskInfo
3330 // Free up task parameter descriptor
3331 RUNFREE(currtpd->parameterArray);
3335 BAMBOO_DEBUGPRINT(0xe99a);
3338 //clock7 = BAMBOO_GET_EXE_TIME();
3339 //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));
3342 //} // if (hashsize(activetasks)>0)
3343 } // while(hashsize(activetasks)>0)
3345 BAMBOO_DEBUGPRINT(0xe99b);
3349 /* This function processes an objects tags */
3350 void processtags(struct parameterdescriptor *pd,
3352 struct parameterwrapper *parameter,
3353 int * iteratorcount,
3358 for(i=0; i<pd->numbertags; i++) {
3359 int slotid=pd->tagarray[2*i];
3360 int tagid=pd->tagarray[2*i+1];
3362 if (statusarray[slotid+numparams]==0) {
3363 parameter->iterators[*iteratorcount].istag=1;
3364 parameter->iterators[*iteratorcount].tagid=tagid;
3365 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3366 parameter->iterators[*iteratorcount].tagobjectslot=index;
3367 statusarray[slotid+numparams]=1;
3374 void processobject(struct parameterwrapper *parameter,
3376 struct parameterdescriptor *pd,
3382 struct ObjectHash * objectset=
3383 ((struct parameterwrapper *)pd->queue)->objectset;
3385 parameter->iterators[*iteratorcount].istag=0;
3386 parameter->iterators[*iteratorcount].slot=index;
3387 parameter->iterators[*iteratorcount].objectset=objectset;
3388 statusarray[index]=1;
3390 for(i=0; i<pd->numbertags; i++) {
3391 int slotid=pd->tagarray[2*i];
3392 //int tagid=pd->tagarray[2*i+1];
3393 if (statusarray[slotid+numparams]!=0) {
3394 /* This tag has already been enqueued, use it to narrow search */
3395 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3400 parameter->iterators[*iteratorcount].numtags=tagcount;
3405 /* This function builds the iterators for a task & parameter */
3407 void builditerators(struct taskdescriptor * task,
3409 struct parameterwrapper * parameter) {
3410 int statusarray[MAXTASKPARAMS];
3412 int numparams=task->numParameters;
3413 int iteratorcount=0;
3414 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3416 statusarray[index]=1; /* Initial parameter */
3417 /* Process tags for initial iterator */
3419 processtags(task->descriptorarray[index], index, parameter,
3420 &iteratorcount, statusarray, numparams);
3424 /* Check for objects with existing tags */
3425 for(i=0; i<numparams; i++) {
3426 if (statusarray[i]==0) {
3427 struct parameterdescriptor *pd=task->descriptorarray[i];
3429 for(j=0; j<pd->numbertags; j++) {
3430 int slotid=pd->tagarray[2*j];
3431 if(statusarray[slotid+numparams]!=0) {
3432 processobject(parameter, i, pd, &iteratorcount, statusarray,
3434 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3441 /* Next do objects w/ unbound tags*/
3443 for(i=0; i<numparams; i++) {
3444 if (statusarray[i]==0) {
3445 struct parameterdescriptor *pd=task->descriptorarray[i];
3446 if (pd->numbertags>0) {
3447 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3448 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3454 /* Nothing with a tag enqueued */
3456 for(i=0; i<numparams; i++) {
3457 if (statusarray[i]==0) {
3458 struct parameterdescriptor *pd=task->descriptorarray[i];
3459 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3460 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3473 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3476 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3477 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3479 printf("%s\n", task->name);
3481 for(j=0; j<task->numParameters; j++) {
3482 struct parameterdescriptor *param=task->descriptorarray[j];
3483 struct parameterwrapper *parameter=param->queue;
3484 struct ObjectHash * set=parameter->objectset;
3485 struct ObjectIterator objit;
3487 printf(" Parameter %d\n", j);
3489 ObjectHashiterator(set, &objit);
3490 while(ObjhasNext(&objit)) {
3491 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3492 struct ___Object___ * tagptr=obj->___tags___;
3493 int nonfailed=Objdata4(&objit);
3494 int numflags=Objdata3(&objit);
3495 int flags=Objdata2(&objit);
3498 printf(" Contains %lx\n", obj);
3499 printf(" flag=%d\n", obj->flag);
3502 } else if (tagptr->type==TAGTYPE) {
3504 printf(" tag=%lx\n",tagptr);
3510 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3511 for(; tagindex<ao->___cachedCode___; tagindex++) {
3513 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3526 /* This function processes the task information to create queues for
3527 each parameter type. */
3529 void processtasks() {
3531 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3534 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3535 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3538 /* Build objectsets */
3539 for(j=0; j<task->numParameters; j++) {
3540 struct parameterdescriptor *param=task->descriptorarray[j];
3541 struct parameterwrapper *parameter=param->queue;
3542 parameter->objectset=allocateObjectHash(10);
3543 parameter->task=task;
3546 /* Build iterators for parameters */
3547 for(j=0; j<task->numParameters; j++) {
3548 struct parameterdescriptor *param=task->descriptorarray[j];
3549 struct parameterwrapper *parameter=param->queue;
3550 builditerators(task, j, parameter);
3555 void toiReset(struct tagobjectiterator * it) {
3558 } else if (it->numtags>0) {
3561 ObjectHashiterator(it->objectset, &it->it);
3565 int toiHasNext(struct tagobjectiterator *it,
3566 void ** objectarray OPTARG(int * failed)) {
3569 /* Get object with tags */
3570 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3571 struct ___Object___ *tagptr=obj->___tags___;
3572 if (tagptr->type==TAGTYPE) {
3573 if ((it->tagobjindex==0)&& /* First object */
3574 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3579 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3580 int tagindex=it->tagobjindex;
3581 for(; tagindex<ao->___cachedCode___; tagindex++) {
3582 struct ___TagDescriptor___ *td=
3583 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3584 if (td->flag==it->tagid) {
3585 it->tagobjindex=tagindex; /* Found right type of tag */
3591 } else if (it->numtags>0) {
3592 /* Use tags to locate appropriate objects */
3593 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3594 struct ___Object___ *objptr=tag->flagptr;
3596 if (objptr->type!=OBJECTARRAYTYPE) {
3597 if (it->tagobjindex>0)
3599 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3601 for(i=1; i<it->numtags; i++) {
3602 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3603 if (!containstag(objptr,tag2))
3608 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3611 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
3612 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3613 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3615 for(i=1; i<it->numtags; i++) {
3616 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3617 if (!containstag(objptr,tag2))
3620 it->tagobjindex=tagindex;
3625 it->tagobjindex=tagindex;
3629 return ObjhasNext(&it->it);
3633 int containstag(struct ___Object___ *ptr,
3634 struct ___TagDescriptor___ *tag) {
3636 struct ___Object___ * objptr=tag->flagptr;
3637 if (objptr->type==OBJECTARRAYTYPE) {
3638 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3639 for(j=0; j<ao->___cachedCode___; j++) {
3640 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3650 void toiNext(struct tagobjectiterator *it,
3651 void ** objectarray OPTARG(int * failed)) {
3652 /* hasNext has all of the intelligence */
3655 /* Get object with tags */
3656 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3657 struct ___Object___ *tagptr=obj->___tags___;
3658 if (tagptr->type==TAGTYPE) {
3660 objectarray[it->slot]=tagptr;
3662 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3663 objectarray[it->slot]=
3664 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3666 } else if (it->numtags>0) {
3667 /* Use tags to locate appropriate objects */
3668 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3669 struct ___Object___ *objptr=tag->flagptr;
3670 if (objptr->type!=OBJECTARRAYTYPE) {
3672 objectarray[it->slot]=objptr;
3674 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3675 objectarray[it->slot]=
3676 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3679 /* Iterate object */
3680 objectarray[it->slot]=(void *)Objkey(&it->it);
3686 inline void profileTaskStart(char * taskname) {
3687 if(!taskInfoOverflow) {
3688 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
3689 taskInfoArray[taskInfoIndex] = taskInfo;
3690 taskInfo->taskName = taskname;
3691 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
3692 taskInfo->endTime = -1;
3693 taskInfo->exitIndex = -1;
3694 taskInfo->newObjs = NULL;
3698 inline void profileTaskEnd() {
3699 if(!taskInfoOverflow) {
3700 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
3702 if(taskInfoIndex == TASKINFOLENGTH) {
3703 taskInfoOverflow = true;
3704 //taskInfoIndex = 0;
3709 // output the profiling data
3710 void outputProfileData() {
3713 unsigned long long totaltasktime = 0;
3714 unsigned long long preprocessingtime = 0;
3715 unsigned long long objqueuecheckingtime = 0;
3716 unsigned long long postprocessingtime = 0;
3717 //int interruptiontime = 0;
3718 unsigned long long other = 0;
3719 unsigned long long averagetasktime = 0;
3722 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
3723 // output task related info
3724 for(i = 0; i < taskInfoIndex; i++) {
3725 TaskInfo* tmpTInfo = taskInfoArray[i];
3726 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
3727 printf("%s, %lld, %lld, %lld, %lld",
3728 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
3729 duration, tmpTInfo->exitIndex);
3730 // summarize new obj info
3731 if(tmpTInfo->newObjs != NULL) {
3732 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3733 struct RuntimeIterator * iter = NULL;
3734 while(0 == isEmpty(tmpTInfo->newObjs)) {
3735 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3736 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3738 RuntimeHashget(nobjtbl, (int)objtype, &num);
3739 RuntimeHashremovekey(nobjtbl, (int)objtype);
3741 RuntimeHashadd(nobjtbl, (int)objtype, num);
3743 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3745 //printf(stderr, "new obj!\n");
3748 // output all new obj info
3749 iter = RuntimeHashcreateiterator(nobjtbl);
3750 while(RunhasNext(iter)) {
3751 char * objtype = (char *)Runkey(iter);
3752 int num = Runnext(iter);
3753 printf(", %s, %d", objtype, num);
3757 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
3758 preprocessingtime += duration;
3759 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
3760 postprocessingtime += duration;
3761 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
3762 objqueuecheckingtime += duration;
3764 totaltasktime += duration;
3765 averagetasktime += duration;
3770 if(taskInfoOverflow) {
3771 printf("Caution: task info overflow!\n");
3774 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
3775 averagetasktime /= tasknum;
3777 printf("\nTotal time: %lld\n", totalexetime);
3778 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
3779 (int)(((double)totaltasktime/(double)totalexetime)*100));
3780 printf("Total objqueue checking time: %lld (%d%%)\n",
3781 objqueuecheckingtime,
3782 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
3783 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
3784 (int)(((double)preprocessingtime/(double)totalexetime)*100));
3785 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
3786 (int)(((double)postprocessingtime/(double)totalexetime)*100));
3787 printf("Other time: %lld (%d%%)\n", other,
3788 (int)(((double)other/(double)totalexetime)*100));
3791 printf("\nAverage task execution time: %lld\n", averagetasktime);
3793 //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
3798 BAMBOO_DEBUGPRINT(0xdddd);
3799 // output task related info
3800 for(i= 0; i < taskInfoIndex; i++) {
3801 TaskInfo* tmpTInfo = taskInfoArray[i];
3802 char* tmpName = tmpTInfo->taskName;
3803 int nameLen = strlen(tmpName);
3804 BAMBOO_DEBUGPRINT(0xddda);
3805 for(j = 0; j < nameLen; j++) {
3806 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
3808 BAMBOO_DEBUGPRINT(0xdddb);
3809 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
3810 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
3811 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
3812 if(tmpTInfo->newObjs != NULL) {
3813 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3814 struct RuntimeIterator * iter = NULL;
3815 while(0 == isEmpty(tmpTInfo->newObjs)) {
3816 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3817 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3819 RuntimeHashget(nobjtbl, (int)objtype, &num);
3820 RuntimeHashremovekey(nobjtbl, (int)objtype);
3822 RuntimeHashadd(nobjtbl, (int)objtype, num);
3824 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3828 // ouput all new obj info
3829 iter = RuntimeHashcreateiterator(nobjtbl);
3830 while(RunhasNext(iter)) {
3831 char * objtype = (char *)Runkey(iter);
3832 int num = Runnext(iter);
3833 int nameLen = strlen(objtype);
3834 BAMBOO_DEBUGPRINT(0xddda);
3835 for(j = 0; j < nameLen; j++) {
3836 BAMBOO_DEBUGPRINT_REG(objtype[j]);
3838 BAMBOO_DEBUGPRINT(0xdddb);
3839 BAMBOO_DEBUGPRINT_REG(num);
3842 BAMBOO_DEBUGPRINT(0xdddc);
3845 if(taskInfoOverflow) {
3846 BAMBOO_DEBUGPRINT(0xefee);
3849 // output interrupt related info
3850 for(i = 0; i < interruptInfoIndex; i++) {
3851 InterruptInfo* tmpIInfo = interruptInfoArray[i];
3852 BAMBOO_DEBUGPRINT(0xddde);
3853 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
3854 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
3855 BAMBOO_DEBUGPRINT(0xdddf);
3858 if(interruptInfoOverflow) {
3859 BAMBOO_DEBUGPRINT(0xefef);
3862 BAMBOO_DEBUGPRINT(0xeeee);
3865 #endif // #ifdef PROFILE