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();
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(20);
120 //gcpointertbl = allocateMGCHash(20);
121 gcforwardobjtbl = allocateMGCHash(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(20);
151 objRedirectLockTbl = allocateRuntimeHash(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);
200 inline __attribute__((always_inline))
201 bool checkObjQueue() {
203 struct transObjInfo * objInfo = NULL;
207 #ifdef ACCURATEPROFILE
208 bool isChecking = false;
209 if(!isEmpty(&objqueue)) {
210 profileTaskStart("objqueue checking");
212 } // if(!isEmpty(&objqueue))
216 while(!isEmpty(&objqueue)) {
218 BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE();
220 BAMBOO_DEBUGPRINT(0xf001);
223 //isInterrupt = false;
226 BAMBOO_DEBUGPRINT(0xeee1);
229 objInfo = (struct transObjInfo *)getItem(&objqueue);
230 obj = objInfo->objptr;
232 BAMBOO_DEBUGPRINT_REG((int)obj);
234 // grab lock and flush the obj
238 BAMBOO_WAITING_FOR_LOCK();
239 } // while(!lockflag)
242 BAMBOO_DEBUGPRINT_REG(grount);
257 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
258 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
259 classsize[((struct ___Object___ *)obj)->type]);
261 // enqueue the object
262 for(k = 0; k < objInfo->length; ++k) {
263 int taskindex = objInfo->queues[2 * k];
264 int paramindex = objInfo->queues[2 * k + 1];
265 struct parameterwrapper ** queues =
266 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
268 BAMBOO_DEBUGPRINT_REG(taskindex);
269 BAMBOO_DEBUGPRINT_REG(paramindex);
270 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
271 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
272 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
273 (long)obj, tmpptr->flag);
275 enqueueObject_I(obj, queues, 1);
277 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
279 } // for(k = 0; k < objInfo->length; ++k)
280 releasewritelock_I(obj);
281 RUNFREE(objInfo->queues);
285 // put it at the end of the queue if no update version in the queue
286 struct QueueItem * qitem = getHead(&objqueue);
287 struct QueueItem * prev = NULL;
288 while(qitem != NULL) {
289 struct transObjInfo * tmpinfo =
290 (struct transObjInfo *)(qitem->objectptr);
291 if(tmpinfo->objptr == obj) {
292 // the same object in the queue, which should be enqueued
293 // recently. Current one is outdate, do not re-enqueue it
294 RUNFREE(objInfo->queues);
299 } // if(tmpinfo->objptr == obj)
300 qitem = getNextQueueItem(prev);
301 } // while(qitem != NULL)
302 // try to execute active tasks already enqueued first
303 addNewItem_I(&objqueue, objInfo);
305 //isInterrupt = true;
308 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
310 BAMBOO_DEBUGPRINT(0xf000);
314 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
316 BAMBOO_DEBUGPRINT(0xf000);
318 } // while(!isEmpty(&objqueue))
321 #ifdef ACCURATEPROFILE
329 BAMBOO_DEBUGPRINT(0xee02);
334 inline __attribute__((always_inline))
335 void checkCoreStatus() {
336 bool allStall = false;
340 (waitconfirm && (numconfirm == 0))) {
342 BAMBOO_DEBUGPRINT(0xee04);
343 BAMBOO_DEBUGPRINT_REG(waitconfirm);
345 BAMBOO_START_CRITICAL_SECTION_STATUS();
347 BAMBOO_DEBUGPRINT(0xf001);
349 corestatus[BAMBOO_NUM_OF_CORE] = 0;
350 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
351 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
352 // check the status of all cores
355 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
357 for(i = 0; i < NUMCORESACTIVE; ++i) {
359 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
361 if(corestatus[i] != 0) {
365 } // for(i = 0; i < NUMCORESACTIVE; ++i)
367 // check if the sum of send objs and receive obj are the same
368 // yes->check if the info is the latest; no->go on executing
370 for(i = 0; i < NUMCORESACTIVE; ++i) {
371 sumsendobj += numsendobjs[i];
373 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
375 } // for(i = 0; i < NUMCORESACTIVE; ++i)
376 for(i = 0; i < NUMCORESACTIVE; ++i) {
377 sumsendobj -= numreceiveobjs[i];
379 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
381 } // for(i = 0; i < NUMCORESACTIVE; ++i)
382 if(0 == sumsendobj) {
384 // the first time found all cores stall
385 // send out status confirm msg to all other cores
386 // reset the corestatus array too
388 BAMBOO_DEBUGPRINT(0xee05);
390 corestatus[BAMBOO_NUM_OF_CORE] = 1;
391 for(i = 1; i < NUMCORESACTIVE; ++i) {
393 // send status confirm msg to core i
394 send_msg_1(i, STATUSCONFIRM, false);
395 } // for(i = 1; i < NUMCORESACTIVE; ++i)
397 numconfirm = NUMCORESACTIVE - 1;
399 // all the core status info are the latest
400 // terminate; for profiling mode, send request to all
401 // other cores to pour out profiling data
403 BAMBOO_DEBUGPRINT(0xee06);
407 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
410 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
411 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
412 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
414 // profile mode, send msgs to other cores to request pouring
415 // out progiling data
417 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
419 BAMBOO_DEBUGPRINT(0xf000);
421 for(i = 1; i < NUMCORESACTIVE; ++i) {
422 // send profile request msg to core i
423 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
424 } // for(i = 1; i < NUMCORESACTIVE; ++i)
425 // pour profiling data on startup core
428 BAMBOO_START_CRITICAL_SECTION_STATUS();
430 BAMBOO_DEBUGPRINT(0xf001);
432 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
433 // check the status of all cores
436 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
438 for(i = 0; i < NUMCORESACTIVE; ++i) {
440 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
442 if(profilestatus[i] != 0) {
446 } // for(i = 0; i < NUMCORESACTIVE; ++i)
449 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
451 BAMBOO_DEBUGPRINT(0xf000);
461 // gc_profile mode, ourput gc prfiling data
464 gc_outputProfileData();
465 #endif // #ifdef GC_PROFILE
466 #endif // #ifdef MULTICORE_GC
468 terminate(); // All done.
469 } // if(!waitconfirm)
471 // still some objects on the fly on the network
472 // reset the waitconfirm and numconfirm
474 BAMBOO_DEBUGPRINT(0xee07);
478 } // if(0 == sumsendobj)
480 // not all cores are stall, keep on waiting
482 BAMBOO_DEBUGPRINT(0xee08);
487 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
489 BAMBOO_DEBUGPRINT(0xf000);
491 } // if((!waitconfirm) ||
494 // main function for each core
495 inline void run(void * arg) {
499 bool sendStall = false;
501 bool tocontinue = false;
503 corenum = BAMBOO_GET_NUM_OF_CORE();
505 BAMBOO_DEBUGPRINT(0xeeee);
506 BAMBOO_DEBUGPRINT_REG(corenum);
507 BAMBOO_DEBUGPRINT(STARTUPCORE);
510 // initialize runtime data structures
513 // other architecture related initialization
517 initializeexithandler();
519 // main process of the execution module
520 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
521 // non-executing cores, only processing communications
524 BAMBOO_DEBUGPRINT(0xee01);
525 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
526 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
527 profileTaskStart("msg handling");
531 //isInterrupt = false;
535 /* Create queue of active tasks */
537 genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
538 (int(*) (void *,void *)) &comparetpd);
540 /* Process task information */
543 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
544 /* Create startup object */
545 createstartupobject(argc, argv);
549 BAMBOO_DEBUGPRINT(0xee00);
554 // check if need to do GC
558 // check if there are new active tasks can be executed
565 while(receiveObject() != -1) {
570 BAMBOO_DEBUGPRINT(0xee01);
573 // check if there are some pending objects,
574 // if yes, enqueue them and executetasks again
575 tocontinue = checkObjQueue();
579 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
582 BAMBOO_DEBUGPRINT(0xee03);
590 BAMBOO_DEBUGPRINT(0xee09);
596 // wait for some time
599 BAMBOO_DEBUGPRINT(0xee0a);
605 // send StallMsg to startup core
607 BAMBOO_DEBUGPRINT(0xee0b);
610 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
611 self_numsendobjs, self_numreceiveobjs, false);
623 BAMBOO_DEBUGPRINT(0xee0c);
626 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
629 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
633 struct ___createstartupobject____I_locals {
636 struct ___StartupObject___ * ___startupobject___;
637 struct ArrayObject * ___stringarray___;
638 }; // struct ___createstartupobject____I_locals
640 void createstartupobject(int argc,
644 /* Allocate startup object */
646 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
647 struct ___StartupObject___ *startupobject=
648 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
649 ___locals___.___startupobject___ = startupobject;
650 struct ArrayObject * stringarray=
651 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
652 ___locals___.___stringarray___ = stringarray;
654 struct ___StartupObject___ *startupobject=
655 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
656 struct ArrayObject * stringarray=
657 allocate_newarray(STRINGARRAYTYPE, argc-1);
659 /* Build array of strings */
660 startupobject->___parameters___=stringarray;
661 for(i=1; i<argc; i++) {
662 int length=strlen(argv[i]);
664 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
666 struct ___String___ *newstring=NewString(argv[i],length);
668 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
672 startupobject->version = 0;
673 startupobject->lock = NULL;
675 /* Set initialized flag for startup object */
676 flagorandinit(startupobject,1,0xFFFFFFFF);
677 enqueueObject(startupobject, NULL, 0);
679 BAMBOO_CACHE_FLUSH_ALL();
683 int hashCodetpd(struct taskparamdescriptor *ftd) {
684 int hash=(int)ftd->task;
686 for(i=0; i<ftd->numParameters; i++) {
687 hash^=(int)ftd->parameterArray[i];
692 int comparetpd(struct taskparamdescriptor *ftd1,
693 struct taskparamdescriptor *ftd2) {
695 if (ftd1->task!=ftd2->task)
697 for(i=0; i<ftd1->numParameters; i++)
698 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
703 /* This function sets a tag. */
705 void tagset(void *ptr,
706 struct ___Object___ * obj,
707 struct ___TagDescriptor___ * tagd) {
709 void tagset(struct ___Object___ * obj,
710 struct ___TagDescriptor___ * tagd) {
712 struct ArrayObject * ao=NULL;
713 struct ___Object___ * tagptr=obj->___tags___;
715 obj->___tags___=(struct ___Object___ *)tagd;
717 /* Have to check if it is already set */
718 if (tagptr->type==TAGTYPE) {
719 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
724 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
725 struct ArrayObject * ao=
726 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
727 obj=(struct ___Object___ *)ptrarray[2];
728 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
729 td=(struct ___TagDescriptor___ *) obj->___tags___;
731 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
734 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
735 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
736 obj->___tags___=(struct ___Object___ *) ao;
737 ao->___cachedCode___=2;
741 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
742 for(i=0; i<ao->___cachedCode___; i++) {
743 struct ___TagDescriptor___ * td=
744 ARRAYGET(ao, struct ___TagDescriptor___*, i);
749 if (ao->___cachedCode___<ao->___length___) {
750 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
751 ao->___cachedCode___++;
754 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
755 struct ArrayObject * aonew=
756 allocate_newarray(&ptrarray,TAGARRAYTYPE,
757 TAGARRAYINTERVAL+ao->___length___);
758 obj=(struct ___Object___ *)ptrarray[2];
759 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
760 ao=(struct ArrayObject *)obj->___tags___;
762 struct ArrayObject * aonew=
763 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
766 aonew->___cachedCode___=ao->___length___+1;
767 for(i=0; i<ao->___length___; i++) {
768 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
769 ARRAYGET(ao, struct ___TagDescriptor___*, i));
771 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
777 struct ___Object___ * tagset=tagd->flagptr;
780 } else if (tagset->type!=OBJECTARRAYTYPE) {
782 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
783 struct ArrayObject * ao=
784 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
785 obj=(struct ___Object___ *)ptrarray[2];
786 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
788 struct ArrayObject * ao=
789 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
791 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
792 ARRAYSET(ao, struct ___Object___ *, 1, obj);
793 ao->___cachedCode___=2;
794 tagd->flagptr=(struct ___Object___ *)ao;
796 struct ArrayObject *ao=(struct ArrayObject *) tagset;
797 if (ao->___cachedCode___<ao->___length___) {
798 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
802 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
803 struct ArrayObject * aonew=
804 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
805 OBJECTARRAYINTERVAL+ao->___length___);
806 obj=(struct ___Object___ *)ptrarray[2];
807 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
808 ao=(struct ArrayObject *)tagd->flagptr;
810 struct ArrayObject * aonew=
811 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
813 aonew->___cachedCode___=ao->___cachedCode___+1;
814 for(i=0; i<ao->___length___; i++) {
815 ARRAYSET(aonew, struct ___Object___*, i,
816 ARRAYGET(ao, struct ___Object___*, i));
818 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
819 tagd->flagptr=(struct ___Object___ *) aonew;
825 /* This function clears a tag. */
827 void tagclear(void *ptr,
828 struct ___Object___ * obj,
829 struct ___TagDescriptor___ * tagd) {
831 void tagclear(struct ___Object___ * obj,
832 struct ___TagDescriptor___ * tagd) {
834 /* We'll assume that tag is alway there.
835 Need to statically check for this of course. */
836 struct ___Object___ * tagptr=obj->___tags___;
838 if (tagptr->type==TAGTYPE) {
839 if ((struct ___TagDescriptor___ *)tagptr==tagd)
840 obj->___tags___=NULL;
842 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
844 for(i=0; i<ao->___cachedCode___; i++) {
845 struct ___TagDescriptor___ * td=
846 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
848 ao->___cachedCode___--;
849 if (i<ao->___cachedCode___)
850 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
851 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
852 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
853 if (ao->___cachedCode___==0)
854 obj->___tags___=NULL;
861 struct ___Object___ *tagset=tagd->flagptr;
862 if (tagset->type!=OBJECTARRAYTYPE) {
866 struct ArrayObject *ao=(struct ArrayObject *) tagset;
868 for(i=0; i<ao->___cachedCode___; i++) {
869 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
871 ao->___cachedCode___--;
872 if (i<ao->___cachedCode___)
873 ARRAYSET(ao, struct ___Object___ *, i,
874 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
875 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
876 if (ao->___cachedCode___==0)
887 /* This function allocates a new tag. */
889 struct ___TagDescriptor___ * allocate_tag(void *ptr,
891 struct ___TagDescriptor___ * v=
892 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
895 struct ___TagDescriptor___ * allocate_tag(int index) {
896 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
905 /* This function updates the flag for object ptr. It or's the flag
906 with the or mask and and's it with the andmask. */
908 void flagbody(struct ___Object___ *ptr,
910 struct parameterwrapper ** queues,
914 int flagcomp(const int *val1, const int *val2) {
915 return (*val1)-(*val2);
918 void flagorand(void * ptr,
921 struct parameterwrapper ** queues,
924 int oldflag=((int *)ptr)[1];
925 int flag=ormask|oldflag;
927 flagbody(ptr, flag, queues, length, false);
931 bool intflagorand(void * ptr,
935 int oldflag=((int *)ptr)[1];
936 int flag=ormask|oldflag;
938 if (flag==oldflag) /* Don't do anything */
941 flagbody(ptr, flag, NULL, 0, false);
947 void flagorandinit(void * ptr,
950 int oldflag=((int *)ptr)[1];
951 int flag=ormask|oldflag;
953 flagbody(ptr,flag,NULL,0,true);
956 void flagbody(struct ___Object___ *ptr,
958 struct parameterwrapper ** vqueues,
961 struct parameterwrapper * flagptr = NULL;
963 struct parameterwrapper ** queues = vqueues;
964 int length = vlength;
967 int * enterflags = NULL;
968 if((!isnew) && (queues == NULL)) {
969 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
970 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
971 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
978 /*Remove object from all queues */
979 for(i = 0; i < length; ++i) {
981 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
982 (int *) &enterflags, &UNUSED, &UNUSED2);
983 ObjectHashremove(flagptr->objectset, (int)ptr);
984 if (enterflags!=NULL)
989 void enqueueObject(void * vptr,
990 struct parameterwrapper ** vqueues,
992 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
995 //struct QueueItem *tmpptr;
996 struct parameterwrapper * parameter=NULL;
999 struct parameterwrapper * prevptr=NULL;
1000 struct ___Object___ *tagptr=NULL;
1001 struct parameterwrapper ** queues = vqueues;
1002 int length = vlength;
1003 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1006 if(queues == NULL) {
1007 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1008 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1010 tagptr=ptr->___tags___;
1012 /* Outer loop iterates through all parameter queues an object of
1013 this type could be in. */
1014 for(j = 0; j < length; ++j) {
1015 parameter = queues[j];
1017 if (parameter->numbertags>0) {
1019 goto nextloop; //that means the object has no tag
1020 //but that param needs tag
1021 else if(tagptr->type==TAGTYPE) { //one tag
1022 //struct ___TagDescriptor___ * tag=
1023 //(struct ___TagDescriptor___*) tagptr;
1024 for(i=0; i<parameter->numbertags; i++) {
1025 //slotid is parameter->tagarray[2*i];
1026 int tagid=parameter->tagarray[2*i+1];
1027 if (tagid!=tagptr->flag)
1028 goto nextloop; /*We don't have this tag */
1030 } else { //multiple tags
1031 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1032 for(i=0; i<parameter->numbertags; i++) {
1033 //slotid is parameter->tagarray[2*i];
1034 int tagid=parameter->tagarray[2*i+1];
1036 for(j=0; j<ao->___cachedCode___; j++) {
1037 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1048 for(i=0; i<parameter->numberofterms; i++) {
1049 int andmask=parameter->intarray[i*2];
1050 int checkmask=parameter->intarray[i*2+1];
1051 if ((ptr->flag&andmask)==checkmask) {
1052 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1063 void enqueueObject_I(void * vptr,
1064 struct parameterwrapper ** vqueues,
1066 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1069 //struct QueueItem *tmpptr;
1070 struct parameterwrapper * parameter=NULL;
1073 struct parameterwrapper * prevptr=NULL;
1074 struct ___Object___ *tagptr=NULL;
1075 struct parameterwrapper ** queues = vqueues;
1076 int length = vlength;
1077 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1080 if(queues == NULL) {
1081 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1082 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1084 tagptr=ptr->___tags___;
1086 /* Outer loop iterates through all parameter queues an object of
1087 this type could be in. */
1088 for(j = 0; j < length; ++j) {
1089 parameter = queues[j];
1091 if (parameter->numbertags>0) {
1093 goto nextloop; //that means the object has no tag
1094 //but that param needs tag
1095 else if(tagptr->type==TAGTYPE) { //one tag
1096 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1097 for(i=0; i<parameter->numbertags; i++) {
1098 //slotid is parameter->tagarray[2*i];
1099 int tagid=parameter->tagarray[2*i+1];
1100 if (tagid!=tagptr->flag)
1101 goto nextloop; /*We don't have this tag */
1103 } else { //multiple tags
1104 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1105 for(i=0; i<parameter->numbertags; i++) {
1106 //slotid is parameter->tagarray[2*i];
1107 int tagid=parameter->tagarray[2*i+1];
1109 for(j=0; j<ao->___cachedCode___; j++) {
1110 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1121 for(i=0; i<parameter->numberofterms; i++) {
1122 int andmask=parameter->intarray[i*2];
1123 int checkmask=parameter->intarray[i*2+1];
1124 if ((ptr->flag&andmask)==checkmask) {
1125 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1137 int * getAliasLock(void ** ptrs,
1139 struct RuntimeHash * tbl) {
1141 return (int*)(RUNMALLOC(sizeof(int)));
1146 bool redirect = false;
1147 int redirectlock = 0;
1148 for(; i < length; i++) {
1149 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1152 if(ptr->lock == NULL) {
1155 lock = (int)(ptr->lock);
1158 if(lock != redirectlock) {
1159 RuntimeHashadd(tbl, lock, redirectlock);
1162 if(RuntimeHashcontainskey(tbl, lock)) {
1163 // already redirected
1165 RuntimeHashget(tbl, lock, &redirectlock);
1166 for(; j < locklen; j++) {
1167 if(locks[j] != redirectlock) {
1168 RuntimeHashadd(tbl, locks[j], redirectlock);
1173 for(j = 0; j < locklen; j++) {
1174 if(locks[j] == lock) {
1177 } else if(locks[j] > lock) {
1184 locks[h] = locks[h-1];
1193 return (int *)redirectlock;
1195 return (int *)(locks[0]);
1200 void addAliasLock(void * ptr,
1202 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1203 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1204 // originally no alias lock associated or have a different alias lock
1205 // flush it as the new one
1206 obj->lock = (int *)lock;
1211 inline void setTaskExitIndex(int index) {
1212 taskInfoArray[taskInfoIndex]->exitIndex = index;
1215 inline void addNewObjInfo(void * nobj) {
1216 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1217 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1219 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1224 void * localmalloc_I(int coren,
1230 int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1231 int totest = tofindb;
1232 int bound = BAMBOO_SMEM_SIZE_L;
1236 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1237 int nsize = bamboo_smemtbl[totest];
1238 bool islocal = true;
1240 bool tocheck = true;
1241 // have some space in the block
1242 if(totest == tofindb) {
1243 // the first partition
1244 size = bound - nsize;
1245 } else if(nsize == 0) {
1246 // an empty partition, can be appended
1249 // not an empty partition, can not be appended
1250 // the last continuous block is not big enough, go to check the next
1254 } // if(totest == tofindb) else if(nsize == 0) else ...
1257 // have enough space in the block, malloc
1261 // no enough space yet, try to append next continuous block
1263 } // if(size > isize) else ...
1265 } // if(nsize < bound)
1267 // no space in the block, go to check the next block
1273 tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1276 } // if(islocal) else ...
1277 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1278 // no more local mem, do not find suitable block
1281 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1284 if(foundsmem == 1) {
1285 // find suitable block
1286 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC)?
1287 (BAMBOO_SMEM_SIZE_L*tofindb):(BAMBOO_LARGE_SMEM_BOUND+
1288 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1290 // set bamboo_smemtbl
1291 for(i = tofindb; i <= totest; i++) {
1292 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1294 } else if(foundsmem == 2) {
1295 // no suitable block
1300 } // void * localmalloc_I(int, int, int *)
1302 void * globalmalloc_I(int coren,
1306 int tofindb = bamboo_free_block; //0;
1307 int totest = tofindb;
1308 int bound = BAMBOO_SMEM_SIZE_L;
1311 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1316 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1317 int nsize = bamboo_smemtbl[totest];
1318 bool isnext = false;
1320 bool tocheck = true;
1321 // have some space in the block
1322 if(totest == tofindb) {
1323 // the first partition
1324 size = bound - nsize;
1325 } else if(nsize == 0) {
1326 // an empty partition, can be appended
1329 // not an empty partition, can not be appended
1330 // the last continuous block is not big enough, start another block
1333 } // if(totest == tofindb) else if(nsize == 0) else ...
1336 // have enough space in the block, malloc
1339 } // if(size > isize)
1343 }// if(nsize < bound) else ...
1345 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1346 // no more local mem, do not find suitable block
1349 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1351 // start another block
1356 if(foundsmem == 1) {
1357 // find suitable block
1358 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC)?
1359 (BAMBOO_SMEM_SIZE_L*tofindb):(BAMBOO_LARGE_SMEM_BOUND+
1360 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1362 // set bamboo_smemtbl
1363 for(int i = tofindb; i <= totest; i++) {
1364 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1366 if(tofindb == bamboo_free_block) {
1367 bamboo_free_block = totest+1;
1369 } else if(foundsmem == 2) {
1370 // no suitable block
1376 } // void * globalmalloc_I(int, int, int *)
1377 #endif // #ifdef MULTICORE_GC
1379 // malloc from the shared memory
1380 void * smemalloc_I(int coren,
1385 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1387 // go through the bamboo_smemtbl for suitable partitions
1388 switch(bamboo_smem_mode) {
1390 mem = localmalloc_I(coren, isize, allocsize);
1395 // TODO not supported yet
1396 BAMBOO_EXIT(0xe001);
1401 // TODO not supported yet
1402 BAMBOO_EXIT(0xe002);
1407 mem = globalmalloc_I(coren, isize, allocsize);
1417 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size):(BAMBOO_SMEM_SIZE);
1418 mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1419 *allocsize = toallocate;
1422 // no enough shared global memory
1428 BAMBOO_DEBUGPRINT(0xa001);
1429 BAMBOO_EXIT(0xa001);
1433 } // void * smemalloc_I(int, int, int)
1435 INLINE int checkMsgLength_I(int size) {
1438 BAMBOO_DEBUGPRINT(0xcccc);
1441 int type = msgdata[msgdataindex];
1460 case GCSTARTCOMPACT:
1484 case REDIRECTGROUNT:
1486 case REDIRECTRELEASE:
1498 case GCFINISHCOMPACT:
1510 case TRANSOBJ: // nonfixed size
1516 msglength = msgdata[msgdataindex+1];
1524 BAMBOO_DEBUGPRINT_REG(type);
1527 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1529 BAMBOO_EXIT(0xd005);
1535 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1540 BAMBOO_DEBUGPRINT(0xffff);
1546 INLINE void processmsg_transobj_I() {
1548 struct transObjInfo * transObj = RUNMALLOC_I(sizeof(struct transObjInfo));
1552 BAMBOO_DEBUGPRINT(0xe880);
1555 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1557 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]/*[2]*/);
1559 BAMBOO_EXIT(0xa002);
1561 // store the object and its corresponding queue info, enqueue it later
1562 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
1564 transObj->length = (msglength - 3) / 2;
1565 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1566 for(k = 0; k < transObj->length; ++k) {
1567 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
1571 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1574 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
1578 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1582 // check if there is an existing duplicate item
1584 struct QueueItem * qitem = getHead(&objqueue);
1585 struct QueueItem * prev = NULL;
1586 while(qitem != NULL) {
1587 struct transObjInfo * tmpinfo =
1588 (struct transObjInfo *)(qitem->objectptr);
1589 if(tmpinfo->objptr == transObj->objptr) {
1590 // the same object, remove outdate one
1591 RUNFREE(tmpinfo->queues);
1593 removeItem(&objqueue, qitem);
1599 qitem = getHead(&objqueue);
1601 qitem = getNextQueueItem(prev);
1604 addNewItem_I(&objqueue, (void *)transObj);
1606 ++(self_numreceiveobjs);
1609 INLINE void processmsg_transtall_I() {
1610 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1611 // non startup core can not receive stall msg
1613 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]/*[1]*/);
1615 BAMBOO_EXIT(0xa003);
1617 int num_core = msgdata[msgdataindex]; //[1]
1619 if(num_core < NUMCORESACTIVE) {
1622 BAMBOO_DEBUGPRINT(0xe881);
1625 corestatus[num_core] = 0;
1626 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
1628 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
1633 #ifndef MULTICORE_GC
1634 INLINE void processmsg_lockrequest_I() {
1635 // check to see if there is a lock exist for the required obj
1636 // msgdata[1] -> lock type
1637 int locktype = msgdata[msgdataindex]; //[1];
1639 int data2 = msgdata[msgdataindex]; // obj pointer
1641 int data3 = msgdata[msgdataindex]; // lock
1643 int data4 = msgdata[msgdataindex]; // request core
1645 // -1: redirected, 0: approved, 1: denied
1646 int deny = processlockrequest(locktype, data3, data2, data4, data4, true);
1648 // this lock request is redirected
1651 // send response msg
1652 // for 32 bit machine, the size is always 4 words
1653 int tmp = deny==1?LOCKDENY:LOCKGROUNT;
1655 cache_msg_4(data4, tmp, locktype, data2, data3);
1657 send_msg_4(data4, tmp, locktype, data2, data3, true);
1662 INLINE void processmsg_lockgrount_I() {
1664 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1666 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]/*[2]*/);
1668 BAMBOO_EXIT(0xa004);
1670 int data2 = msgdata[msgdataindex];
1672 int data3 = msgdata[msgdataindex];
1674 if((lockobj == data2) && (lock2require == data3)) {
1677 BAMBOO_DEBUGPRINT(0xe882);
1686 // conflicts on lockresults
1688 BAMBOO_DEBUGPRINT_REG(data2);
1690 BAMBOO_EXIT(0xa005);
1694 INLINE void processmsg_lockdeny_I() {
1696 int data2 = msgdata[msgdataindex];
1698 int data3 = msgdata[msgdataindex];
1700 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1702 BAMBOO_DEBUGPRINT_REG(data2);
1704 BAMBOO_EXIT(0xa006);
1706 if((lockobj == data2) && (lock2require == data3)) {
1709 BAMBOO_DEBUGPRINT(0xe883);
1718 // conflicts on lockresults
1720 BAMBOO_DEBUGPRINT_REG(data2);
1722 BAMBOO_EXIT(0xa007);
1726 INLINE void processmsg_lockrelease_I() {
1727 int data1 = msgdata[msgdataindex];
1729 int data2 = msgdata[msgdataindex];
1731 // receive lock release msg
1732 processlockrelease(data1, data2, 0, false);
1735 INLINE void processmsg_redirectlock_I() {
1736 // check to see if there is a lock exist for the required obj
1737 int data1 = msgdata[msgdataindex];
1738 MSG_INDEXINC_I(); //msgdata[1]; // lock type
1739 int data2 = msgdata[msgdataindex];
1740 MSG_INDEXINC_I();//msgdata[2]; // obj pointer
1741 int data3 = msgdata[msgdataindex];
1742 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
1743 int data4 = msgdata[msgdataindex];
1744 MSG_INDEXINC_I(); //msgdata[4]; // root request core
1745 int data5 = msgdata[msgdataindex];
1746 MSG_INDEXINC_I(); //msgdata[5]; // request core
1747 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
1749 // this lock request is redirected
1752 // send response msg
1753 // for 32 bit machine, the size is always 4 words
1755 cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1756 data1, data2, data3);
1758 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1759 data1, data2, data3, true);
1764 INLINE void processmsg_redirectgrount_I() {
1766 int data2 = msgdata[msgdataindex];
1768 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1770 BAMBOO_DEBUGPRINT_REG(data2);
1772 BAMBOO_EXIT(0xa00a);
1774 if(lockobj == data2) {
1777 BAMBOO_DEBUGPRINT(0xe891);
1780 int data3 = msgdata[msgdataindex];
1784 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
1789 // conflicts on lockresults
1791 BAMBOO_DEBUGPRINT_REG(data2);
1793 BAMBOO_EXIT(0xa00b);
1797 INLINE void processmsg_redirectdeny_I() {
1799 int data2 = msgdata[msgdataindex];
1801 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1803 BAMBOO_DEBUGPRINT_REG(data2);
1805 BAMBOO_EXIT(0xa00c);
1807 if(lockobj == data2) {
1810 BAMBOO_DEBUGPRINT(0xe892);
1819 // conflicts on lockresults
1821 BAMBOO_DEBUGPRINT_REG(data2);
1823 BAMBOO_EXIT(0xa00d);
1827 INLINE void processmsg_redirectrelease_I() {
1828 int data1 = msgdata[msgdataindex];
1830 int data2 = msgdata[msgdataindex];
1832 int data3 = msgdata[msgdataindex];
1834 processlockrelease(data1, data2, data3, true);
1836 #endif // #ifndef MULTICORE_GC
1839 INLINE void processmsg_profileoutput_I() {
1840 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1841 // startup core can not receive profile output finish msg
1842 BAMBOO_EXIT(0xa008);
1846 BAMBOO_DEBUGPRINT(0xe885);
1850 totalexetime = msgdata[msgdataindex]; //[1]
1852 outputProfileData();
1854 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1856 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
1860 INLINE void processmsg_profilefinish_I() {
1861 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1862 // non startup core can not receive profile output finish msg
1864 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex/*1*/]);
1866 BAMBOO_EXIT(0xa009);
1870 BAMBOO_DEBUGPRINT(0xe886);
1873 int data1 = msgdata[msgdataindex];
1875 profilestatus[data1] = 0;
1877 #endif // #ifdef PROFILE
1879 INLINE void processmsg_statusconfirm_I() {
1880 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1881 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1882 // wrong core to receive such msg
1883 BAMBOO_EXIT(0xa00e);
1885 // send response msg
1888 BAMBOO_DEBUGPRINT(0xe887);
1892 cache_msg_5(STARTUPCORE, STATUSREPORT,
1893 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1894 self_numsendobjs, self_numreceiveobjs);
1896 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
1897 BAMBOO_NUM_OF_CORE, self_numsendobjs,
1898 self_numreceiveobjs, true);
1903 INLINE void processmsg_statusreport_I() {
1904 int data1 = msgdata[msgdataindex];
1906 int data2 = msgdata[msgdataindex];
1908 int data3 = msgdata[msgdataindex];
1910 int data4 = msgdata[msgdataindex];
1912 // receive a status confirm info
1913 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1914 // wrong core to receive such msg
1916 BAMBOO_DEBUGPRINT_REG(data2);
1918 BAMBOO_EXIT(0xa00f);
1922 BAMBOO_DEBUGPRINT(0xe888);
1928 corestatus[data2] = data1;
1929 numsendobjs[data2] = data3;
1930 numreceiveobjs[data2] = data4;
1934 INLINE void processmsg_terminate_I() {
1937 BAMBOO_DEBUGPRINT(0xe889);
1944 INLINE void processmsg_memrequest_I() {
1945 int data1 = msgdata[msgdataindex];
1947 int data2 = msgdata[msgdataindex];
1949 // receive a shared memory request msg
1950 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1951 // wrong core to receive such msg
1953 BAMBOO_DEBUGPRINT_REG(data2);
1955 BAMBOO_EXIT(0xa010);
1959 BAMBOO_DEBUGPRINT(0xe88a);
1966 // is currently doing gc, dump this msg
1967 if(INITPHASE == gcphase) {
1968 // if still in the initphase of gc, send a startinit msg again
1970 cache_msg_1(data2, GCSTARTINIT);
1972 send_msg_1(data2, GCSTARTINIT, true);
1977 mem = smemalloc_I(data2, data1, &allocsize);
1979 // send the start_va to request core
1981 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
1983 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
1985 } // if mem == NULL, the gcflag of the startup core has been set
1986 // and the gc should be started later, then a GCSTARTINIT msg
1987 // will be sent to the requesting core to notice it to start gc
1988 // and try malloc again
1995 INLINE void processmsg_memresponse_I() {
1996 int data1 = msgdata[msgdataindex];
1998 int data2 = msgdata[msgdataindex];
2000 // receive a shared memory response msg
2003 BAMBOO_DEBUGPRINT(0xe88b);
2007 // if is currently doing gc, dump this msg
2011 bamboo_smem_size = 0;
2015 // fill header to store the size of this mem block
2016 memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2017 (*((int*)data1)) = data2;
2018 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2019 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2021 bamboo_smem_size = data2;
2022 bamboo_cur_msp =(void*)(data1);
2032 INLINE void processmsg_gcstartinit_I() {
2034 gcphase = INITPHASE;
2036 // is waiting for response of mem request
2037 // let it return NULL and start gc
2038 bamboo_smem_size = 0;
2039 bamboo_cur_msp = NULL;
2044 INLINE void processmsg_gcstart_I() {
2047 BAMBOO_DEBUGPRINT(0xe88c);
2051 gcphase = MARKPHASE;
2054 INLINE void processmsg_gcstartcompact_I() {
2055 gcblock2fill = msgdata[msgdataindex];
2056 MSG_INDEXINC_I(); //msgdata[1];
2057 gcphase = COMPACTPHASE;
2060 INLINE void processmsg_gcstartflush_I() {
2061 gcphase = FLUSHPHASE;
2064 INLINE void processmsg_gcfinishinit_I() {
2065 int data1 = msgdata[msgdataindex];
2067 // received a init phase finish msg
2068 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2069 // non startup core can not receive this msg
2071 BAMBOO_DEBUGPRINT_REG(data1);
2073 BAMBOO_EXIT(0xb001);
2076 BAMBOO_DEBUGPRINT(0xe88c);
2077 BAMBOO_DEBUGPRINT_REG(data1);
2079 // All cores should do init GC
2080 if(data1 < NUMCORESACTIVE) {
2081 gccorestatus[data1] = 0;
2085 INLINE void processmsg_gcfinishmark_I() {
2086 int data1 = msgdata[msgdataindex];
2088 int data2 = msgdata[msgdataindex];
2090 int data3 = msgdata[msgdataindex];
2092 // received a mark phase finish msg
2093 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2094 // non startup core can not receive this msg
2096 BAMBOO_DEBUGPRINT_REG(data1);
2098 BAMBOO_EXIT(0xb002);
2100 // all cores should do mark
2101 if(data1 < NUMCORESACTIVE) {
2102 gccorestatus[data1] = 0;
2103 gcnumsendobjs[data1] = data2;
2104 gcnumreceiveobjs[data1] = data3;
2108 INLINE void processmsg_gcfinishcompact_I() {
2109 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2110 // non startup core can not receive this msg
2113 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]/*[1]*/);
2115 BAMBOO_EXIT(0xb003);
2117 int cnum = msgdata[msgdataindex];
2118 MSG_INDEXINC_I(); //msgdata[1];
2119 int filledblocks = msgdata[msgdataindex];
2120 MSG_INDEXINC_I(); //msgdata[2];
2121 int heaptop = msgdata[msgdataindex];
2122 MSG_INDEXINC_I(); //msgdata[3];
2123 int data4 = msgdata[msgdataindex];
2124 MSG_INDEXINC_I(); //msgdata[4];
2125 // only gc cores need to do compact
2126 if(cnum < NUMCORES4GC) {
2127 if(COMPACTPHASE == gcphase) {
2128 gcfilledblocks[cnum] = filledblocks;
2129 gcloads[cnum] = heaptop;
2136 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2138 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2140 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2144 gccorestatus[cnum] = 0;
2146 } // if(cnum < NUMCORES4GC)
2149 INLINE void processmsg_gcfinishflush_I() {
2150 int data1 = msgdata[msgdataindex];
2152 // received a flush phase finish msg
2153 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2154 // non startup core can not receive this msg
2157 BAMBOO_DEBUGPRINT_REG(data1);
2159 BAMBOO_EXIT(0xb004);
2161 // all cores should do flush
2162 if(data1 < NUMCORESACTIVE) {
2163 gccorestatus[data1] = 0;
2167 INLINE void processmsg_gcmarkconfirm_I() {
2168 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2169 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2170 // wrong core to receive such msg
2171 BAMBOO_EXIT(0xb005);
2173 // send response msg
2175 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2176 gcbusystatus, gcself_numsendobjs,
2177 gcself_numreceiveobjs);
2179 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2180 gcbusystatus, gcself_numsendobjs,
2181 gcself_numreceiveobjs, true);
2186 INLINE void processmsg_gcmarkreport_I() {
2187 int data1 = msgdata[msgdataindex];
2189 int data2 = msgdata[msgdataindex];
2191 int data3 = msgdata[msgdataindex];
2193 int data4 = msgdata[msgdataindex];
2195 // received a marked phase finish confirm response msg
2196 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2197 // wrong core to receive such msg
2199 BAMBOO_DEBUGPRINT_REG(data2);
2201 BAMBOO_EXIT(0xb006);
2206 gccorestatus[data1] = data2;
2207 gcnumsendobjs[data1] = data3;
2208 gcnumreceiveobjs[data1] = data4;
2212 INLINE void processmsg_gcmarkedobj_I() {
2213 int data1 = msgdata[msgdataindex];
2215 // received a markedObj msg
2216 if(((int *)data1)[6] == INIT) {
2217 // this is the first time that this object is discovered,
2218 // set the flag as DISCOVERED
2219 ((int *)data1)[6] = DISCOVERED;
2220 gc_enqueue_I(data1);
2222 gcself_numreceiveobjs++;
2223 gcbusystatus = true;
2226 INLINE void processmsg_gcmovestart_I() {
2228 gcdstcore = msgdata[msgdataindex];
2229 MSG_INDEXINC_I(); //msgdata[1];
2230 gcmovestartaddr = msgdata[msgdataindex];
2231 MSG_INDEXINC_I(); //msgdata[2];
2232 gcblock2fill = msgdata[msgdataindex];
2233 MSG_INDEXINC_I(); //msgdata[3];
2236 INLINE void processmsg_gcmaprequest_I() {
2238 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2240 void * dstptr = NULL;
2241 int data1 = msgdata[msgdataindex];
2243 //dstptr = mgchashSearch(msgdata[1]);
2245 unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2247 RuntimeHashget(gcpointertbl, data1, &dstptr);
2249 flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2251 int data2 = msgdata[msgdataindex];
2253 //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2255 unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2257 if(NULL == dstptr) {
2258 // no such pointer in this core, something is wrong
2260 BAMBOO_DEBUGPRINT_REG(data1);
2261 BAMBOO_DEBUGPRINT_REG(data2);
2263 BAMBOO_EXIT(0xb007);
2264 //assume that the object was not moved, use the original address
2265 /*if(isMsgSending) {
2266 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2268 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1], true);
2271 // send back the mapping info
2273 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2275 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2279 flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2280 //num_mapinforequest_i++;
2284 INLINE void processmsg_gcmapinfo_I() {
2286 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2288 int data1 = msgdata[msgdataindex];
2290 if(data1 != gcobj2map) {
2291 // obj not matched, something is wrong
2293 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2294 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2296 BAMBOO_EXIT(0xb008);
2298 gcmappedobj = msgdata[msgdataindex]; // [2]
2300 //mgchashReplace_I(msgdata[1], msgdata[2]);
2301 //mgchashInsert_I(gcobj2map, gcmappedobj);
2302 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2303 //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2307 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2311 INLINE void processmsg_gclobjinfo_I() {
2314 int data1 = msgdata[msgdataindex];
2316 int data2 = msgdata[msgdataindex];
2318 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2320 BAMBOO_DEBUGPRINT_REG(data2);
2322 BAMBOO_EXIT(0xb009);
2324 // store the mark result info
2326 gcloads[cnum] = msgdata[msgdataindex];
2327 MSG_INDEXINC_I(); // msgdata[3];
2328 int data4 = msgdata[msgdataindex];
2330 if(gcheaptop < data4) {
2333 // large obj info here
2334 for(int k = 5; k < data1;) {
2335 int lobj = msgdata[msgdataindex];
2336 MSG_INDEXINC_I(); //msgdata[k++];
2337 int length = msgdata[msgdataindex];
2338 MSG_INDEXINC_I(); //msgdata[k++];
2339 gc_lobjenqueue_I(lobj, length, cnum);
2341 } // for(int k = 5; k < msgdata[1];)
2344 INLINE void processmsg_gclobjmapping_I() {
2345 int data1 = msgdata[msgdataindex];
2347 int data2 = msgdata[msgdataindex];
2349 //mgchashInsert_I(msgdata[1], msgdata[2]);
2350 RuntimeHashadd_I(gcpointertbl, data1, data2);
2351 //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2353 #endif // #ifdef MULTICORE_GC
2355 // receive object transferred from other cores
2356 // or the terminate message from other cores
2357 // Should be invoked in critical sections!!
2358 // NOTICE: following format is for threadsimulate version only
2359 // RAW version please see previous description
2360 // format: type + object
2361 // type: -1--stall msg
2363 // return value: 0--received an object
2364 // 1--received nothing
2365 // 2--received a Stall Msg
2366 // 3--received a lock Msg
2367 // RAW version: -1 -- received nothing
2368 // otherwise -- received msg type
2369 int receiveObject() {
2371 // get the incoming msgs
2372 if(receiveMsg() == -1) {
2376 // processing received msgs
2378 MSG_REMAINSIZE_I(&size);
2379 if(checkMsgLength_I(size) == -1) {
2381 // have new coming msg
2382 if(BAMBOO_MSG_AVAIL() != 0) {
2389 if(msglength <= size) {
2390 // have some whole msg
2391 //if(msgdataindex == msglength) {
2392 // received a whole msg
2394 type = msgdata[msgdataindex]; //[0]
2396 msgdatafull = false;
2398 //tprintf("msg type: %x\n", type);
2401 // receive a object transfer msg
2402 processmsg_transobj_I();
2407 // receive a stall msg
2408 processmsg_transtall_I();
2412 // GC version have no lock msgs
2413 #ifndef MULTICORE_GC
2415 // receive lock request msg, handle it right now
2416 processmsg_lockrequest_I();
2418 } // case LOCKREQUEST
2421 // receive lock grount msg
2422 processmsg_lockgrount_I();
2424 } // case LOCKGROUNT
2427 // receive lock deny msg
2428 processmsg_lockdeny_I();
2433 processmsg_lockrelease_I();
2435 } // case LOCKRELEASE
2436 #endif // #ifndef MULTICORE_GC
2439 case PROFILEOUTPUT: {
2440 // receive an output profile data request msg
2441 processmsg_profileoutput_I();
2443 } // case PROFILEOUTPUT
2445 case PROFILEFINISH: {
2446 // receive a profile output finish msg
2447 processmsg_profilefinish_I();
2449 } // case PROFILEFINISH
2450 #endif // #ifdef PROFILE
2452 // GC version has no lock msgs
2453 #ifndef MULTICORE_GC
2454 case REDIRECTLOCK: {
2455 // receive a redirect lock request msg, handle it right now
2456 processmsg_redirectlock_I();
2458 } // case REDIRECTLOCK
2460 case REDIRECTGROUNT: {
2461 // receive a lock grant msg with redirect info
2462 processmsg_redirectgrount_I();
2464 } // case REDIRECTGROUNT
2466 case REDIRECTDENY: {
2467 // receive a lock deny msg with redirect info
2468 processmsg_redirectdeny_I();
2470 } // case REDIRECTDENY
2472 case REDIRECTRELEASE: {
2473 // receive a lock release msg with redirect info
2474 processmsg_redirectrelease_I();
2476 } // case REDIRECTRELEASE
2477 #endif // #ifndef MULTICORE_GC
2479 case STATUSCONFIRM: {
2480 // receive a status confirm info
2481 processmsg_statusconfirm_I();
2483 } // case STATUSCONFIRM
2485 case STATUSREPORT: {
2486 processmsg_statusreport_I();
2488 } // case STATUSREPORT
2491 // receive a terminate msg
2492 processmsg_terminate_I();
2497 processmsg_memrequest_I();
2499 } // case MEMREQUEST
2502 processmsg_memresponse_I();
2504 } // case MEMRESPONSE
2509 processmsg_gcstartinit_I();
2511 } // case GCSTARTINIT
2514 // receive a start GC msg
2515 processmsg_gcstart_I();
2519 case GCSTARTCOMPACT: {
2520 // a compact phase start msg
2521 processmsg_gcstartcompact_I();
2523 } // case GCSTARTCOMPACT
2525 case GCSTARTFLUSH: {
2526 // received a flush phase start msg
2527 processmsg_gcstartflush_I();
2529 } // case GCSTARTFLUSH
2531 case GCFINISHINIT: {
2532 processmsg_gcfinishinit_I();
2534 } // case GCFINISHINIT
2536 case GCFINISHMARK: {
2537 processmsg_gcfinishmark_I();
2539 } // case GCFINISHMARK
2541 case GCFINISHCOMPACT: {
2542 // received a compact phase finish msg
2543 processmsg_gcfinishcompact_I();
2545 } // case GCFINISHCOMPACT
2547 case GCFINISHFLUSH: {
2548 processmsg_gcfinishflush_I();
2550 } // case GCFINISHFLUSH
2553 // received a GC finish msg
2554 gcphase = FINISHPHASE;
2558 case GCMARKCONFIRM: {
2559 // received a marked phase finish confirm request msg
2560 // all cores should do mark
2561 processmsg_gcmarkconfirm_I();
2563 } // case GCMARKCONFIRM
2565 case GCMARKREPORT: {
2566 processmsg_gcmarkreport_I();
2568 } // case GCMARKREPORT
2571 processmsg_gcmarkedobj_I();
2573 } // case GCMARKEDOBJ
2576 // received a start moving objs msg
2577 processmsg_gcmovestart_I();
2579 } // case GCMOVESTART
2581 case GCMAPREQUEST: {
2582 // received a mapping info request msg
2583 processmsg_gcmaprequest_I();
2585 } // case GCMAPREQUEST
2588 // received a mapping info response msg
2589 processmsg_gcmapinfo_I();
2593 case GCLOBJREQUEST: {
2594 // received a large objs info request msg
2595 transferMarkResults_I();
2597 } // case GCLOBJREQUEST
2600 // received a large objs info response msg
2601 processmsg_gclobjinfo_I();
2603 } // case GCLOBJINFO
2605 case GCLOBJMAPPING: {
2606 // received a large obj mapping info msg
2607 processmsg_gclobjmapping_I();
2609 } // case GCLOBJMAPPING
2611 #endif // #ifdef MULTICORE_GC
2616 //memset(msgdata, '\0', sizeof(int) * msgdataindex);
2618 msglength = BAMBOO_MSG_BUF_LENGTH;
2620 //printf("++ msg: %x \n", type);
2621 if(msgdataindex != msgdatalast) {
2622 // still have available msg
2627 BAMBOO_DEBUGPRINT(0xe88d);
2631 // have new coming msg
2632 if(BAMBOO_MSG_AVAIL() != 0) {
2646 BAMBOO_DEBUGPRINT(0xe88e);
2650 /* if(isInterrupt) {
2658 int enqueuetasks(struct parameterwrapper *parameter,
2659 struct parameterwrapper *prevptr,
2660 struct ___Object___ *ptr,
2662 int numenterflags) {
2663 void * taskpointerarray[MAXTASKPARAMS];
2665 //int numparams=parameter->task->numParameters;
2666 int numiterators=parameter->task->numTotal-1;
2669 struct taskdescriptor * task=parameter->task;
2671 //this add the object to parameterwrapper
2672 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
2673 numenterflags, enterflags==NULL);
2675 /* Add enqueued object to parameter vector */
2676 taskpointerarray[parameter->slot]=ptr;
2678 /* Reset iterators */
2679 for(j=0; j<numiterators; j++) {
2680 toiReset(¶meter->iterators[j]);
2683 /* Find initial state */
2684 for(j=0; j<numiterators; j++) {
2686 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2687 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2689 /* Need to backtrack */
2690 toiReset(¶meter->iterators[j]);
2694 /* Nothing to enqueue */
2700 /* Enqueue current state */
2702 struct taskparamdescriptor *tpd=
2703 RUNMALLOC(sizeof(struct taskparamdescriptor));
2705 tpd->numParameters=numiterators+1;
2706 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2708 for(j=0; j<=numiterators; j++) {
2709 //store the actual parameters
2710 tpd->parameterArray[j]=taskpointerarray[j];
2713 if ((/*!gencontains(failedtasks, tpd)&&*/
2714 !gencontains(activetasks,tpd))) {
2715 genputtable(activetasks, tpd, tpd);
2717 RUNFREE(tpd->parameterArray);
2721 /* This loop iterates to the next parameter combination */
2722 if (numiterators==0)
2725 for(j=numiterators-1; j<numiterators; j++) {
2727 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2728 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2730 /* Need to backtrack */
2731 toiReset(¶meter->iterators[j]);
2735 /* Nothing more to enqueue */
2743 int enqueuetasks_I(struct parameterwrapper *parameter,
2744 struct parameterwrapper *prevptr,
2745 struct ___Object___ *ptr,
2747 int numenterflags) {
2748 void * taskpointerarray[MAXTASKPARAMS];
2750 //int numparams=parameter->task->numParameters;
2751 int numiterators=parameter->task->numTotal-1;
2756 struct taskdescriptor * task=parameter->task;
2758 //this add the object to parameterwrapper
2759 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2760 numenterflags, enterflags==NULL);
2762 /* Add enqueued object to parameter vector */
2763 taskpointerarray[parameter->slot]=ptr;
2765 /* Reset iterators */
2766 for(j=0; j<numiterators; j++) {
2767 toiReset(¶meter->iterators[j]);
2770 /* Find initial state */
2771 for(j=0; j<numiterators; j++) {
2773 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2774 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2776 /* Need to backtrack */
2777 toiReset(¶meter->iterators[j]);
2781 /* Nothing to enqueue */
2787 /* Enqueue current state */
2789 struct taskparamdescriptor *tpd=
2790 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2792 tpd->numParameters=numiterators+1;
2793 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2795 for(j=0; j<=numiterators; j++) {
2796 //store the actual parameters
2797 tpd->parameterArray[j]=taskpointerarray[j];
2800 if ((/*!gencontains(failedtasks, tpd)&&*/
2801 !gencontains(activetasks,tpd))) {
2802 genputtable_I(activetasks, tpd, tpd);
2804 RUNFREE(tpd->parameterArray);
2808 /* This loop iterates to the next parameter combination */
2809 if (numiterators==0)
2812 for(j=numiterators-1; j<numiterators; j++) {
2814 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2815 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2817 /* Need to backtrack */
2818 toiReset(¶meter->iterators[j]);
2822 /* Nothing more to enqueue */
2836 int containstag(struct ___Object___ *ptr,
2837 struct ___TagDescriptor___ *tag);
2839 #ifndef MULTICORE_GC
2840 void releasewritelock_r(void * lock, void * redirectlock) {
2842 int reallock = (int)lock;
2843 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2846 BAMBOO_DEBUGPRINT(0xe671);
2847 BAMBOO_DEBUGPRINT_REG((int)lock);
2848 BAMBOO_DEBUGPRINT_REG(reallock);
2849 BAMBOO_DEBUGPRINT_REG(targetcore);
2852 if(targetcore == BAMBOO_NUM_OF_CORE) {
2853 BAMBOO_START_CRITICAL_SECTION_LOCK();
2855 BAMBOO_DEBUGPRINT(0xf001);
2857 // reside on this core
2858 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2859 // no locks for this object, something is wrong
2860 BAMBOO_EXIT(0xa011);
2863 struct LockValue * lockvalue = NULL;
2865 BAMBOO_DEBUGPRINT(0xe672);
2867 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2868 lockvalue = (struct LockValue *)rwlock_obj;
2870 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2873 lockvalue->redirectlock = (int)redirectlock;
2875 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2878 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2880 BAMBOO_DEBUGPRINT(0xf000);
2884 // send lock release with redirect info msg
2885 // for 32 bit machine, the size is always 4 words
2886 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
2887 (int)redirectlock, false);
2892 void executetasks() {
2893 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2896 struct ___Object___ * tmpparam = NULL;
2897 struct parameterdescriptor * pd=NULL;
2898 struct parameterwrapper *pw=NULL;
2908 while(hashsize(activetasks)>0) {
2913 BAMBOO_DEBUGPRINT(0xe990);
2916 /* See if there are any active tasks */
2917 //if (hashsize(activetasks)>0) {
2920 #ifdef ACCURATEPROFILE
2921 profileTaskStart("tpd checking");
2925 //clock1 = BAMBOO_GET_EXE_TIME();
2928 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2929 genfreekey(activetasks, currtpd);
2931 numparams=currtpd->task->numParameters;
2932 numtotal=currtpd->task->numTotal;
2934 // clear the lockRedirectTbl
2935 // (TODO, this table should be empty after all locks are released)
2937 /*for(j = 0; j < MAXTASKPARAMS; j++) {
2938 runtime_locks[j].redirectlock = 0;
2939 runtime_locks[j].value = 0;
2941 // get all required locks
2942 runtime_locklen = 0;
2943 // check which locks are needed
2944 for(i = 0; i < numparams; i++) {
2945 void * param = currtpd->parameterArray[i];
2949 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2951 taskpointerarray[i+OFFSET]=param;
2954 if(((struct ___Object___ *)param)->lock == NULL) {
2955 tmplock = (int)param;
2957 tmplock = (int)(((struct ___Object___ *)param)->lock);
2959 // insert into the locks array
2960 for(j = 0; j < runtime_locklen; j++) {
2961 if(runtime_locks[j].value == tmplock) {
2964 } else if(runtime_locks[j].value > tmplock) {
2969 int h = runtime_locklen;
2971 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
2972 runtime_locks[h].value = runtime_locks[h-1].value;
2974 runtime_locks[j].value = tmplock;
2975 runtime_locks[j].redirectlock = (int)param;
2978 } // line 2713: for(i = 0; i < numparams; i++)
2979 // grab these required locks
2981 BAMBOO_DEBUGPRINT(0xe991);
2984 //clock2 = BAMBOO_GET_EXE_TIME();
2986 for(i = 0; i < runtime_locklen; i++) {
2987 int * lock = (int *)(runtime_locks[i].redirectlock);
2989 // require locks for this parameter if it is not a startup object
2991 BAMBOO_DEBUGPRINT_REG((int)lock);
2992 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
2995 BAMBOO_START_CRITICAL_SECTION();
2997 BAMBOO_DEBUGPRINT(0xf001);
3000 //isInterrupt = false;
3003 BAMBOO_WAITING_FOR_LOCK();
3007 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
3011 grount = lockresult;
3021 //isInterrupt = true;
3023 BAMBOO_CLOSE_CRITICAL_SECTION();
3025 BAMBOO_DEBUGPRINT(0xf000);
3030 BAMBOO_DEBUGPRINT(0xe992);
3031 BAMBOO_DEBUGPRINT_REG(lock);
3033 // check if has the lock already
3034 // can not get the lock, try later
3035 // release all grabbed locks for previous parameters
3036 for(j = 0; j < i; ++j) {
3037 lock = (int*)(runtime_locks[j].redirectlock);
3038 releasewritelock(lock);
3040 genputtable(activetasks, currtpd, currtpd);
3041 if(hashsize(activetasks) == 1) {
3042 // only one task right now, wait a little while before next try
3048 #ifdef ACCURATEPROFILE
3049 // fail, set the end of the checkTaskInfo
3056 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3059 clock3 = BAMBOO_GET_EXE_TIME();
3060 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3063 BAMBOO_DEBUGPRINT(0xe993);
3065 /* Make sure that the parameters are still in the queues */
3066 for(i=0; i<numparams; i++) {
3067 void * parameter=currtpd->parameterArray[i];
3071 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3072 classsize[((struct ___Object___ *)parameter)->type]);
3074 tmpparam = (struct ___Object___ *)parameter;
3075 pd=currtpd->task->descriptorarray[i];
3076 pw=(struct parameterwrapper *) pd->queue;
3077 /* Check that object is still in queue */
3079 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3081 BAMBOO_DEBUGPRINT(0xe994);
3082 BAMBOO_DEBUGPRINT_REG(parameter);
3084 // release grabbed locks
3085 for(j = 0; j < runtime_locklen; ++j) {
3086 int * lock = (int *)(runtime_locks[j].redirectlock);
3087 releasewritelock(lock);
3089 RUNFREE(currtpd->parameterArray);
3095 /* Check if the object's flags still meets requirements */
3099 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3100 andmask=pw->intarray[tmpi*2];
3101 checkmask=pw->intarray[tmpi*2+1];
3102 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3108 // flags are never suitable
3109 // remove this obj from the queue
3111 int UNUSED, UNUSED2;
3114 BAMBOO_DEBUGPRINT(0xe995);
3115 BAMBOO_DEBUGPRINT_REG(parameter);
3117 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3118 (int *) &enterflags, &UNUSED, &UNUSED2);
3119 ObjectHashremove(pw->objectset, (int)parameter);
3120 if (enterflags!=NULL)
3121 RUNFREE(enterflags);
3122 // release grabbed locks
3123 for(j = 0; j < runtime_locklen; ++j) {
3124 int * lock = (int *)(runtime_locks[j].redirectlock);
3125 releasewritelock(lock);
3127 RUNFREE(currtpd->parameterArray);
3131 #ifdef ACCURATEPROFILE
3132 // fail, set the end of the checkTaskInfo
3137 } // line 2878: if (!ismet)
3141 /* Check that object still has necessary tags */
3142 for(j=0; j<pd->numbertags; j++) {
3143 int slotid=pd->tagarray[2*j]+numparams;
3144 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3145 if (!containstag(parameter, tagd)) {
3147 BAMBOO_DEBUGPRINT(0xe996);
3150 // release grabbed locks
3152 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3153 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3154 releasewritelock(lock);
3157 RUNFREE(currtpd->parameterArray);
3161 } // line2911: if (!containstag(parameter, tagd))
3162 } // line 2808: for(j=0; j<pd->numbertags; j++)
3164 taskpointerarray[i+OFFSET]=parameter;
3165 } // line 2824: for(i=0; i<numparams; i++)
3167 for(; i<numtotal; i++) {
3168 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3173 /* Actually call task */
3175 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3176 taskpointerarray[1]=NULL;
3179 #ifdef ACCURATEPROFILE
3180 // check finish, set the end of the checkTaskInfo
3183 profileTaskStart(currtpd->task->name);
3187 //clock4 = BAMBOO_GET_EXE_TIME();
3188 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3191 BAMBOO_DEBUGPRINT(0xe997);
3193 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
3196 //clock5 = BAMBOO_GET_EXE_TIME();
3197 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3200 #ifdef ACCURATEPROFILE
3201 // task finish, set the end of the checkTaskInfo
3203 // new a PostTaskInfo for the post-task execution
3204 profileTaskStart("post task execution");
3208 BAMBOO_DEBUGPRINT(0xe998);
3209 BAMBOO_DEBUGPRINT_REG(islock);
3214 BAMBOO_DEBUGPRINT(0xe999);
3216 for(i = 0; i < runtime_locklen; ++i) {
3217 void * ptr = (void *)(runtime_locks[i].redirectlock);
3218 int * lock = (int *)(runtime_locks[i].value);
3220 BAMBOO_DEBUGPRINT_REG((int)ptr);
3221 BAMBOO_DEBUGPRINT_REG((int)lock);
3222 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3224 #ifndef MULTICORE_GC
3225 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3227 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3228 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3229 releasewritelock_r(lock, (int *)redirectlock);
3234 releasewritelock(ptr);
3237 } // line 3015: if(islock)
3240 //clock6 = BAMBOO_GET_EXE_TIME();
3241 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3244 // post task execution finish, set the end of the postTaskInfo
3248 // Free up task parameter descriptor
3249 RUNFREE(currtpd->parameterArray);
3253 BAMBOO_DEBUGPRINT(0xe99a);
3256 //clock7 = BAMBOO_GET_EXE_TIME();
3257 //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));
3260 //} // if (hashsize(activetasks)>0)
3261 } // while(hashsize(activetasks)>0)
3263 BAMBOO_DEBUGPRINT(0xe99b);
3267 /* This function processes an objects tags */
3268 void processtags(struct parameterdescriptor *pd,
3270 struct parameterwrapper *parameter,
3271 int * iteratorcount,
3276 for(i=0; i<pd->numbertags; i++) {
3277 int slotid=pd->tagarray[2*i];
3278 int tagid=pd->tagarray[2*i+1];
3280 if (statusarray[slotid+numparams]==0) {
3281 parameter->iterators[*iteratorcount].istag=1;
3282 parameter->iterators[*iteratorcount].tagid=tagid;
3283 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3284 parameter->iterators[*iteratorcount].tagobjectslot=index;
3285 statusarray[slotid+numparams]=1;
3292 void processobject(struct parameterwrapper *parameter,
3294 struct parameterdescriptor *pd,
3300 struct ObjectHash * objectset=
3301 ((struct parameterwrapper *)pd->queue)->objectset;
3303 parameter->iterators[*iteratorcount].istag=0;
3304 parameter->iterators[*iteratorcount].slot=index;
3305 parameter->iterators[*iteratorcount].objectset=objectset;
3306 statusarray[index]=1;
3308 for(i=0; i<pd->numbertags; i++) {
3309 int slotid=pd->tagarray[2*i];
3310 //int tagid=pd->tagarray[2*i+1];
3311 if (statusarray[slotid+numparams]!=0) {
3312 /* This tag has already been enqueued, use it to narrow search */
3313 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3318 parameter->iterators[*iteratorcount].numtags=tagcount;
3323 /* This function builds the iterators for a task & parameter */
3325 void builditerators(struct taskdescriptor * task,
3327 struct parameterwrapper * parameter) {
3328 int statusarray[MAXTASKPARAMS];
3330 int numparams=task->numParameters;
3331 int iteratorcount=0;
3332 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3334 statusarray[index]=1; /* Initial parameter */
3335 /* Process tags for initial iterator */
3337 processtags(task->descriptorarray[index], index, parameter,
3338 &iteratorcount, statusarray, numparams);
3342 /* Check for objects with existing tags */
3343 for(i=0; i<numparams; i++) {
3344 if (statusarray[i]==0) {
3345 struct parameterdescriptor *pd=task->descriptorarray[i];
3347 for(j=0; j<pd->numbertags; j++) {
3348 int slotid=pd->tagarray[2*j];
3349 if(statusarray[slotid+numparams]!=0) {
3350 processobject(parameter, i, pd, &iteratorcount, statusarray,
3352 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3359 /* Next do objects w/ unbound tags*/
3361 for(i=0; i<numparams; i++) {
3362 if (statusarray[i]==0) {
3363 struct parameterdescriptor *pd=task->descriptorarray[i];
3364 if (pd->numbertags>0) {
3365 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3366 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3372 /* Nothing with a tag enqueued */
3374 for(i=0; i<numparams; i++) {
3375 if (statusarray[i]==0) {
3376 struct parameterdescriptor *pd=task->descriptorarray[i];
3377 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3378 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3391 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3394 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3395 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3397 printf("%s\n", task->name);
3399 for(j=0; j<task->numParameters; j++) {
3400 struct parameterdescriptor *param=task->descriptorarray[j];
3401 struct parameterwrapper *parameter=param->queue;
3402 struct ObjectHash * set=parameter->objectset;
3403 struct ObjectIterator objit;
3405 printf(" Parameter %d\n", j);
3407 ObjectHashiterator(set, &objit);
3408 while(ObjhasNext(&objit)) {
3409 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3410 struct ___Object___ * tagptr=obj->___tags___;
3411 int nonfailed=Objdata4(&objit);
3412 int numflags=Objdata3(&objit);
3413 int flags=Objdata2(&objit);
3416 printf(" Contains %lx\n", obj);
3417 printf(" flag=%d\n", obj->flag);
3420 } else if (tagptr->type==TAGTYPE) {
3422 printf(" tag=%lx\n",tagptr);
3428 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3429 for(; tagindex<ao->___cachedCode___; tagindex++) {
3431 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3444 /* This function processes the task information to create queues for
3445 each parameter type. */
3447 void processtasks() {
3449 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3452 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3453 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3456 /* Build objectsets */
3457 for(j=0; j<task->numParameters; j++) {
3458 struct parameterdescriptor *param=task->descriptorarray[j];
3459 struct parameterwrapper *parameter=param->queue;
3460 parameter->objectset=allocateObjectHash(10);
3461 parameter->task=task;
3464 /* Build iterators for parameters */
3465 for(j=0; j<task->numParameters; j++) {
3466 struct parameterdescriptor *param=task->descriptorarray[j];
3467 struct parameterwrapper *parameter=param->queue;
3468 builditerators(task, j, parameter);
3473 void toiReset(struct tagobjectiterator * it) {
3476 } else if (it->numtags>0) {
3479 ObjectHashiterator(it->objectset, &it->it);
3483 int toiHasNext(struct tagobjectiterator *it,
3484 void ** objectarray OPTARG(int * failed)) {
3487 /* Get object with tags */
3488 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3489 struct ___Object___ *tagptr=obj->___tags___;
3490 if (tagptr->type==TAGTYPE) {
3491 if ((it->tagobjindex==0)&& /* First object */
3492 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3497 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3498 int tagindex=it->tagobjindex;
3499 for(; tagindex<ao->___cachedCode___; tagindex++) {
3500 struct ___TagDescriptor___ *td=
3501 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3502 if (td->flag==it->tagid) {
3503 it->tagobjindex=tagindex; /* Found right type of tag */
3509 } else if (it->numtags>0) {
3510 /* Use tags to locate appropriate objects */
3511 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3512 struct ___Object___ *objptr=tag->flagptr;
3514 if (objptr->type!=OBJECTARRAYTYPE) {
3515 if (it->tagobjindex>0)
3517 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3519 for(i=1; i<it->numtags; i++) {
3520 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3521 if (!containstag(objptr,tag2))
3526 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3529 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
3530 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3531 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3533 for(i=1; i<it->numtags; i++) {
3534 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3535 if (!containstag(objptr,tag2))
3538 it->tagobjindex=tagindex;
3543 it->tagobjindex=tagindex;
3547 return ObjhasNext(&it->it);
3551 int containstag(struct ___Object___ *ptr,
3552 struct ___TagDescriptor___ *tag) {
3554 struct ___Object___ * objptr=tag->flagptr;
3555 if (objptr->type==OBJECTARRAYTYPE) {
3556 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3557 for(j=0; j<ao->___cachedCode___; j++) {
3558 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3568 void toiNext(struct tagobjectiterator *it,
3569 void ** objectarray OPTARG(int * failed)) {
3570 /* hasNext has all of the intelligence */
3573 /* Get object with tags */
3574 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3575 struct ___Object___ *tagptr=obj->___tags___;
3576 if (tagptr->type==TAGTYPE) {
3578 objectarray[it->slot]=tagptr;
3580 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3581 objectarray[it->slot]=
3582 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3584 } else if (it->numtags>0) {
3585 /* Use tags to locate appropriate objects */
3586 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3587 struct ___Object___ *objptr=tag->flagptr;
3588 if (objptr->type!=OBJECTARRAYTYPE) {
3590 objectarray[it->slot]=objptr;
3592 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3593 objectarray[it->slot]=
3594 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3597 /* Iterate object */
3598 objectarray[it->slot]=(void *)Objkey(&it->it);
3604 inline void profileTaskStart(char * taskname) {
3605 if(!taskInfoOverflow) {
3606 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
3607 taskInfoArray[taskInfoIndex] = taskInfo;
3608 taskInfo->taskName = taskname;
3609 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
3610 taskInfo->endTime = -1;
3611 taskInfo->exitIndex = -1;
3612 taskInfo->newObjs = NULL;
3616 inline void profileTaskEnd() {
3617 if(!taskInfoOverflow) {
3618 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
3620 if(taskInfoIndex == TASKINFOLENGTH) {
3621 taskInfoOverflow = true;
3622 //taskInfoIndex = 0;
3627 // output the profiling data
3628 void outputProfileData() {
3631 unsigned long long totaltasktime = 0;
3632 unsigned long long preprocessingtime = 0;
3633 unsigned long long objqueuecheckingtime = 0;
3634 unsigned long long postprocessingtime = 0;
3635 //int interruptiontime = 0;
3636 unsigned long long other = 0;
3637 unsigned long long averagetasktime = 0;
3640 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
3641 // output task related info
3642 for(i = 0; i < taskInfoIndex; i++) {
3643 TaskInfo* tmpTInfo = taskInfoArray[i];
3644 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
3645 printf("%s, %lld, %lld, %lld, %lld",
3646 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
3647 duration, tmpTInfo->exitIndex);
3648 // summarize new obj info
3649 if(tmpTInfo->newObjs != NULL) {
3650 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3651 struct RuntimeIterator * iter = NULL;
3652 while(0 == isEmpty(tmpTInfo->newObjs)) {
3653 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3654 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3656 RuntimeHashget(nobjtbl, (int)objtype, &num);
3657 RuntimeHashremovekey(nobjtbl, (int)objtype);
3659 RuntimeHashadd(nobjtbl, (int)objtype, num);
3661 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3663 //printf(stderr, "new obj!\n");
3666 // output all new obj info
3667 iter = RuntimeHashcreateiterator(nobjtbl);
3668 while(RunhasNext(iter)) {
3669 char * objtype = (char *)Runkey(iter);
3670 int num = Runnext(iter);
3671 printf(", %s, %d", objtype, num);
3675 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
3676 preprocessingtime += duration;
3677 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
3678 postprocessingtime += duration;
3679 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
3680 objqueuecheckingtime += duration;
3682 totaltasktime += duration;
3683 averagetasktime += duration;
3688 if(taskInfoOverflow) {
3689 printf("Caution: task info overflow!\n");
3692 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
3693 averagetasktime /= tasknum;
3695 printf("\nTotal time: %lld\n", totalexetime);
3696 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
3697 (int)(((double)totaltasktime/(double)totalexetime)*100));
3698 printf("Total objqueue checking time: %lld (%d%%)\n",
3699 objqueuecheckingtime,
3700 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
3701 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
3702 (int)(((double)preprocessingtime/(double)totalexetime)*100));
3703 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
3704 (int)(((double)postprocessingtime/(double)totalexetime)*100));
3705 printf("Other time: %lld (%d%%)\n", other,
3706 (int)(((double)other/(double)totalexetime)*100));
3708 printf("\nAverage task execution time: %lld\n", averagetasktime);
3713 BAMBOO_DEBUGPRINT(0xdddd);
3714 // output task related info
3715 for(i= 0; i < taskInfoIndex; i++) {
3716 TaskInfo* tmpTInfo = taskInfoArray[i];
3717 char* tmpName = tmpTInfo->taskName;
3718 int nameLen = strlen(tmpName);
3719 BAMBOO_DEBUGPRINT(0xddda);
3720 for(j = 0; j < nameLen; j++) {
3721 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
3723 BAMBOO_DEBUGPRINT(0xdddb);
3724 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
3725 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
3726 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
3727 if(tmpTInfo->newObjs != NULL) {
3728 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3729 struct RuntimeIterator * iter = NULL;
3730 while(0 == isEmpty(tmpTInfo->newObjs)) {
3731 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3732 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3734 RuntimeHashget(nobjtbl, (int)objtype, &num);
3735 RuntimeHashremovekey(nobjtbl, (int)objtype);
3737 RuntimeHashadd(nobjtbl, (int)objtype, num);
3739 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3743 // ouput all new obj info
3744 iter = RuntimeHashcreateiterator(nobjtbl);
3745 while(RunhasNext(iter)) {
3746 char * objtype = (char *)Runkey(iter);
3747 int num = Runnext(iter);
3748 int nameLen = strlen(objtype);
3749 BAMBOO_DEBUGPRINT(0xddda);
3750 for(j = 0; j < nameLen; j++) {
3751 BAMBOO_DEBUGPRINT_REG(objtype[j]);
3753 BAMBOO_DEBUGPRINT(0xdddb);
3754 BAMBOO_DEBUGPRINT_REG(num);
3757 BAMBOO_DEBUGPRINT(0xdddc);
3760 if(taskInfoOverflow) {
3761 BAMBOO_DEBUGPRINT(0xefee);
3764 // output interrupt related info
3765 /*for(i = 0; i < interruptInfoIndex; i++) {
3766 InterruptInfo* tmpIInfo = interruptInfoArray[i];
3767 BAMBOO_DEBUGPRINT(0xddde);
3768 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
3769 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
3770 BAMBOO_DEBUGPRINT(0xdddf);
3773 if(interruptInfoOverflow) {
3774 BAMBOO_DEBUGPRINT(0xefef);
3777 BAMBOO_DEBUGPRINT(0xeeee);
3780 #endif // #ifdef PROFILE