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;
166 taskInfoOverflow = false;
167 /*interruptInfoIndex = 0;
168 interruptInfoOverflow = false;*/
171 for(i = 0; i < MAXTASKPARAMS; i++) {
172 runtime_locks[i].redirectlock = 0;
173 runtime_locks[i].value = 0;
178 inline __attribute__((always_inline))
179 void disruntimedata() {
182 freeRuntimeHash(gcpointertbl);
183 //freeMGCHash(gcpointertbl);
184 freeMGCHash(gcforwardobjtbl);
186 freeRuntimeHash(lockRedirectTbl);
187 freeRuntimeHash(objRedirectLockTbl);
188 RUNFREE(locktable.bucket);
190 if(activetasks != NULL) {
191 genfreehashtable(activetasks);
193 if(currtpd != NULL) {
194 RUNFREE(currtpd->parameterArray);
198 BAMBOO_LOCAL_MEM_CLOSE();
199 BAMBOO_SHARE_MEM_CLOSE();
202 inline __attribute__((always_inline))
203 bool checkObjQueue() {
205 struct transObjInfo * objInfo = NULL;
209 #ifdef ACCURATEPROFILE
210 bool isChecking = false;
211 if(!isEmpty(&objqueue)) {
212 profileTaskStart("objqueue checking");
214 } // if(!isEmpty(&objqueue))
218 while(!isEmpty(&objqueue)) {
220 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
222 BAMBOO_DEBUGPRINT(0xf001);
225 //isInterrupt = false;
228 BAMBOO_DEBUGPRINT(0xeee1);
231 objInfo = (struct transObjInfo *)getItem(&objqueue);
232 obj = objInfo->objptr;
234 BAMBOO_DEBUGPRINT_REG((int)obj);
236 // grab lock and flush the obj
240 BAMBOO_WAITING_FOR_LOCK(0);
241 } // while(!lockflag)
244 BAMBOO_DEBUGPRINT_REG(grount);
259 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
260 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
261 classsize[((struct ___Object___ *)obj)->type]);
263 // enqueue the object
264 for(k = 0; k < objInfo->length; ++k) {
265 int taskindex = objInfo->queues[2 * k];
266 int paramindex = objInfo->queues[2 * k + 1];
267 struct parameterwrapper ** queues =
268 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
270 BAMBOO_DEBUGPRINT_REG(taskindex);
271 BAMBOO_DEBUGPRINT_REG(paramindex);
272 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
273 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
274 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
275 (long)obj, tmpptr->flag);
277 enqueueObject_I(obj, queues, 1);
279 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
281 } // for(k = 0; k < objInfo->length; ++k)
282 releasewritelock_I(obj);
283 RUNFREE(objInfo->queues);
287 // put it at the end of the queue if no update version in the queue
288 struct QueueItem * qitem = getHead(&objqueue);
289 struct QueueItem * prev = NULL;
290 while(qitem != NULL) {
291 struct transObjInfo * tmpinfo =
292 (struct transObjInfo *)(qitem->objectptr);
293 if(tmpinfo->objptr == obj) {
294 // the same object in the queue, which should be enqueued
295 // recently. Current one is outdate, do not re-enqueue it
296 RUNFREE(objInfo->queues);
301 } // if(tmpinfo->objptr == obj)
302 qitem = getNextQueueItem(prev);
303 } // while(qitem != NULL)
304 // try to execute active tasks already enqueued first
305 addNewItem_I(&objqueue, objInfo);
307 //isInterrupt = true;
310 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
312 BAMBOO_DEBUGPRINT(0xf000);
316 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
318 BAMBOO_DEBUGPRINT(0xf000);
320 } // while(!isEmpty(&objqueue))
323 #ifdef ACCURATEPROFILE
331 BAMBOO_DEBUGPRINT(0xee02);
336 inline __attribute__((always_inline))
337 void checkCoreStatus() {
338 bool allStall = false;
342 (waitconfirm && (numconfirm == 0))) {
344 BAMBOO_DEBUGPRINT(0xee04);
345 BAMBOO_DEBUGPRINT_REG(waitconfirm);
347 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
349 BAMBOO_DEBUGPRINT(0xf001);
351 corestatus[BAMBOO_NUM_OF_CORE] = 0;
352 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
353 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
354 // check the status of all cores
357 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
359 for(i = 0; i < NUMCORESACTIVE; ++i) {
361 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
363 if(corestatus[i] != 0) {
367 } // for(i = 0; i < NUMCORESACTIVE; ++i)
369 // check if the sum of send objs and receive obj are the same
370 // yes->check if the info is the latest; no->go on executing
372 for(i = 0; i < NUMCORESACTIVE; ++i) {
373 sumsendobj += numsendobjs[i];
375 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
377 } // for(i = 0; i < NUMCORESACTIVE; ++i)
378 for(i = 0; i < NUMCORESACTIVE; ++i) {
379 sumsendobj -= numreceiveobjs[i];
381 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
383 } // for(i = 0; i < NUMCORESACTIVE; ++i)
384 if(0 == sumsendobj) {
386 // the first time found all cores stall
387 // send out status confirm msg to all other cores
388 // reset the corestatus array too
390 BAMBOO_DEBUGPRINT(0xee05);
392 corestatus[BAMBOO_NUM_OF_CORE] = 1;
393 for(i = 1; i < NUMCORESACTIVE; ++i) {
395 // send status confirm msg to core i
396 send_msg_1(i, STATUSCONFIRM);
397 } // for(i = 1; i < NUMCORESACTIVE; ++i)
399 numconfirm = NUMCORESACTIVE - 1;
401 // all the core status info are the latest
402 // terminate; for profiling mode, send request to all
403 // other cores to pour out profiling data
405 BAMBOO_DEBUGPRINT(0xee06);
409 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
412 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
413 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
414 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
416 // profile mode, send msgs to other cores to request pouring
417 // out progiling data
419 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
421 BAMBOO_DEBUGPRINT(0xf000);
423 for(i = 1; i < NUMCORESACTIVE; ++i) {
424 // send profile request msg to core i
425 send_msg_2(i, PROFILEOUTPUT, totalexetime);
426 } // for(i = 1; i < NUMCORESACTIVE; ++i)
427 // pour profiling data on startup core
430 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
432 BAMBOO_DEBUGPRINT(0xf001);
434 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
435 // check the status of all cores
438 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
440 for(i = 0; i < NUMCORESACTIVE; ++i) {
442 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
444 if(profilestatus[i] != 0) {
448 } // for(i = 0; i < NUMCORESACTIVE; ++i)
451 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
453 BAMBOO_DEBUGPRINT(0xf000);
463 // gc_profile mode, ourput gc prfiling data
466 gc_outputProfileData();
467 #endif // #ifdef GC_PROFILE
468 #endif // #ifdef MULTICORE_GC
470 terminate(); // All done.
471 } // if(!waitconfirm)
473 // still some objects on the fly on the network
474 // reset the waitconfirm and numconfirm
476 BAMBOO_DEBUGPRINT(0xee07);
480 } // if(0 == sumsendobj)
482 // not all cores are stall, keep on waiting
484 BAMBOO_DEBUGPRINT(0xee08);
489 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
491 BAMBOO_DEBUGPRINT(0xf000);
493 } // if((!waitconfirm) ||
496 // main function for each core
497 inline void run(void * arg) {
501 bool sendStall = false;
503 bool tocontinue = false;
505 corenum = BAMBOO_GET_NUM_OF_CORE();
507 BAMBOO_DEBUGPRINT(0xeeee);
508 BAMBOO_DEBUGPRINT_REG(corenum);
509 BAMBOO_DEBUGPRINT(STARTUPCORE);
512 // initialize runtime data structures
515 // other architecture related initialization
519 initializeexithandler();
521 // main process of the execution module
522 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
523 // non-executing cores, only processing communications
526 BAMBOO_DEBUGPRINT(0xee01);
527 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
528 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
529 profileTaskStart("msg handling");
533 //isInterrupt = false;
537 /* Create queue of active tasks */
539 genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
540 (int(*) (void *,void *)) &comparetpd);
542 /* Process task information */
545 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
546 /* Create startup object */
547 createstartupobject(argc, argv);
551 BAMBOO_DEBUGPRINT(0xee00);
556 // check if need to do GC
560 // check if there are new active tasks can be executed
567 while(receiveObject() != -1) {
572 BAMBOO_DEBUGPRINT(0xee01);
575 // check if there are some pending objects,
576 // if yes, enqueue them and executetasks again
577 tocontinue = checkObjQueue();
581 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
584 BAMBOO_DEBUGPRINT(0xee03);
592 BAMBOO_DEBUGPRINT(0xee09);
598 // wait for some time
601 BAMBOO_DEBUGPRINT(0xee0a);
607 // send StallMsg to startup core
609 BAMBOO_DEBUGPRINT(0xee0b);
612 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
613 self_numsendobjs, self_numreceiveobjs);
625 BAMBOO_DEBUGPRINT(0xee0c);
628 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
631 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
635 struct ___createstartupobject____I_locals {
638 struct ___StartupObject___ * ___startupobject___;
639 struct ArrayObject * ___stringarray___;
640 }; // struct ___createstartupobject____I_locals
642 void createstartupobject(int argc,
646 /* Allocate startup object */
648 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
649 struct ___StartupObject___ *startupobject=
650 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
651 ___locals___.___startupobject___ = startupobject;
652 struct ArrayObject * stringarray=
653 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
654 ___locals___.___stringarray___ = stringarray;
656 struct ___StartupObject___ *startupobject=
657 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
658 struct ArrayObject * stringarray=
659 allocate_newarray(STRINGARRAYTYPE, argc-1);
661 /* Build array of strings */
662 startupobject->___parameters___=stringarray;
663 for(i=1; i<argc; i++) {
664 int length=strlen(argv[i]);
666 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
668 struct ___String___ *newstring=NewString(argv[i],length);
670 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
674 startupobject->version = 0;
675 startupobject->lock = NULL;
677 /* Set initialized flag for startup object */
678 flagorandinit(startupobject,1,0xFFFFFFFF);
679 enqueueObject(startupobject, NULL, 0);
681 BAMBOO_CACHE_FLUSH_ALL();
685 int hashCodetpd(struct taskparamdescriptor *ftd) {
686 int hash=(int)ftd->task;
688 for(i=0; i<ftd->numParameters; i++) {
689 hash^=(int)ftd->parameterArray[i];
694 int comparetpd(struct taskparamdescriptor *ftd1,
695 struct taskparamdescriptor *ftd2) {
697 if (ftd1->task!=ftd2->task)
699 for(i=0; i<ftd1->numParameters; i++)
700 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
705 /* This function sets a tag. */
707 void tagset(void *ptr,
708 struct ___Object___ * obj,
709 struct ___TagDescriptor___ * tagd) {
711 void tagset(struct ___Object___ * obj,
712 struct ___TagDescriptor___ * tagd) {
714 struct ArrayObject * ao=NULL;
715 struct ___Object___ * tagptr=obj->___tags___;
717 obj->___tags___=(struct ___Object___ *)tagd;
719 /* Have to check if it is already set */
720 if (tagptr->type==TAGTYPE) {
721 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
726 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
727 struct ArrayObject * ao=
728 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
729 obj=(struct ___Object___ *)ptrarray[2];
730 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
731 td=(struct ___TagDescriptor___ *) obj->___tags___;
733 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
736 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
737 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
738 obj->___tags___=(struct ___Object___ *) ao;
739 ao->___cachedCode___=2;
743 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
744 for(i=0; i<ao->___cachedCode___; i++) {
745 struct ___TagDescriptor___ * td=
746 ARRAYGET(ao, struct ___TagDescriptor___*, i);
751 if (ao->___cachedCode___<ao->___length___) {
752 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
753 ao->___cachedCode___++;
756 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
757 struct ArrayObject * aonew=
758 allocate_newarray(&ptrarray,TAGARRAYTYPE,
759 TAGARRAYINTERVAL+ao->___length___);
760 obj=(struct ___Object___ *)ptrarray[2];
761 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
762 ao=(struct ArrayObject *)obj->___tags___;
764 struct ArrayObject * aonew=
765 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
768 aonew->___cachedCode___=ao->___length___+1;
769 for(i=0; i<ao->___length___; i++) {
770 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
771 ARRAYGET(ao, struct ___TagDescriptor___*, i));
773 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
779 struct ___Object___ * tagset=tagd->flagptr;
782 } else if (tagset->type!=OBJECTARRAYTYPE) {
784 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
785 struct ArrayObject * ao=
786 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
787 obj=(struct ___Object___ *)ptrarray[2];
788 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
790 struct ArrayObject * ao=
791 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
793 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
794 ARRAYSET(ao, struct ___Object___ *, 1, obj);
795 ao->___cachedCode___=2;
796 tagd->flagptr=(struct ___Object___ *)ao;
798 struct ArrayObject *ao=(struct ArrayObject *) tagset;
799 if (ao->___cachedCode___<ao->___length___) {
800 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
804 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
805 struct ArrayObject * aonew=
806 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
807 OBJECTARRAYINTERVAL+ao->___length___);
808 obj=(struct ___Object___ *)ptrarray[2];
809 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
810 ao=(struct ArrayObject *)tagd->flagptr;
812 struct ArrayObject * aonew=
813 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
815 aonew->___cachedCode___=ao->___cachedCode___+1;
816 for(i=0; i<ao->___length___; i++) {
817 ARRAYSET(aonew, struct ___Object___*, i,
818 ARRAYGET(ao, struct ___Object___*, i));
820 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
821 tagd->flagptr=(struct ___Object___ *) aonew;
827 /* This function clears a tag. */
829 void tagclear(void *ptr,
830 struct ___Object___ * obj,
831 struct ___TagDescriptor___ * tagd) {
833 void tagclear(struct ___Object___ * obj,
834 struct ___TagDescriptor___ * tagd) {
836 /* We'll assume that tag is alway there.
837 Need to statically check for this of course. */
838 struct ___Object___ * tagptr=obj->___tags___;
840 if (tagptr->type==TAGTYPE) {
841 if ((struct ___TagDescriptor___ *)tagptr==tagd)
842 obj->___tags___=NULL;
844 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
846 for(i=0; i<ao->___cachedCode___; i++) {
847 struct ___TagDescriptor___ * td=
848 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
850 ao->___cachedCode___--;
851 if (i<ao->___cachedCode___)
852 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
853 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
854 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
855 if (ao->___cachedCode___==0)
856 obj->___tags___=NULL;
863 struct ___Object___ *tagset=tagd->flagptr;
864 if (tagset->type!=OBJECTARRAYTYPE) {
868 struct ArrayObject *ao=(struct ArrayObject *) tagset;
870 for(i=0; i<ao->___cachedCode___; i++) {
871 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
873 ao->___cachedCode___--;
874 if (i<ao->___cachedCode___)
875 ARRAYSET(ao, struct ___Object___ *, i,
876 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
877 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
878 if (ao->___cachedCode___==0)
889 /* This function allocates a new tag. */
891 struct ___TagDescriptor___ * allocate_tag(void *ptr,
893 struct ___TagDescriptor___ * v=
894 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
897 struct ___TagDescriptor___ * allocate_tag(int index) {
898 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
907 /* This function updates the flag for object ptr. It or's the flag
908 with the or mask and and's it with the andmask. */
910 void flagbody(struct ___Object___ *ptr,
912 struct parameterwrapper ** queues,
916 int flagcomp(const int *val1, const int *val2) {
917 return (*val1)-(*val2);
920 void flagorand(void * ptr,
923 struct parameterwrapper ** queues,
926 int oldflag=((int *)ptr)[1];
927 int flag=ormask|oldflag;
929 flagbody(ptr, flag, queues, length, false);
933 bool intflagorand(void * ptr,
937 int oldflag=((int *)ptr)[1];
938 int flag=ormask|oldflag;
940 if (flag==oldflag) /* Don't do anything */
943 flagbody(ptr, flag, NULL, 0, false);
949 void flagorandinit(void * ptr,
952 int oldflag=((int *)ptr)[1];
953 int flag=ormask|oldflag;
955 flagbody(ptr,flag,NULL,0,true);
958 void flagbody(struct ___Object___ *ptr,
960 struct parameterwrapper ** vqueues,
963 struct parameterwrapper * flagptr = NULL;
965 struct parameterwrapper ** queues = vqueues;
966 int length = vlength;
969 int * enterflags = NULL;
970 if((!isnew) && (queues == NULL)) {
971 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
972 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
973 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
980 /*Remove object from all queues */
981 for(i = 0; i < length; ++i) {
983 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
984 (int *) &enterflags, &UNUSED, &UNUSED2);
985 ObjectHashremove(flagptr->objectset, (int)ptr);
986 if (enterflags!=NULL)
991 void enqueueObject(void * vptr,
992 struct parameterwrapper ** vqueues,
994 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
997 //struct QueueItem *tmpptr;
998 struct parameterwrapper * parameter=NULL;
1001 struct parameterwrapper * prevptr=NULL;
1002 struct ___Object___ *tagptr=NULL;
1003 struct parameterwrapper ** queues = vqueues;
1004 int length = vlength;
1005 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1008 if(queues == NULL) {
1009 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1010 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1012 tagptr=ptr->___tags___;
1014 /* Outer loop iterates through all parameter queues an object of
1015 this type could be in. */
1016 for(j = 0; j < length; ++j) {
1017 parameter = queues[j];
1019 if (parameter->numbertags>0) {
1021 goto nextloop; //that means the object has no tag
1022 //but that param needs tag
1023 else if(tagptr->type==TAGTYPE) { //one tag
1024 //struct ___TagDescriptor___ * tag=
1025 //(struct ___TagDescriptor___*) tagptr;
1026 for(i=0; i<parameter->numbertags; i++) {
1027 //slotid is parameter->tagarray[2*i];
1028 int tagid=parameter->tagarray[2*i+1];
1029 if (tagid!=tagptr->flag)
1030 goto nextloop; /*We don't have this tag */
1032 } else { //multiple tags
1033 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1034 for(i=0; i<parameter->numbertags; i++) {
1035 //slotid is parameter->tagarray[2*i];
1036 int tagid=parameter->tagarray[2*i+1];
1038 for(j=0; j<ao->___cachedCode___; j++) {
1039 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1050 for(i=0; i<parameter->numberofterms; i++) {
1051 int andmask=parameter->intarray[i*2];
1052 int checkmask=parameter->intarray[i*2+1];
1053 if ((ptr->flag&andmask)==checkmask) {
1054 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1065 void enqueueObject_I(void * vptr,
1066 struct parameterwrapper ** vqueues,
1068 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1071 //struct QueueItem *tmpptr;
1072 struct parameterwrapper * parameter=NULL;
1075 struct parameterwrapper * prevptr=NULL;
1076 struct ___Object___ *tagptr=NULL;
1077 struct parameterwrapper ** queues = vqueues;
1078 int length = vlength;
1079 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1082 if(queues == NULL) {
1083 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1084 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1086 tagptr=ptr->___tags___;
1088 /* Outer loop iterates through all parameter queues an object of
1089 this type could be in. */
1090 for(j = 0; j < length; ++j) {
1091 parameter = queues[j];
1093 if (parameter->numbertags>0) {
1095 goto nextloop; //that means the object has no tag
1096 //but that param needs tag
1097 else if(tagptr->type==TAGTYPE) { //one tag
1098 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1099 for(i=0; i<parameter->numbertags; i++) {
1100 //slotid is parameter->tagarray[2*i];
1101 int tagid=parameter->tagarray[2*i+1];
1102 if (tagid!=tagptr->flag)
1103 goto nextloop; /*We don't have this tag */
1105 } else { //multiple tags
1106 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1107 for(i=0; i<parameter->numbertags; i++) {
1108 //slotid is parameter->tagarray[2*i];
1109 int tagid=parameter->tagarray[2*i+1];
1111 for(j=0; j<ao->___cachedCode___; j++) {
1112 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1123 for(i=0; i<parameter->numberofterms; i++) {
1124 int andmask=parameter->intarray[i*2];
1125 int checkmask=parameter->intarray[i*2+1];
1126 if ((ptr->flag&andmask)==checkmask) {
1127 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1139 int * getAliasLock(void ** ptrs,
1141 struct RuntimeHash * tbl) {
1143 return (int*)(RUNMALLOC(sizeof(int)));
1148 bool redirect = false;
1149 int redirectlock = 0;
1150 for(; i < length; i++) {
1151 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1154 if(ptr->lock == NULL) {
1157 lock = (int)(ptr->lock);
1160 if(lock != redirectlock) {
1161 RuntimeHashadd(tbl, lock, redirectlock);
1164 if(RuntimeHashcontainskey(tbl, lock)) {
1165 // already redirected
1167 RuntimeHashget(tbl, lock, &redirectlock);
1168 for(; j < locklen; j++) {
1169 if(locks[j] != redirectlock) {
1170 RuntimeHashadd(tbl, locks[j], redirectlock);
1175 for(j = 0; j < locklen; j++) {
1176 if(locks[j] == lock) {
1179 } else if(locks[j] > lock) {
1186 locks[h] = locks[h-1];
1195 return (int *)redirectlock;
1197 return (int *)(locks[0]);
1202 void addAliasLock(void * ptr,
1204 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1205 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1206 // originally no alias lock associated or have a different alias lock
1207 // flush it as the new one
1208 obj->lock = (int *)lock;
1213 inline void setTaskExitIndex(int index) {
1214 taskInfoArray[taskInfoIndex]->exitIndex = index;
1217 inline void addNewObjInfo(void * nobj) {
1218 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1219 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1221 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1226 void * localmalloc_I(int coren,
1232 int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1233 int totest = tofindb;
1234 int bound = BAMBOO_SMEM_SIZE_L;
1238 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1239 int nsize = bamboo_smemtbl[totest];
1240 bool islocal = true;
1242 bool tocheck = true;
1243 // have some space in the block
1244 if(totest == tofindb) {
1245 // the first partition
1246 size = bound - nsize;
1247 } else if(nsize == 0) {
1248 // an empty partition, can be appended
1251 // not an empty partition, can not be appended
1252 // the last continuous block is not big enough, go to check the next
1256 } // if(totest == tofindb) else if(nsize == 0) else ...
1259 // have enough space in the block, malloc
1263 // no enough space yet, try to append next continuous block
1265 } // if(size > isize) else ...
1267 } // if(nsize < bound)
1269 // no space in the block, go to check the next block
1275 tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1278 } // if(islocal) else ...
1279 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1280 // no more local mem, do not find suitable block
1283 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1286 if(foundsmem == 1) {
1287 // find suitable block
1288 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC)?
1289 (BAMBOO_SMEM_SIZE_L*tofindb):(BAMBOO_LARGE_SMEM_BOUND+
1290 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1292 // set bamboo_smemtbl
1293 for(i = tofindb; i <= totest; i++) {
1294 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1296 } else if(foundsmem == 2) {
1297 // no suitable block
1302 } // void * localmalloc_I(int, int, int *)
1304 void * globalmalloc_I(int coren,
1308 int tofindb = bamboo_free_block; //0;
1309 int totest = tofindb;
1310 int bound = BAMBOO_SMEM_SIZE_L;
1313 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1318 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1319 int nsize = bamboo_smemtbl[totest];
1320 bool isnext = false;
1322 bool tocheck = true;
1323 // have some space in the block
1324 if(totest == tofindb) {
1325 // the first partition
1326 size = bound - nsize;
1327 } else if(nsize == 0) {
1328 // an empty partition, can be appended
1331 // not an empty partition, can not be appended
1332 // the last continuous block is not big enough, start another block
1335 } // if(totest == tofindb) else if(nsize == 0) else ...
1338 // have enough space in the block, malloc
1341 } // if(size > isize)
1345 }// if(nsize < bound) else ...
1347 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1348 // no more local mem, do not find suitable block
1351 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1353 // start another block
1358 if(foundsmem == 1) {
1359 // find suitable block
1360 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC)?
1361 (BAMBOO_SMEM_SIZE_L*tofindb):(BAMBOO_LARGE_SMEM_BOUND+
1362 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1364 // set bamboo_smemtbl
1365 for(int i = tofindb; i <= totest; i++) {
1366 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1368 if(tofindb == bamboo_free_block) {
1369 bamboo_free_block = totest+1;
1371 } else if(foundsmem == 2) {
1372 // no suitable block
1378 } // void * globalmalloc_I(int, int, int *)
1379 #endif // #ifdef MULTICORE_GC
1381 // malloc from the shared memory
1382 void * smemalloc_I(int coren,
1387 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1389 // go through the bamboo_smemtbl for suitable partitions
1390 switch(bamboo_smem_mode) {
1392 mem = localmalloc_I(coren, isize, allocsize);
1397 // TODO not supported yet
1398 BAMBOO_EXIT(0xe001);
1403 // TODO not supported yet
1404 BAMBOO_EXIT(0xe002);
1409 mem = globalmalloc_I(coren, isize, allocsize);
1419 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size):(BAMBOO_SMEM_SIZE);
1420 mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1421 *allocsize = toallocate;
1424 // no enough shared global memory
1430 BAMBOO_DEBUGPRINT(0xa001);
1431 BAMBOO_EXIT(0xa001);
1435 } // void * smemalloc_I(int, int, int)
1437 INLINE int checkMsgLength_I(int size) {
1440 BAMBOO_DEBUGPRINT(0xcccc);
1443 int type = msgdata[msgdataindex];
1462 case GCSTARTCOMPACT:
1486 case REDIRECTGROUNT:
1488 case REDIRECTRELEASE:
1500 case GCFINISHCOMPACT:
1512 case TRANSOBJ: // nonfixed size
1518 msglength = msgdata[msgdataindex+1];
1526 BAMBOO_DEBUGPRINT_REG(type);
1527 BAMBOO_DEBUGPRINT_REG(msgdataindex);
1530 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1532 BAMBOO_EXIT(0xd005);
1538 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1543 BAMBOO_DEBUGPRINT(0xffff);
1549 INLINE void processmsg_transobj_I() {
1551 struct transObjInfo * transObj = RUNMALLOC_I(sizeof(struct transObjInfo));
1555 BAMBOO_DEBUGPRINT(0xe880);
1558 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1560 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]/*[2]*/);
1562 BAMBOO_EXIT(0xa002);
1564 // store the object and its corresponding queue info, enqueue it later
1565 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
1567 transObj->length = (msglength - 3) / 2;
1568 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1569 for(k = 0; k < transObj->length; ++k) {
1570 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
1574 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1577 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
1581 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1585 // check if there is an existing duplicate item
1587 struct QueueItem * qitem = getHead(&objqueue);
1588 struct QueueItem * prev = NULL;
1589 while(qitem != NULL) {
1590 struct transObjInfo * tmpinfo =
1591 (struct transObjInfo *)(qitem->objectptr);
1592 if(tmpinfo->objptr == transObj->objptr) {
1593 // the same object, remove outdate one
1594 RUNFREE(tmpinfo->queues);
1596 removeItem(&objqueue, qitem);
1602 qitem = getHead(&objqueue);
1604 qitem = getNextQueueItem(prev);
1607 addNewItem_I(&objqueue, (void *)transObj);
1609 ++(self_numreceiveobjs);
1612 INLINE void processmsg_transtall_I() {
1613 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1614 // non startup core can not receive stall msg
1616 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]/*[1]*/);
1618 BAMBOO_EXIT(0xa003);
1620 int num_core = msgdata[msgdataindex]; //[1]
1622 if(num_core < NUMCORESACTIVE) {
1625 BAMBOO_DEBUGPRINT(0xe881);
1628 corestatus[num_core] = 0;
1629 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
1631 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
1636 #ifndef MULTICORE_GC
1637 INLINE void processmsg_lockrequest_I() {
1638 // check to see if there is a lock exist for the required obj
1639 // msgdata[1] -> lock type
1640 int locktype = msgdata[msgdataindex]; //[1];
1642 int data2 = msgdata[msgdataindex]; // obj pointer
1644 int data3 = msgdata[msgdataindex]; // lock
1646 int data4 = msgdata[msgdataindex]; // request core
1648 // -1: redirected, 0: approved, 1: denied
1649 int deny = processlockrequest(locktype, data3, data2, data4, data4, true);
1651 // this lock request is redirected
1654 // send response msg
1655 // for 32 bit machine, the size is always 4 words, cache the msg first
1656 int tmp = deny==1?LOCKDENY:LOCKGROUNT;
1657 //if(isMsgSending) {
1658 cache_msg_4(data4, tmp, locktype, data2, data3);
1660 send_msg_4(data4, tmp, locktype, data2, data3);
1665 INLINE void processmsg_lockgrount_I() {
1667 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1669 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]/*[2]*/);
1671 BAMBOO_EXIT(0xa004);
1673 int data2 = msgdata[msgdataindex];
1675 int data3 = msgdata[msgdataindex];
1677 if((lockobj == data2) && (lock2require == data3)) {
1680 BAMBOO_DEBUGPRINT(0xe882);
1689 // conflicts on lockresults
1691 BAMBOO_DEBUGPRINT_REG(data2);
1693 BAMBOO_EXIT(0xa005);
1697 INLINE void processmsg_lockdeny_I() {
1699 int data2 = msgdata[msgdataindex];
1701 int data3 = msgdata[msgdataindex];
1703 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1705 BAMBOO_DEBUGPRINT_REG(data2);
1707 BAMBOO_EXIT(0xa006);
1709 if((lockobj == data2) && (lock2require == data3)) {
1712 BAMBOO_DEBUGPRINT(0xe883);
1721 // conflicts on lockresults
1723 BAMBOO_DEBUGPRINT_REG(data2);
1725 BAMBOO_EXIT(0xa007);
1729 INLINE void processmsg_lockrelease_I() {
1730 int data1 = msgdata[msgdataindex];
1732 int data2 = msgdata[msgdataindex];
1734 // receive lock release msg
1735 processlockrelease(data1, data2, 0, false);
1738 INLINE void processmsg_redirectlock_I() {
1739 // check to see if there is a lock exist for the required obj
1740 int data1 = msgdata[msgdataindex];
1741 MSG_INDEXINC_I(); //msgdata[1]; // lock type
1742 int data2 = msgdata[msgdataindex];
1743 MSG_INDEXINC_I();//msgdata[2]; // obj pointer
1744 int data3 = msgdata[msgdataindex];
1745 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
1746 int data4 = msgdata[msgdataindex];
1747 MSG_INDEXINC_I(); //msgdata[4]; // root request core
1748 int data5 = msgdata[msgdataindex];
1749 MSG_INDEXINC_I(); //msgdata[5]; // request core
1750 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
1752 // this lock request is redirected
1755 // send response msg
1756 // for 32 bit machine, the size is always 4 words, cache the msg first
1757 //if(isMsgSending) {
1758 cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1759 data1, data2, data3);
1761 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1762 data1, data2, data3);
1767 INLINE void processmsg_redirectgrount_I() {
1769 int data2 = msgdata[msgdataindex];
1771 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1773 BAMBOO_DEBUGPRINT_REG(data2);
1775 BAMBOO_EXIT(0xa00a);
1777 if(lockobj == data2) {
1780 BAMBOO_DEBUGPRINT(0xe891);
1783 int data3 = msgdata[msgdataindex];
1787 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
1792 // conflicts on lockresults
1794 BAMBOO_DEBUGPRINT_REG(data2);
1796 BAMBOO_EXIT(0xa00b);
1800 INLINE void processmsg_redirectdeny_I() {
1802 int data2 = msgdata[msgdataindex];
1804 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1806 BAMBOO_DEBUGPRINT_REG(data2);
1808 BAMBOO_EXIT(0xa00c);
1810 if(lockobj == data2) {
1813 BAMBOO_DEBUGPRINT(0xe892);
1822 // conflicts on lockresults
1824 BAMBOO_DEBUGPRINT_REG(data2);
1826 BAMBOO_EXIT(0xa00d);
1830 INLINE void processmsg_redirectrelease_I() {
1831 int data1 = msgdata[msgdataindex];
1833 int data2 = msgdata[msgdataindex];
1835 int data3 = msgdata[msgdataindex];
1837 processlockrelease(data1, data2, data3, true);
1839 #endif // #ifndef MULTICORE_GC
1842 INLINE void processmsg_profileoutput_I() {
1843 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1844 // startup core can not receive profile output finish msg
1845 BAMBOO_EXIT(0xa008);
1849 BAMBOO_DEBUGPRINT(0xe885);
1853 totalexetime = msgdata[msgdataindex]; //[1]
1855 outputProfileData();
1856 // cache the msg first
1857 //if(isMsgSending) {
1858 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1860 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1864 INLINE void processmsg_profilefinish_I() {
1865 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1866 // non startup core can not receive profile output finish msg
1868 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex/*1*/]);
1870 BAMBOO_EXIT(0xa009);
1874 BAMBOO_DEBUGPRINT(0xe886);
1877 int data1 = msgdata[msgdataindex];
1879 profilestatus[data1] = 0;
1881 #endif // #ifdef PROFILE
1883 INLINE void processmsg_statusconfirm_I() {
1884 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1885 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1886 // wrong core to receive such msg
1887 BAMBOO_EXIT(0xa00e);
1889 // send response msg
1892 BAMBOO_DEBUGPRINT(0xe887);
1895 // cache the msg first
1896 //if(isMsgSending) {
1897 cache_msg_5(STARTUPCORE, STATUSREPORT,
1898 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1899 self_numsendobjs, self_numreceiveobjs);
1901 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
1902 BAMBOO_NUM_OF_CORE, self_numsendobjs,
1903 self_numreceiveobjs);
1908 INLINE void processmsg_statusreport_I() {
1909 int data1 = msgdata[msgdataindex];
1911 int data2 = msgdata[msgdataindex];
1913 int data3 = msgdata[msgdataindex];
1915 int data4 = msgdata[msgdataindex];
1917 // receive a status confirm info
1918 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1919 // wrong core to receive such msg
1921 BAMBOO_DEBUGPRINT_REG(data2);
1923 BAMBOO_EXIT(0xa00f);
1927 BAMBOO_DEBUGPRINT(0xe888);
1933 corestatus[data2] = data1;
1934 numsendobjs[data2] = data3;
1935 numreceiveobjs[data2] = data4;
1939 INLINE void processmsg_terminate_I() {
1942 BAMBOO_DEBUGPRINT(0xe889);
1949 INLINE void processmsg_memrequest_I() {
1950 int data1 = msgdata[msgdataindex];
1952 int data2 = msgdata[msgdataindex];
1954 // receive a shared memory request msg
1955 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1956 // wrong core to receive such msg
1958 BAMBOO_DEBUGPRINT_REG(data2);
1960 BAMBOO_EXIT(0xa010);
1964 BAMBOO_DEBUGPRINT(0xe88a);
1971 // is currently doing gc, dump this msg
1972 if(INITPHASE == gcphase) {
1973 // if still in the initphase of gc, send a startinit msg again,
1974 // cache the msg first
1975 //if(isMsgSending) {
1976 cache_msg_1(data2, GCSTARTINIT);
1978 send_msg_1(data2, GCSTARTINIT);
1983 mem = smemalloc_I(data2, data1, &allocsize);
1985 // send the start_va to request core, cache the msg first
1986 //if(isMsgSending) {
1987 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
1989 send_msg_3(data2, MEMRESPONSE, mem, allocsize);
1991 } // if mem == NULL, the gcflag of the startup core has been set
1992 // and the gc should be started later, then a GCSTARTINIT msg
1993 // will be sent to the requesting core to notice it to start gc
1994 // and try malloc again
2001 INLINE void processmsg_memresponse_I() {
2002 int data1 = msgdata[msgdataindex];
2004 int data2 = msgdata[msgdataindex];
2006 // receive a shared memory response msg
2009 BAMBOO_DEBUGPRINT(0xe88b);
2013 // if is currently doing gc, dump this msg
2017 bamboo_smem_size = 0;
2021 // fill header to store the size of this mem block
2022 memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2023 (*((int*)data1)) = data2;
2024 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2025 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2027 bamboo_smem_size = data2;
2028 bamboo_cur_msp =(void*)(data1);
2038 INLINE void processmsg_gcstartinit_I() {
2040 gcphase = INITPHASE;
2042 // is waiting for response of mem request
2043 // let it return NULL and start gc
2044 bamboo_smem_size = 0;
2045 bamboo_cur_msp = NULL;
2050 INLINE void processmsg_gcstart_I() {
2053 BAMBOO_DEBUGPRINT(0xe88c);
2057 gcphase = MARKPHASE;
2060 INLINE void processmsg_gcstartcompact_I() {
2061 gcblock2fill = msgdata[msgdataindex];
2062 MSG_INDEXINC_I(); //msgdata[1];
2063 gcphase = COMPACTPHASE;
2066 INLINE void processmsg_gcstartflush_I() {
2067 gcphase = FLUSHPHASE;
2070 INLINE void processmsg_gcfinishinit_I() {
2071 int data1 = msgdata[msgdataindex];
2073 // received a init phase finish msg
2074 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2075 // non startup core can not receive this msg
2077 BAMBOO_DEBUGPRINT_REG(data1);
2079 BAMBOO_EXIT(0xb001);
2082 BAMBOO_DEBUGPRINT(0xe88c);
2083 BAMBOO_DEBUGPRINT_REG(data1);
2085 // All cores should do init GC
2086 if(data1 < NUMCORESACTIVE) {
2087 gccorestatus[data1] = 0;
2091 INLINE void processmsg_gcfinishmark_I() {
2092 int data1 = msgdata[msgdataindex];
2094 int data2 = msgdata[msgdataindex];
2096 int data3 = msgdata[msgdataindex];
2098 // received a mark phase finish msg
2099 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2100 // non startup core can not receive this msg
2102 BAMBOO_DEBUGPRINT_REG(data1);
2104 BAMBOO_EXIT(0xb002);
2106 // all cores should do mark
2107 if(data1 < NUMCORESACTIVE) {
2108 gccorestatus[data1] = 0;
2109 gcnumsendobjs[data1] = data2;
2110 gcnumreceiveobjs[data1] = data3;
2114 INLINE void processmsg_gcfinishcompact_I() {
2115 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2116 // non startup core can not receive this msg
2119 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]/*[1]*/);
2121 BAMBOO_EXIT(0xb003);
2123 int cnum = msgdata[msgdataindex];
2124 MSG_INDEXINC_I(); //msgdata[1];
2125 int filledblocks = msgdata[msgdataindex];
2126 MSG_INDEXINC_I(); //msgdata[2];
2127 int heaptop = msgdata[msgdataindex];
2128 MSG_INDEXINC_I(); //msgdata[3];
2129 int data4 = msgdata[msgdataindex];
2130 MSG_INDEXINC_I(); //msgdata[4];
2131 // only gc cores need to do compact
2132 if(cnum < NUMCORES4GC) {
2133 if(COMPACTPHASE == gcphase) {
2134 gcfilledblocks[cnum] = filledblocks;
2135 gcloads[cnum] = heaptop;
2142 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2143 // cache the msg first
2144 //if(isMsgSending) {
2145 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2147 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2151 gccorestatus[cnum] = 0;
2153 } // if(cnum < NUMCORES4GC)
2156 INLINE void processmsg_gcfinishflush_I() {
2157 int data1 = msgdata[msgdataindex];
2159 // received a flush phase finish msg
2160 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2161 // non startup core can not receive this msg
2164 BAMBOO_DEBUGPRINT_REG(data1);
2166 BAMBOO_EXIT(0xb004);
2168 // all cores should do flush
2169 if(data1 < NUMCORESACTIVE) {
2170 gccorestatus[data1] = 0;
2174 INLINE void processmsg_gcmarkconfirm_I() {
2175 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2176 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2177 // wrong core to receive such msg
2178 BAMBOO_EXIT(0xb005);
2180 // send response msg, cahce the msg first
2181 //if(isMsgSending) {
2182 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2183 gcbusystatus, gcself_numsendobjs,
2184 gcself_numreceiveobjs);
2186 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2187 gcbusystatus, gcself_numsendobjs,
2188 gcself_numreceiveobjs);
2193 INLINE void processmsg_gcmarkreport_I() {
2194 int data1 = msgdata[msgdataindex];
2196 int data2 = msgdata[msgdataindex];
2198 int data3 = msgdata[msgdataindex];
2200 int data4 = msgdata[msgdataindex];
2202 // received a marked phase finish confirm response msg
2203 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2204 // wrong core to receive such msg
2206 BAMBOO_DEBUGPRINT_REG(data2);
2208 BAMBOO_EXIT(0xb006);
2213 gccorestatus[data1] = data2;
2214 gcnumsendobjs[data1] = data3;
2215 gcnumreceiveobjs[data1] = data4;
2219 INLINE void processmsg_gcmarkedobj_I() {
2220 int data1 = msgdata[msgdataindex];
2222 // received a markedObj msg
2223 if(((int *)data1)[6] == INIT) {
2224 // this is the first time that this object is discovered,
2225 // set the flag as DISCOVERED
2226 ((int *)data1)[6] = DISCOVERED;
2227 gc_enqueue_I(data1);
2229 gcself_numreceiveobjs++;
2230 gcbusystatus = true;
2233 INLINE void processmsg_gcmovestart_I() {
2235 gcdstcore = msgdata[msgdataindex];
2236 MSG_INDEXINC_I(); //msgdata[1];
2237 gcmovestartaddr = msgdata[msgdataindex];
2238 MSG_INDEXINC_I(); //msgdata[2];
2239 gcblock2fill = msgdata[msgdataindex];
2240 MSG_INDEXINC_I(); //msgdata[3];
2243 INLINE void processmsg_gcmaprequest_I() {
2245 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2247 void * dstptr = NULL;
2248 int data1 = msgdata[msgdataindex];
2250 //dstptr = mgchashSearch(msgdata[1]);
2252 unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2254 RuntimeHashget(gcpointertbl, data1, &dstptr);
2256 flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2258 int data2 = msgdata[msgdataindex];
2260 //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2262 unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2264 if(NULL == dstptr) {
2265 // no such pointer in this core, something is wrong
2267 BAMBOO_DEBUGPRINT_REG(data1);
2268 BAMBOO_DEBUGPRINT_REG(data2);
2270 BAMBOO_EXIT(0xb007);
2271 //assume that the object was not moved, use the original address
2272 /*if(isMsgSending) {
2273 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2275 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2278 // send back the mapping info, cache the msg first
2279 //if(isMsgSending) {
2280 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2282 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2286 flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2287 //num_mapinforequest_i++;
2291 INLINE void processmsg_gcmapinfo_I() {
2293 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2295 int data1 = msgdata[msgdataindex];
2297 if(data1 != gcobj2map) {
2298 // obj not matched, something is wrong
2300 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2301 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2303 BAMBOO_EXIT(0xb008);
2305 gcmappedobj = msgdata[msgdataindex]; // [2]
2307 //mgchashReplace_I(msgdata[1], msgdata[2]);
2308 //mgchashInsert_I(gcobj2map, gcmappedobj);
2309 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2310 //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2314 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2318 INLINE void processmsg_gclobjinfo_I() {
2321 int data1 = msgdata[msgdataindex];
2323 int data2 = msgdata[msgdataindex];
2325 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2327 BAMBOO_DEBUGPRINT_REG(data2);
2329 BAMBOO_EXIT(0xb009);
2331 // store the mark result info
2333 gcloads[cnum] = msgdata[msgdataindex];
2334 MSG_INDEXINC_I(); // msgdata[3];
2335 int data4 = msgdata[msgdataindex];
2337 if(gcheaptop < data4) {
2340 // large obj info here
2341 for(int k = 5; k < data1;) {
2342 int lobj = msgdata[msgdataindex];
2343 MSG_INDEXINC_I(); //msgdata[k++];
2344 int length = msgdata[msgdataindex];
2345 MSG_INDEXINC_I(); //msgdata[k++];
2346 gc_lobjenqueue_I(lobj, length, cnum);
2348 } // for(int k = 5; k < msgdata[1];)
2351 INLINE void processmsg_gclobjmapping_I() {
2352 int data1 = msgdata[msgdataindex];
2354 int data2 = msgdata[msgdataindex];
2356 //mgchashInsert_I(msgdata[1], msgdata[2]);
2357 RuntimeHashadd_I(gcpointertbl, data1, data2);
2358 //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2360 #endif // #ifdef MULTICORE_GC
2362 // receive object transferred from other cores
2363 // or the terminate message from other cores
2364 // Should be invoked in critical sections!!
2365 // NOTICE: following format is for threadsimulate version only
2366 // RAW version please see previous description
2367 // format: type + object
2368 // type: -1--stall msg
2370 // return value: 0--received an object
2371 // 1--received nothing
2372 // 2--received a Stall Msg
2373 // 3--received a lock Msg
2374 // RAW version: -1 -- received nothing
2375 // otherwise -- received msg type
2376 int receiveObject(int send_port_pending) {
2378 // get the incoming msgs
2379 if(receiveMsg(send_port_pending) == -1) {
2383 // processing received msgs
2385 MSG_REMAINSIZE_I(&size);
2386 if((size == 0) || (checkMsgLength_I(size) == -1)) {
2388 // have new coming msg
2389 if(BAMBOO_MSG_AVAIL() != 0) {
2396 if(msglength <= size) {
2397 // have some whole msg
2398 //if(msgdataindex == msglength) {
2399 // received a whole msg
2401 type = msgdata[msgdataindex]; //[0]
2403 msgdatafull = false;
2405 //tprintf("msg type: %x\n", type);
2408 // receive a object transfer msg
2409 processmsg_transobj_I();
2414 // receive a stall msg
2415 processmsg_transtall_I();
2419 // GC version have no lock msgs
2420 #ifndef MULTICORE_GC
2422 // receive lock request msg, handle it right now
2423 processmsg_lockrequest_I();
2425 } // case LOCKREQUEST
2428 // receive lock grount msg
2429 processmsg_lockgrount_I();
2431 } // case LOCKGROUNT
2434 // receive lock deny msg
2435 processmsg_lockdeny_I();
2440 processmsg_lockrelease_I();
2442 } // case LOCKRELEASE
2443 #endif // #ifndef MULTICORE_GC
2446 case PROFILEOUTPUT: {
2447 // receive an output profile data request msg
2448 processmsg_profileoutput_I();
2450 } // case PROFILEOUTPUT
2452 case PROFILEFINISH: {
2453 // receive a profile output finish msg
2454 processmsg_profilefinish_I();
2456 } // case PROFILEFINISH
2457 #endif // #ifdef PROFILE
2459 // GC version has no lock msgs
2460 #ifndef MULTICORE_GC
2461 case REDIRECTLOCK: {
2462 // receive a redirect lock request msg, handle it right now
2463 processmsg_redirectlock_I();
2465 } // case REDIRECTLOCK
2467 case REDIRECTGROUNT: {
2468 // receive a lock grant msg with redirect info
2469 processmsg_redirectgrount_I();
2471 } // case REDIRECTGROUNT
2473 case REDIRECTDENY: {
2474 // receive a lock deny msg with redirect info
2475 processmsg_redirectdeny_I();
2477 } // case REDIRECTDENY
2479 case REDIRECTRELEASE: {
2480 // receive a lock release msg with redirect info
2481 processmsg_redirectrelease_I();
2483 } // case REDIRECTRELEASE
2484 #endif // #ifndef MULTICORE_GC
2486 case STATUSCONFIRM: {
2487 // receive a status confirm info
2488 processmsg_statusconfirm_I();
2490 } // case STATUSCONFIRM
2492 case STATUSREPORT: {
2493 processmsg_statusreport_I();
2495 } // case STATUSREPORT
2498 // receive a terminate msg
2499 processmsg_terminate_I();
2504 processmsg_memrequest_I();
2506 } // case MEMREQUEST
2509 processmsg_memresponse_I();
2511 } // case MEMRESPONSE
2516 processmsg_gcstartinit_I();
2518 } // case GCSTARTINIT
2521 // receive a start GC msg
2522 processmsg_gcstart_I();
2526 case GCSTARTCOMPACT: {
2527 // a compact phase start msg
2528 processmsg_gcstartcompact_I();
2530 } // case GCSTARTCOMPACT
2532 case GCSTARTFLUSH: {
2533 // received a flush phase start msg
2534 processmsg_gcstartflush_I();
2536 } // case GCSTARTFLUSH
2538 case GCFINISHINIT: {
2539 processmsg_gcfinishinit_I();
2541 } // case GCFINISHINIT
2543 case GCFINISHMARK: {
2544 processmsg_gcfinishmark_I();
2546 } // case GCFINISHMARK
2548 case GCFINISHCOMPACT: {
2549 // received a compact phase finish msg
2550 processmsg_gcfinishcompact_I();
2552 } // case GCFINISHCOMPACT
2554 case GCFINISHFLUSH: {
2555 processmsg_gcfinishflush_I();
2557 } // case GCFINISHFLUSH
2560 // received a GC finish msg
2561 gcphase = FINISHPHASE;
2565 case GCMARKCONFIRM: {
2566 // received a marked phase finish confirm request msg
2567 // all cores should do mark
2568 processmsg_gcmarkconfirm_I();
2570 } // case GCMARKCONFIRM
2572 case GCMARKREPORT: {
2573 processmsg_gcmarkreport_I();
2575 } // case GCMARKREPORT
2578 processmsg_gcmarkedobj_I();
2580 } // case GCMARKEDOBJ
2583 // received a start moving objs msg
2584 processmsg_gcmovestart_I();
2586 } // case GCMOVESTART
2588 case GCMAPREQUEST: {
2589 // received a mapping info request msg
2590 processmsg_gcmaprequest_I();
2592 } // case GCMAPREQUEST
2595 // received a mapping info response msg
2596 processmsg_gcmapinfo_I();
2600 case GCLOBJREQUEST: {
2601 // received a large objs info request msg
2602 transferMarkResults_I();
2604 } // case GCLOBJREQUEST
2607 // received a large objs info response msg
2608 processmsg_gclobjinfo_I();
2610 } // case GCLOBJINFO
2612 case GCLOBJMAPPING: {
2613 // received a large obj mapping info msg
2614 processmsg_gclobjmapping_I();
2616 } // case GCLOBJMAPPING
2618 #endif // #ifdef MULTICORE_GC
2623 //memset(msgdata, '\0', sizeof(int) * msgdataindex);
2625 msglength = BAMBOO_MSG_BUF_LENGTH;
2627 //printf("++ msg: %x \n", type);
2628 if(msgdataindex != msgdatalast) {
2629 // still have available msg
2634 BAMBOO_DEBUGPRINT(0xe88d);
2638 // have new coming msg
2639 if(BAMBOO_MSG_AVAIL() != 0) {
2653 BAMBOO_DEBUGPRINT(0xe88e);
2657 /* if(isInterrupt) {
2665 int enqueuetasks(struct parameterwrapper *parameter,
2666 struct parameterwrapper *prevptr,
2667 struct ___Object___ *ptr,
2669 int numenterflags) {
2670 void * taskpointerarray[MAXTASKPARAMS];
2672 //int numparams=parameter->task->numParameters;
2673 int numiterators=parameter->task->numTotal-1;
2676 struct taskdescriptor * task=parameter->task;
2678 //this add the object to parameterwrapper
2679 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
2680 numenterflags, enterflags==NULL);
2682 /* Add enqueued object to parameter vector */
2683 taskpointerarray[parameter->slot]=ptr;
2685 /* Reset iterators */
2686 for(j=0; j<numiterators; j++) {
2687 toiReset(¶meter->iterators[j]);
2690 /* Find initial state */
2691 for(j=0; j<numiterators; j++) {
2693 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2694 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2696 /* Need to backtrack */
2697 toiReset(¶meter->iterators[j]);
2701 /* Nothing to enqueue */
2707 /* Enqueue current state */
2709 struct taskparamdescriptor *tpd=
2710 RUNMALLOC(sizeof(struct taskparamdescriptor));
2712 tpd->numParameters=numiterators+1;
2713 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2715 for(j=0; j<=numiterators; j++) {
2716 //store the actual parameters
2717 tpd->parameterArray[j]=taskpointerarray[j];
2720 if ((/*!gencontains(failedtasks, tpd)&&*/
2721 !gencontains(activetasks,tpd))) {
2722 genputtable(activetasks, tpd, tpd);
2724 RUNFREE(tpd->parameterArray);
2728 /* This loop iterates to the next parameter combination */
2729 if (numiterators==0)
2732 for(j=numiterators-1; j<numiterators; j++) {
2734 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2735 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2737 /* Need to backtrack */
2738 toiReset(¶meter->iterators[j]);
2742 /* Nothing more to enqueue */
2750 int enqueuetasks_I(struct parameterwrapper *parameter,
2751 struct parameterwrapper *prevptr,
2752 struct ___Object___ *ptr,
2754 int numenterflags) {
2755 void * taskpointerarray[MAXTASKPARAMS];
2757 //int numparams=parameter->task->numParameters;
2758 int numiterators=parameter->task->numTotal-1;
2763 struct taskdescriptor * task=parameter->task;
2765 //this add the object to parameterwrapper
2766 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2767 numenterflags, enterflags==NULL);
2769 /* Add enqueued object to parameter vector */
2770 taskpointerarray[parameter->slot]=ptr;
2772 /* Reset iterators */
2773 for(j=0; j<numiterators; j++) {
2774 toiReset(¶meter->iterators[j]);
2777 /* Find initial state */
2778 for(j=0; j<numiterators; j++) {
2780 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2781 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2783 /* Need to backtrack */
2784 toiReset(¶meter->iterators[j]);
2788 /* Nothing to enqueue */
2794 /* Enqueue current state */
2796 struct taskparamdescriptor *tpd=
2797 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2799 tpd->numParameters=numiterators+1;
2800 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2802 for(j=0; j<=numiterators; j++) {
2803 //store the actual parameters
2804 tpd->parameterArray[j]=taskpointerarray[j];
2807 if ((/*!gencontains(failedtasks, tpd)&&*/
2808 !gencontains(activetasks,tpd))) {
2809 genputtable_I(activetasks, tpd, tpd);
2811 RUNFREE(tpd->parameterArray);
2815 /* This loop iterates to the next parameter combination */
2816 if (numiterators==0)
2819 for(j=numiterators-1; j<numiterators; j++) {
2821 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2822 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2824 /* Need to backtrack */
2825 toiReset(¶meter->iterators[j]);
2829 /* Nothing more to enqueue */
2843 int containstag(struct ___Object___ *ptr,
2844 struct ___TagDescriptor___ *tag);
2846 #ifndef MULTICORE_GC
2847 void releasewritelock_r(void * lock, void * redirectlock) {
2849 int reallock = (int)lock;
2850 targetcore = (reallock >> 5) % NUMCORES;
2853 BAMBOO_DEBUGPRINT(0xe671);
2854 BAMBOO_DEBUGPRINT_REG((int)lock);
2855 BAMBOO_DEBUGPRINT_REG(reallock);
2856 BAMBOO_DEBUGPRINT_REG(targetcore);
2859 if(targetcore == BAMBOO_NUM_OF_CORE) {
2860 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2862 BAMBOO_DEBUGPRINT(0xf001);
2864 // reside on this core
2865 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2866 // no locks for this object, something is wrong
2867 BAMBOO_EXIT(0xa011);
2870 struct LockValue * lockvalue = NULL;
2872 BAMBOO_DEBUGPRINT(0xe672);
2874 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2875 lockvalue = (struct LockValue *)rwlock_obj;
2877 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2880 lockvalue->redirectlock = (int)redirectlock;
2882 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2885 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2887 BAMBOO_DEBUGPRINT(0xf000);
2891 // send lock release with redirect info msg
2892 // for 32 bit machine, the size is always 4 words
2893 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
2899 void executetasks() {
2900 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2903 struct ___Object___ * tmpparam = NULL;
2904 struct parameterdescriptor * pd=NULL;
2905 struct parameterwrapper *pw=NULL;
2915 while(hashsize(activetasks)>0) {
2920 BAMBOO_DEBUGPRINT(0xe990);
2923 /* See if there are any active tasks */
2924 //if (hashsize(activetasks)>0) {
2927 #ifdef ACCURATEPROFILE
2928 profileTaskStart("tpd checking");
2932 //clock1 = BAMBOO_GET_EXE_TIME();
2935 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2936 genfreekey(activetasks, currtpd);
2938 numparams=currtpd->task->numParameters;
2939 numtotal=currtpd->task->numTotal;
2941 // clear the lockRedirectTbl
2942 // (TODO, this table should be empty after all locks are released)
2944 /*for(j = 0; j < MAXTASKPARAMS; j++) {
2945 runtime_locks[j].redirectlock = 0;
2946 runtime_locks[j].value = 0;
2948 // get all required locks
2949 runtime_locklen = 0;
2950 // check which locks are needed
2951 for(i = 0; i < numparams; i++) {
2952 void * param = currtpd->parameterArray[i];
2956 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2958 taskpointerarray[i+OFFSET]=param;
2961 if(((struct ___Object___ *)param)->lock == NULL) {
2962 tmplock = (int)param;
2964 tmplock = (int)(((struct ___Object___ *)param)->lock);
2966 // insert into the locks array
2967 for(j = 0; j < runtime_locklen; j++) {
2968 if(runtime_locks[j].value == tmplock) {
2971 } else if(runtime_locks[j].value > tmplock) {
2976 int h = runtime_locklen;
2978 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
2979 runtime_locks[h].value = runtime_locks[h-1].value;
2981 runtime_locks[j].value = tmplock;
2982 runtime_locks[j].redirectlock = (int)param;
2985 } // line 2713: for(i = 0; i < numparams; i++)
2986 // grab these required locks
2988 BAMBOO_DEBUGPRINT(0xe991);
2991 //clock2 = BAMBOO_GET_EXE_TIME();
2993 for(i = 0; i < runtime_locklen; i++) {
2994 int * lock = (int *)(runtime_locks[i].redirectlock);
2996 // require locks for this parameter if it is not a startup object
2998 BAMBOO_DEBUGPRINT_REG((int)lock);
2999 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3002 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3004 BAMBOO_DEBUGPRINT(0xf001);
3007 //isInterrupt = false;
3010 BAMBOO_WAITING_FOR_LOCK(0);
3014 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
3018 grount = lockresult;
3028 //isInterrupt = true;
3030 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3032 BAMBOO_DEBUGPRINT(0xf000);
3037 BAMBOO_DEBUGPRINT(0xe992);
3038 BAMBOO_DEBUGPRINT_REG(lock);
3040 // check if has the lock already
3041 // can not get the lock, try later
3042 // release all grabbed locks for previous parameters
3043 for(j = 0; j < i; ++j) {
3044 lock = (int*)(runtime_locks[j].redirectlock);
3045 releasewritelock(lock);
3047 genputtable(activetasks, currtpd, currtpd);
3048 if(hashsize(activetasks) == 1) {
3049 // only one task right now, wait a little while before next try
3055 #ifdef ACCURATEPROFILE
3056 // fail, set the end of the checkTaskInfo
3063 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3066 clock3 = BAMBOO_GET_EXE_TIME();
3067 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3070 BAMBOO_DEBUGPRINT(0xe993);
3072 /* Make sure that the parameters are still in the queues */
3073 for(i=0; i<numparams; i++) {
3074 void * parameter=currtpd->parameterArray[i];
3078 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3079 classsize[((struct ___Object___ *)parameter)->type]);
3081 tmpparam = (struct ___Object___ *)parameter;
3082 pd=currtpd->task->descriptorarray[i];
3083 pw=(struct parameterwrapper *) pd->queue;
3084 /* Check that object is still in queue */
3086 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3088 BAMBOO_DEBUGPRINT(0xe994);
3089 BAMBOO_DEBUGPRINT_REG(parameter);
3091 // release grabbed locks
3092 for(j = 0; j < runtime_locklen; ++j) {
3093 int * lock = (int *)(runtime_locks[j].redirectlock);
3094 releasewritelock(lock);
3096 RUNFREE(currtpd->parameterArray);
3102 /* Check if the object's flags still meets requirements */
3106 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3107 andmask=pw->intarray[tmpi*2];
3108 checkmask=pw->intarray[tmpi*2+1];
3109 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3115 // flags are never suitable
3116 // remove this obj from the queue
3118 int UNUSED, UNUSED2;
3121 BAMBOO_DEBUGPRINT(0xe995);
3122 BAMBOO_DEBUGPRINT_REG(parameter);
3124 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3125 (int *) &enterflags, &UNUSED, &UNUSED2);
3126 ObjectHashremove(pw->objectset, (int)parameter);
3127 if (enterflags!=NULL)
3128 RUNFREE(enterflags);
3129 // release grabbed locks
3130 for(j = 0; j < runtime_locklen; ++j) {
3131 int * lock = (int *)(runtime_locks[j].redirectlock);
3132 releasewritelock(lock);
3134 RUNFREE(currtpd->parameterArray);
3138 #ifdef ACCURATEPROFILE
3139 // fail, set the end of the checkTaskInfo
3144 } // line 2878: if (!ismet)
3148 /* Check that object still has necessary tags */
3149 for(j=0; j<pd->numbertags; j++) {
3150 int slotid=pd->tagarray[2*j]+numparams;
3151 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3152 if (!containstag(parameter, tagd)) {
3154 BAMBOO_DEBUGPRINT(0xe996);
3157 // release grabbed locks
3159 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3160 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3161 releasewritelock(lock);
3164 RUNFREE(currtpd->parameterArray);
3168 } // line2911: if (!containstag(parameter, tagd))
3169 } // line 2808: for(j=0; j<pd->numbertags; j++)
3171 taskpointerarray[i+OFFSET]=parameter;
3172 } // line 2824: for(i=0; i<numparams; i++)
3174 for(; i<numtotal; i++) {
3175 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3180 /* Actually call task */
3182 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3183 taskpointerarray[1]=NULL;
3186 #ifdef ACCURATEPROFILE
3187 // check finish, set the end of the checkTaskInfo
3190 profileTaskStart(currtpd->task->name);
3194 //clock4 = BAMBOO_GET_EXE_TIME();
3195 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3198 BAMBOO_DEBUGPRINT(0xe997);
3200 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
3203 //clock5 = BAMBOO_GET_EXE_TIME();
3204 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3207 #ifdef ACCURATEPROFILE
3208 // task finish, set the end of the checkTaskInfo
3210 // new a PostTaskInfo for the post-task execution
3211 profileTaskStart("post task execution");
3215 BAMBOO_DEBUGPRINT(0xe998);
3216 BAMBOO_DEBUGPRINT_REG(islock);
3221 BAMBOO_DEBUGPRINT(0xe999);
3223 for(i = 0; i < runtime_locklen; ++i) {
3224 void * ptr = (void *)(runtime_locks[i].redirectlock);
3225 int * lock = (int *)(runtime_locks[i].value);
3227 BAMBOO_DEBUGPRINT_REG((int)ptr);
3228 BAMBOO_DEBUGPRINT_REG((int)lock);
3229 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3231 #ifndef MULTICORE_GC
3232 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3234 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3235 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3236 releasewritelock_r(lock, (int *)redirectlock);
3241 releasewritelock(ptr);
3244 } // line 3015: if(islock)
3247 //clock6 = BAMBOO_GET_EXE_TIME();
3248 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3251 // post task execution finish, set the end of the postTaskInfo
3255 // Free up task parameter descriptor
3256 RUNFREE(currtpd->parameterArray);
3260 BAMBOO_DEBUGPRINT(0xe99a);
3263 //clock7 = BAMBOO_GET_EXE_TIME();
3264 //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));
3267 //} // if (hashsize(activetasks)>0)
3268 } // while(hashsize(activetasks)>0)
3270 BAMBOO_DEBUGPRINT(0xe99b);
3274 /* This function processes an objects tags */
3275 void processtags(struct parameterdescriptor *pd,
3277 struct parameterwrapper *parameter,
3278 int * iteratorcount,
3283 for(i=0; i<pd->numbertags; i++) {
3284 int slotid=pd->tagarray[2*i];
3285 int tagid=pd->tagarray[2*i+1];
3287 if (statusarray[slotid+numparams]==0) {
3288 parameter->iterators[*iteratorcount].istag=1;
3289 parameter->iterators[*iteratorcount].tagid=tagid;
3290 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3291 parameter->iterators[*iteratorcount].tagobjectslot=index;
3292 statusarray[slotid+numparams]=1;
3299 void processobject(struct parameterwrapper *parameter,
3301 struct parameterdescriptor *pd,
3307 struct ObjectHash * objectset=
3308 ((struct parameterwrapper *)pd->queue)->objectset;
3310 parameter->iterators[*iteratorcount].istag=0;
3311 parameter->iterators[*iteratorcount].slot=index;
3312 parameter->iterators[*iteratorcount].objectset=objectset;
3313 statusarray[index]=1;
3315 for(i=0; i<pd->numbertags; i++) {
3316 int slotid=pd->tagarray[2*i];
3317 //int tagid=pd->tagarray[2*i+1];
3318 if (statusarray[slotid+numparams]!=0) {
3319 /* This tag has already been enqueued, use it to narrow search */
3320 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3325 parameter->iterators[*iteratorcount].numtags=tagcount;
3330 /* This function builds the iterators for a task & parameter */
3332 void builditerators(struct taskdescriptor * task,
3334 struct parameterwrapper * parameter) {
3335 int statusarray[MAXTASKPARAMS];
3337 int numparams=task->numParameters;
3338 int iteratorcount=0;
3339 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3341 statusarray[index]=1; /* Initial parameter */
3342 /* Process tags for initial iterator */
3344 processtags(task->descriptorarray[index], index, parameter,
3345 &iteratorcount, statusarray, numparams);
3349 /* Check for objects with existing tags */
3350 for(i=0; i<numparams; i++) {
3351 if (statusarray[i]==0) {
3352 struct parameterdescriptor *pd=task->descriptorarray[i];
3354 for(j=0; j<pd->numbertags; j++) {
3355 int slotid=pd->tagarray[2*j];
3356 if(statusarray[slotid+numparams]!=0) {
3357 processobject(parameter, i, pd, &iteratorcount, statusarray,
3359 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3366 /* Next do objects w/ unbound tags*/
3368 for(i=0; i<numparams; i++) {
3369 if (statusarray[i]==0) {
3370 struct parameterdescriptor *pd=task->descriptorarray[i];
3371 if (pd->numbertags>0) {
3372 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3373 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3379 /* Nothing with a tag enqueued */
3381 for(i=0; i<numparams; i++) {
3382 if (statusarray[i]==0) {
3383 struct parameterdescriptor *pd=task->descriptorarray[i];
3384 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3385 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3398 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3401 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3402 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3404 printf("%s\n", task->name);
3406 for(j=0; j<task->numParameters; j++) {
3407 struct parameterdescriptor *param=task->descriptorarray[j];
3408 struct parameterwrapper *parameter=param->queue;
3409 struct ObjectHash * set=parameter->objectset;
3410 struct ObjectIterator objit;
3412 printf(" Parameter %d\n", j);
3414 ObjectHashiterator(set, &objit);
3415 while(ObjhasNext(&objit)) {
3416 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3417 struct ___Object___ * tagptr=obj->___tags___;
3418 int nonfailed=Objdata4(&objit);
3419 int numflags=Objdata3(&objit);
3420 int flags=Objdata2(&objit);
3423 printf(" Contains %lx\n", obj);
3424 printf(" flag=%d\n", obj->flag);
3427 } else if (tagptr->type==TAGTYPE) {
3429 printf(" tag=%lx\n",tagptr);
3435 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3436 for(; tagindex<ao->___cachedCode___; tagindex++) {
3438 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3451 /* This function processes the task information to create queues for
3452 each parameter type. */
3454 void processtasks() {
3456 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3459 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3460 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3463 /* Build objectsets */
3464 for(j=0; j<task->numParameters; j++) {
3465 struct parameterdescriptor *param=task->descriptorarray[j];
3466 struct parameterwrapper *parameter=param->queue;
3467 parameter->objectset=allocateObjectHash(10);
3468 parameter->task=task;
3471 /* Build iterators for parameters */
3472 for(j=0; j<task->numParameters; j++) {
3473 struct parameterdescriptor *param=task->descriptorarray[j];
3474 struct parameterwrapper *parameter=param->queue;
3475 builditerators(task, j, parameter);
3480 void toiReset(struct tagobjectiterator * it) {
3483 } else if (it->numtags>0) {
3486 ObjectHashiterator(it->objectset, &it->it);
3490 int toiHasNext(struct tagobjectiterator *it,
3491 void ** objectarray OPTARG(int * failed)) {
3494 /* Get object with tags */
3495 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3496 struct ___Object___ *tagptr=obj->___tags___;
3497 if (tagptr->type==TAGTYPE) {
3498 if ((it->tagobjindex==0)&& /* First object */
3499 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3504 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3505 int tagindex=it->tagobjindex;
3506 for(; tagindex<ao->___cachedCode___; tagindex++) {
3507 struct ___TagDescriptor___ *td=
3508 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3509 if (td->flag==it->tagid) {
3510 it->tagobjindex=tagindex; /* Found right type of tag */
3516 } else if (it->numtags>0) {
3517 /* Use tags to locate appropriate objects */
3518 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3519 struct ___Object___ *objptr=tag->flagptr;
3521 if (objptr->type!=OBJECTARRAYTYPE) {
3522 if (it->tagobjindex>0)
3524 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3526 for(i=1; i<it->numtags; i++) {
3527 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3528 if (!containstag(objptr,tag2))
3533 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3536 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
3537 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3538 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3540 for(i=1; i<it->numtags; i++) {
3541 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3542 if (!containstag(objptr,tag2))
3545 it->tagobjindex=tagindex;
3550 it->tagobjindex=tagindex;
3554 return ObjhasNext(&it->it);
3558 int containstag(struct ___Object___ *ptr,
3559 struct ___TagDescriptor___ *tag) {
3561 struct ___Object___ * objptr=tag->flagptr;
3562 if (objptr->type==OBJECTARRAYTYPE) {
3563 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3564 for(j=0; j<ao->___cachedCode___; j++) {
3565 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3575 void toiNext(struct tagobjectiterator *it,
3576 void ** objectarray OPTARG(int * failed)) {
3577 /* hasNext has all of the intelligence */
3580 /* Get object with tags */
3581 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3582 struct ___Object___ *tagptr=obj->___tags___;
3583 if (tagptr->type==TAGTYPE) {
3585 objectarray[it->slot]=tagptr;
3587 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3588 objectarray[it->slot]=
3589 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
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;
3595 if (objptr->type!=OBJECTARRAYTYPE) {
3597 objectarray[it->slot]=objptr;
3599 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3600 objectarray[it->slot]=
3601 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3604 /* Iterate object */
3605 objectarray[it->slot]=(void *)Objkey(&it->it);
3611 inline void profileTaskStart(char * taskname) {
3612 if(!taskInfoOverflow) {
3613 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
3614 taskInfoArray[taskInfoIndex] = taskInfo;
3615 taskInfo->taskName = taskname;
3616 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
3617 taskInfo->endTime = -1;
3618 taskInfo->exitIndex = -1;
3619 taskInfo->newObjs = NULL;
3623 inline void profileTaskEnd() {
3624 if(!taskInfoOverflow) {
3625 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
3627 if(taskInfoIndex == TASKINFOLENGTH) {
3628 taskInfoOverflow = true;
3629 //taskInfoIndex = 0;
3634 // output the profiling data
3635 void outputProfileData() {
3638 unsigned long long totaltasktime = 0;
3639 unsigned long long preprocessingtime = 0;
3640 unsigned long long objqueuecheckingtime = 0;
3641 unsigned long long postprocessingtime = 0;
3642 //int interruptiontime = 0;
3643 unsigned long long other = 0;
3644 unsigned long long averagetasktime = 0;
3647 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
3648 // output task related info
3649 for(i = 0; i < taskInfoIndex; i++) {
3650 TaskInfo* tmpTInfo = taskInfoArray[i];
3651 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
3652 printf("%s, %lld, %lld, %lld, %lld",
3653 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
3654 duration, tmpTInfo->exitIndex);
3655 // summarize new obj info
3656 if(tmpTInfo->newObjs != NULL) {
3657 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3658 struct RuntimeIterator * iter = NULL;
3659 while(0 == isEmpty(tmpTInfo->newObjs)) {
3660 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3661 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3663 RuntimeHashget(nobjtbl, (int)objtype, &num);
3664 RuntimeHashremovekey(nobjtbl, (int)objtype);
3666 RuntimeHashadd(nobjtbl, (int)objtype, num);
3668 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3670 //printf(stderr, "new obj!\n");
3673 // output all new obj info
3674 iter = RuntimeHashcreateiterator(nobjtbl);
3675 while(RunhasNext(iter)) {
3676 char * objtype = (char *)Runkey(iter);
3677 int num = Runnext(iter);
3678 printf(", %s, %d", objtype, num);
3682 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
3683 preprocessingtime += duration;
3684 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
3685 postprocessingtime += duration;
3686 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
3687 objqueuecheckingtime += duration;
3689 totaltasktime += duration;
3690 averagetasktime += duration;
3695 if(taskInfoOverflow) {
3696 printf("Caution: task info overflow!\n");
3699 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
3700 averagetasktime /= tasknum;
3702 printf("\nTotal time: %lld\n", totalexetime);
3703 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
3704 (int)(((double)totaltasktime/(double)totalexetime)*100));
3705 printf("Total objqueue checking time: %lld (%d%%)\n",
3706 objqueuecheckingtime,
3707 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
3708 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
3709 (int)(((double)preprocessingtime/(double)totalexetime)*100));
3710 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
3711 (int)(((double)postprocessingtime/(double)totalexetime)*100));
3712 printf("Other time: %lld (%d%%)\n", other,
3713 (int)(((double)other/(double)totalexetime)*100));
3715 printf("\nAverage task execution time: %lld\n", averagetasktime);
3720 BAMBOO_DEBUGPRINT(0xdddd);
3721 // output task related info
3722 for(i= 0; i < taskInfoIndex; i++) {
3723 TaskInfo* tmpTInfo = taskInfoArray[i];
3724 char* tmpName = tmpTInfo->taskName;
3725 int nameLen = strlen(tmpName);
3726 BAMBOO_DEBUGPRINT(0xddda);
3727 for(j = 0; j < nameLen; j++) {
3728 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
3730 BAMBOO_DEBUGPRINT(0xdddb);
3731 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
3732 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
3733 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
3734 if(tmpTInfo->newObjs != NULL) {
3735 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3736 struct RuntimeIterator * iter = NULL;
3737 while(0 == isEmpty(tmpTInfo->newObjs)) {
3738 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3739 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3741 RuntimeHashget(nobjtbl, (int)objtype, &num);
3742 RuntimeHashremovekey(nobjtbl, (int)objtype);
3744 RuntimeHashadd(nobjtbl, (int)objtype, num);
3746 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3750 // ouput all new obj info
3751 iter = RuntimeHashcreateiterator(nobjtbl);
3752 while(RunhasNext(iter)) {
3753 char * objtype = (char *)Runkey(iter);
3754 int num = Runnext(iter);
3755 int nameLen = strlen(objtype);
3756 BAMBOO_DEBUGPRINT(0xddda);
3757 for(j = 0; j < nameLen; j++) {
3758 BAMBOO_DEBUGPRINT_REG(objtype[j]);
3760 BAMBOO_DEBUGPRINT(0xdddb);
3761 BAMBOO_DEBUGPRINT_REG(num);
3764 BAMBOO_DEBUGPRINT(0xdddc);
3767 if(taskInfoOverflow) {
3768 BAMBOO_DEBUGPRINT(0xefee);
3771 // output interrupt related info
3772 /*for(i = 0; i < interruptInfoIndex; i++) {
3773 InterruptInfo* tmpIInfo = interruptInfoArray[i];
3774 BAMBOO_DEBUGPRINT(0xddde);
3775 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
3776 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
3777 BAMBOO_DEBUGPRINT(0xdddf);
3780 if(interruptInfoOverflow) {
3781 BAMBOO_DEBUGPRINT(0xefef);
3784 BAMBOO_DEBUGPRINT(0xeeee);
3787 #endif // #ifdef PROFILE