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;
409 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
410 BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
411 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
413 // profile mode, send msgs to other cores to request pouring
414 // out progiling data
416 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
418 BAMBOO_DEBUGPRINT(0xf000);
420 for(i = 1; i < NUMCORESACTIVE; ++i) {
421 // send profile request msg to core i
422 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
423 } // for(i = 1; i < NUMCORESACTIVE; ++i)
424 // pour profiling data on startup core
427 BAMBOO_START_CRITICAL_SECTION_STATUS();
429 BAMBOO_DEBUGPRINT(0xf001);
431 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
432 // check the status of all cores
435 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
437 for(i = 0; i < NUMCORESACTIVE; ++i) {
439 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
441 if(profilestatus[i] != 0) {
445 } // for(i = 0; i < NUMCORESACTIVE; ++i)
448 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
450 BAMBOO_DEBUGPRINT(0xf000);
460 // gc_profile mode, ourput gc prfiling data
463 gc_outputProfileData();
464 #endif // #ifdef GC_PROFILE
465 #endif // #ifdef MULTICORE_GC
467 terminate(); // All done.
468 } // if(!waitconfirm)
470 // still some objects on the fly on the network
471 // reset the waitconfirm and numconfirm
473 BAMBOO_DEBUGPRINT(0xee07);
477 } // if(0 == sumsendobj)
479 // not all cores are stall, keep on waiting
481 BAMBOO_DEBUGPRINT(0xee08);
486 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
488 BAMBOO_DEBUGPRINT(0xf000);
490 } // if((!waitconfirm) ||
493 // main function for each core
494 inline void run(void * arg) {
498 bool sendStall = false;
500 bool tocontinue = false;
502 corenum = BAMBOO_GET_NUM_OF_CORE();
504 BAMBOO_DEBUGPRINT(0xeeee);
505 BAMBOO_DEBUGPRINT_REG(corenum);
506 BAMBOO_DEBUGPRINT(STARTUPCORE);
509 // initialize runtime data structures
512 // other architecture related initialization
516 initializeexithandler();
518 // main process of the execution module
519 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
520 // non-executing cores, only processing communications
523 BAMBOO_DEBUGPRINT(0xee01);
524 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
525 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
526 profileTaskStart("msg handling");
530 //isInterrupt = false;
534 /* Create queue of active tasks */
536 genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
537 (int(*) (void *,void *)) &comparetpd);
539 /* Process task information */
542 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
543 /* Create startup object */
544 createstartupobject(argc, argv);
548 BAMBOO_DEBUGPRINT(0xee00);
553 // check if need to do GC
557 // check if there are new active tasks can be executed
564 while(receiveObject() != -1) {
569 BAMBOO_DEBUGPRINT(0xee01);
572 // check if there are some pending objects,
573 // if yes, enqueue them and executetasks again
574 tocontinue = checkObjQueue();
578 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
581 BAMBOO_DEBUGPRINT(0xee03);
589 BAMBOO_DEBUGPRINT(0xee09);
595 // wait for some time
598 BAMBOO_DEBUGPRINT(0xee0a);
604 // send StallMsg to startup core
606 BAMBOO_DEBUGPRINT(0xee0b);
609 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
610 self_numsendobjs, self_numreceiveobjs, false);
622 BAMBOO_DEBUGPRINT(0xee0c);
625 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
628 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
632 struct ___createstartupobject____I_locals {
635 struct ___StartupObject___ * ___startupobject___;
636 struct ArrayObject * ___stringarray___;
637 }; // struct ___createstartupobject____I_locals
639 void createstartupobject(int argc,
643 /* Allocate startup object */
645 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
646 struct ___StartupObject___ *startupobject=
647 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
648 ___locals___.___startupobject___ = startupobject;
649 struct ArrayObject * stringarray=
650 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
651 ___locals___.___stringarray___ = stringarray;
653 struct ___StartupObject___ *startupobject=
654 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
655 struct ArrayObject * stringarray=
656 allocate_newarray(STRINGARRAYTYPE, argc-1);
658 /* Build array of strings */
659 startupobject->___parameters___=stringarray;
660 for(i=1; i<argc; i++) {
661 int length=strlen(argv[i]);
663 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
665 struct ___String___ *newstring=NewString(argv[i],length);
667 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
671 startupobject->version = 0;
672 startupobject->lock = NULL;
674 /* Set initialized flag for startup object */
675 flagorandinit(startupobject,1,0xFFFFFFFF);
676 enqueueObject(startupobject, NULL, 0);
678 BAMBOO_CACHE_FLUSH_ALL();
682 int hashCodetpd(struct taskparamdescriptor *ftd) {
683 int hash=(int)ftd->task;
685 for(i=0; i<ftd->numParameters; i++) {
686 hash^=(int)ftd->parameterArray[i];
691 int comparetpd(struct taskparamdescriptor *ftd1,
692 struct taskparamdescriptor *ftd2) {
694 if (ftd1->task!=ftd2->task)
696 for(i=0; i<ftd1->numParameters; i++)
697 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
702 /* This function sets a tag. */
704 void tagset(void *ptr,
705 struct ___Object___ * obj,
706 struct ___TagDescriptor___ * tagd) {
708 void tagset(struct ___Object___ * obj,
709 struct ___TagDescriptor___ * tagd) {
711 struct ArrayObject * ao=NULL;
712 struct ___Object___ * tagptr=obj->___tags___;
714 obj->___tags___=(struct ___Object___ *)tagd;
716 /* Have to check if it is already set */
717 if (tagptr->type==TAGTYPE) {
718 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
723 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
724 struct ArrayObject * ao=
725 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
726 obj=(struct ___Object___ *)ptrarray[2];
727 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
728 td=(struct ___TagDescriptor___ *) obj->___tags___;
730 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
733 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
734 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
735 obj->___tags___=(struct ___Object___ *) ao;
736 ao->___cachedCode___=2;
740 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
741 for(i=0; i<ao->___cachedCode___; i++) {
742 struct ___TagDescriptor___ * td=
743 ARRAYGET(ao, struct ___TagDescriptor___*, i);
748 if (ao->___cachedCode___<ao->___length___) {
749 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
750 ao->___cachedCode___++;
753 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
754 struct ArrayObject * aonew=
755 allocate_newarray(&ptrarray,TAGARRAYTYPE,
756 TAGARRAYINTERVAL+ao->___length___);
757 obj=(struct ___Object___ *)ptrarray[2];
758 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
759 ao=(struct ArrayObject *)obj->___tags___;
761 struct ArrayObject * aonew=
762 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
765 aonew->___cachedCode___=ao->___length___+1;
766 for(i=0; i<ao->___length___; i++) {
767 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
768 ARRAYGET(ao, struct ___TagDescriptor___*, i));
770 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
776 struct ___Object___ * tagset=tagd->flagptr;
779 } else if (tagset->type!=OBJECTARRAYTYPE) {
781 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
782 struct ArrayObject * ao=
783 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
784 obj=(struct ___Object___ *)ptrarray[2];
785 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
787 struct ArrayObject * ao=
788 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
790 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
791 ARRAYSET(ao, struct ___Object___ *, 1, obj);
792 ao->___cachedCode___=2;
793 tagd->flagptr=(struct ___Object___ *)ao;
795 struct ArrayObject *ao=(struct ArrayObject *) tagset;
796 if (ao->___cachedCode___<ao->___length___) {
797 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
801 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
802 struct ArrayObject * aonew=
803 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
804 OBJECTARRAYINTERVAL+ao->___length___);
805 obj=(struct ___Object___ *)ptrarray[2];
806 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
807 ao=(struct ArrayObject *)tagd->flagptr;
809 struct ArrayObject * aonew=
810 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
812 aonew->___cachedCode___=ao->___cachedCode___+1;
813 for(i=0; i<ao->___length___; i++) {
814 ARRAYSET(aonew, struct ___Object___*, i,
815 ARRAYGET(ao, struct ___Object___*, i));
817 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
818 tagd->flagptr=(struct ___Object___ *) aonew;
824 /* This function clears a tag. */
826 void tagclear(void *ptr,
827 struct ___Object___ * obj,
828 struct ___TagDescriptor___ * tagd) {
830 void tagclear(struct ___Object___ * obj,
831 struct ___TagDescriptor___ * tagd) {
833 /* We'll assume that tag is alway there.
834 Need to statically check for this of course. */
835 struct ___Object___ * tagptr=obj->___tags___;
837 if (tagptr->type==TAGTYPE) {
838 if ((struct ___TagDescriptor___ *)tagptr==tagd)
839 obj->___tags___=NULL;
841 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
843 for(i=0; i<ao->___cachedCode___; i++) {
844 struct ___TagDescriptor___ * td=
845 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
847 ao->___cachedCode___--;
848 if (i<ao->___cachedCode___)
849 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
850 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
851 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
852 if (ao->___cachedCode___==0)
853 obj->___tags___=NULL;
860 struct ___Object___ *tagset=tagd->flagptr;
861 if (tagset->type!=OBJECTARRAYTYPE) {
865 struct ArrayObject *ao=(struct ArrayObject *) tagset;
867 for(i=0; i<ao->___cachedCode___; i++) {
868 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
870 ao->___cachedCode___--;
871 if (i<ao->___cachedCode___)
872 ARRAYSET(ao, struct ___Object___ *, i,
873 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
874 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
875 if (ao->___cachedCode___==0)
886 /* This function allocates a new tag. */
888 struct ___TagDescriptor___ * allocate_tag(void *ptr,
890 struct ___TagDescriptor___ * v=
891 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
894 struct ___TagDescriptor___ * allocate_tag(int index) {
895 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
904 /* This function updates the flag for object ptr. It or's the flag
905 with the or mask and and's it with the andmask. */
907 void flagbody(struct ___Object___ *ptr,
909 struct parameterwrapper ** queues,
913 int flagcomp(const int *val1, const int *val2) {
914 return (*val1)-(*val2);
917 void flagorand(void * ptr,
920 struct parameterwrapper ** queues,
923 int oldflag=((int *)ptr)[1];
924 int flag=ormask|oldflag;
926 flagbody(ptr, flag, queues, length, false);
930 bool intflagorand(void * ptr,
934 int oldflag=((int *)ptr)[1];
935 int flag=ormask|oldflag;
937 if (flag==oldflag) /* Don't do anything */
940 flagbody(ptr, flag, NULL, 0, false);
946 void flagorandinit(void * ptr,
949 int oldflag=((int *)ptr)[1];
950 int flag=ormask|oldflag;
952 flagbody(ptr,flag,NULL,0,true);
955 void flagbody(struct ___Object___ *ptr,
957 struct parameterwrapper ** vqueues,
960 struct parameterwrapper * flagptr = NULL;
962 struct parameterwrapper ** queues = vqueues;
963 int length = vlength;
966 int * enterflags = NULL;
967 if((!isnew) && (queues == NULL)) {
968 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
969 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
970 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
977 /*Remove object from all queues */
978 for(i = 0; i < length; ++i) {
980 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
981 (int *) &enterflags, &UNUSED, &UNUSED2);
982 ObjectHashremove(flagptr->objectset, (int)ptr);
983 if (enterflags!=NULL)
988 void enqueueObject(void * vptr,
989 struct parameterwrapper ** vqueues,
991 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
994 //struct QueueItem *tmpptr;
995 struct parameterwrapper * parameter=NULL;
998 struct parameterwrapper * prevptr=NULL;
999 struct ___Object___ *tagptr=NULL;
1000 struct parameterwrapper ** queues = vqueues;
1001 int length = vlength;
1002 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1005 if(queues == NULL) {
1006 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1007 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1009 tagptr=ptr->___tags___;
1011 /* Outer loop iterates through all parameter queues an object of
1012 this type could be in. */
1013 for(j = 0; j < length; ++j) {
1014 parameter = queues[j];
1016 if (parameter->numbertags>0) {
1018 goto nextloop; //that means the object has no tag
1019 //but that param needs tag
1020 else if(tagptr->type==TAGTYPE) { //one tag
1021 //struct ___TagDescriptor___ * tag=
1022 //(struct ___TagDescriptor___*) tagptr;
1023 for(i=0; i<parameter->numbertags; i++) {
1024 //slotid is parameter->tagarray[2*i];
1025 int tagid=parameter->tagarray[2*i+1];
1026 if (tagid!=tagptr->flag)
1027 goto nextloop; /*We don't have this tag */
1029 } else { //multiple tags
1030 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1031 for(i=0; i<parameter->numbertags; i++) {
1032 //slotid is parameter->tagarray[2*i];
1033 int tagid=parameter->tagarray[2*i+1];
1035 for(j=0; j<ao->___cachedCode___; j++) {
1036 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1047 for(i=0; i<parameter->numberofterms; i++) {
1048 int andmask=parameter->intarray[i*2];
1049 int checkmask=parameter->intarray[i*2+1];
1050 if ((ptr->flag&andmask)==checkmask) {
1051 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1062 void enqueueObject_I(void * vptr,
1063 struct parameterwrapper ** vqueues,
1065 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1068 //struct QueueItem *tmpptr;
1069 struct parameterwrapper * parameter=NULL;
1072 struct parameterwrapper * prevptr=NULL;
1073 struct ___Object___ *tagptr=NULL;
1074 struct parameterwrapper ** queues = vqueues;
1075 int length = vlength;
1076 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1079 if(queues == NULL) {
1080 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1081 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1083 tagptr=ptr->___tags___;
1085 /* Outer loop iterates through all parameter queues an object of
1086 this type could be in. */
1087 for(j = 0; j < length; ++j) {
1088 parameter = queues[j];
1090 if (parameter->numbertags>0) {
1092 goto nextloop; //that means the object has no tag
1093 //but that param needs tag
1094 else if(tagptr->type==TAGTYPE) { //one tag
1095 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1096 for(i=0; i<parameter->numbertags; i++) {
1097 //slotid is parameter->tagarray[2*i];
1098 int tagid=parameter->tagarray[2*i+1];
1099 if (tagid!=tagptr->flag)
1100 goto nextloop; /*We don't have this tag */
1102 } else { //multiple tags
1103 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1104 for(i=0; i<parameter->numbertags; i++) {
1105 //slotid is parameter->tagarray[2*i];
1106 int tagid=parameter->tagarray[2*i+1];
1108 for(j=0; j<ao->___cachedCode___; j++) {
1109 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1120 for(i=0; i<parameter->numberofterms; i++) {
1121 int andmask=parameter->intarray[i*2];
1122 int checkmask=parameter->intarray[i*2+1];
1123 if ((ptr->flag&andmask)==checkmask) {
1124 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1136 int * getAliasLock(void ** ptrs,
1138 struct RuntimeHash * tbl) {
1140 return (int*)(RUNMALLOC(sizeof(int)));
1145 bool redirect = false;
1146 int redirectlock = 0;
1147 for(; i < length; i++) {
1148 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1151 if(ptr->lock == NULL) {
1154 lock = (int)(ptr->lock);
1157 if(lock != redirectlock) {
1158 RuntimeHashadd(tbl, lock, redirectlock);
1161 if(RuntimeHashcontainskey(tbl, lock)) {
1162 // already redirected
1164 RuntimeHashget(tbl, lock, &redirectlock);
1165 for(; j < locklen; j++) {
1166 if(locks[j] != redirectlock) {
1167 RuntimeHashadd(tbl, locks[j], redirectlock);
1172 for(j = 0; j < locklen; j++) {
1173 if(locks[j] == lock) {
1176 } else if(locks[j] > lock) {
1183 locks[h] = locks[h-1];
1192 return (int *)redirectlock;
1194 return (int *)(locks[0]);
1199 void addAliasLock(void * ptr,
1201 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1202 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1203 // originally no alias lock associated or have a different alias lock
1204 // flush it as the new one
1205 obj->lock = (int *)lock;
1210 inline void setTaskExitIndex(int index) {
1211 taskInfoArray[taskInfoIndex]->exitIndex = index;
1214 inline void addNewObjInfo(void * nobj) {
1215 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1216 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1218 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1223 void * localmalloc_I(int coren,
1229 int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1230 int totest = tofindb;
1231 int bound = BAMBOO_SMEM_SIZE_L;
1235 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1236 int nsize = bamboo_smemtbl[totest];
1237 bool islocal = true;
1239 bool tocheck = true;
1240 // have some space in the block
1241 if(totest == tofindb) {
1242 // the first partition
1243 size = bound - nsize;
1244 } else if(nsize == 0) {
1245 // an empty partition, can be appended
1248 // not an empty partition, can not be appended
1249 // the last continuous block is not big enough, go to check the next
1253 } // if(totest == tofindb) else if(nsize == 0) else ...
1256 // have enough space in the block, malloc
1260 // no enough space yet, try to append next continuous block
1262 } // if(size > isize) else ...
1264 } // if(nsize < bound)
1266 // no space in the block, go to check the next block
1272 tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1275 } // if(islocal) else ...
1276 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1277 // no more local mem, do not find suitable block
1280 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1283 if(foundsmem == 1) {
1284 // find suitable block
1285 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC)?
1286 (BAMBOO_SMEM_SIZE_L*tofindb):(BAMBOO_LARGE_SMEM_BOUND+
1287 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1289 // set bamboo_smemtbl
1290 for(i = tofindb; i <= totest; i++) {
1291 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1293 } else if(foundsmem == 2) {
1294 // no suitable block
1299 } // void * localmalloc_I(int, int, int *)
1301 void * globalmalloc_I(int coren,
1305 int tofindb = bamboo_free_block; //0;
1306 int totest = tofindb;
1307 int bound = BAMBOO_SMEM_SIZE_L;
1310 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1315 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1316 int nsize = bamboo_smemtbl[totest];
1317 bool isnext = false;
1319 bool tocheck = true;
1320 // have some space in the block
1321 if(totest == tofindb) {
1322 // the first partition
1323 size = bound - nsize;
1324 } else if(nsize == 0) {
1325 // an empty partition, can be appended
1328 // not an empty partition, can not be appended
1329 // the last continuous block is not big enough, start another block
1332 } // if(totest == tofindb) else if(nsize == 0) else ...
1335 // have enough space in the block, malloc
1338 } // if(size > isize)
1342 }// if(nsize < bound) else ...
1344 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1345 // no more local mem, do not find suitable block
1348 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1350 // start another block
1355 if(foundsmem == 1) {
1356 // find suitable block
1357 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC)?
1358 (BAMBOO_SMEM_SIZE_L*tofindb):(BAMBOO_LARGE_SMEM_BOUND+
1359 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1361 // set bamboo_smemtbl
1362 for(int i = tofindb; i <= totest; i++) {
1363 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1365 if(tofindb == bamboo_free_block) {
1366 bamboo_free_block = totest+1;
1368 } else if(foundsmem == 2) {
1369 // no suitable block
1375 } // void * globalmalloc_I(int, int, int *)
1376 #endif // #ifdef MULTICORE_GC
1378 // malloc from the shared memory
1379 void * smemalloc_I(int coren,
1384 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1386 // go through the bamboo_smemtbl for suitable partitions
1387 switch(bamboo_smem_mode) {
1389 mem = localmalloc_I(coren, isize, allocsize);
1394 // TODO not supported yet
1395 BAMBOO_EXIT(0xe001);
1400 // TODO not supported yet
1401 BAMBOO_EXIT(0xe002);
1406 mem = globalmalloc_I(coren, isize, allocsize);
1416 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size):(BAMBOO_SMEM_SIZE);
1417 mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1418 *allocsize = toallocate;
1421 // no enough shared global memory
1427 BAMBOO_DEBUGPRINT(0xa001);
1428 BAMBOO_EXIT(0xa001);
1432 } // void * smemalloc_I(int, int, int)
1434 INLINE int checkMsgLength_I(int size) {
1437 BAMBOO_DEBUGPRINT(0xcccc);
1440 int type = msgdata[msgdataindex];
1459 case GCSTARTCOMPACT:
1483 case REDIRECTGROUNT:
1485 case REDIRECTRELEASE:
1497 case GCFINISHCOMPACT:
1509 case TRANSOBJ: // nonfixed size
1515 msglength = msgdata[msgdataindex+1];
1523 BAMBOO_DEBUGPRINT_REG(type);
1526 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1528 BAMBOO_EXIT(0xd005);
1534 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1539 BAMBOO_DEBUGPRINT(0xffff);
1545 INLINE void processmsg_transobj_I() {
1547 struct transObjInfo * transObj = RUNMALLOC_I(sizeof(struct transObjInfo));
1551 BAMBOO_DEBUGPRINT(0xe880);
1554 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1556 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]/*[2]*/);
1558 BAMBOO_EXIT(0xa002);
1560 // store the object and its corresponding queue info, enqueue it later
1561 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
1563 transObj->length = (msglength - 3) / 2;
1564 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1565 for(k = 0; k < transObj->length; ++k) {
1566 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
1570 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1573 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
1577 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1581 // check if there is an existing duplicate item
1583 struct QueueItem * qitem = getHead(&objqueue);
1584 struct QueueItem * prev = NULL;
1585 while(qitem != NULL) {
1586 struct transObjInfo * tmpinfo =
1587 (struct transObjInfo *)(qitem->objectptr);
1588 if(tmpinfo->objptr == transObj->objptr) {
1589 // the same object, remove outdate one
1590 RUNFREE(tmpinfo->queues);
1592 removeItem(&objqueue, qitem);
1598 qitem = getHead(&objqueue);
1600 qitem = getNextQueueItem(prev);
1603 addNewItem_I(&objqueue, (void *)transObj);
1605 ++(self_numreceiveobjs);
1608 INLINE void processmsg_transtall_I() {
1609 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1610 // non startup core can not receive stall msg
1612 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]/*[1]*/);
1614 BAMBOO_EXIT(0xa003);
1616 int num_core = msgdata[msgdataindex]; //[1]
1618 if(num_core < NUMCORESACTIVE) {
1621 BAMBOO_DEBUGPRINT(0xe881);
1624 corestatus[num_core] = 0;
1625 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
1627 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
1632 #ifndef MULTICORE_GC
1633 INLINE void processmsg_lockrequest_I() {
1634 // check to see if there is a lock exist for the required obj
1635 // msgdata[1] -> lock type
1636 int locktype = msgdata[msgdataindex]; //[1];
1638 int data2 = msgdata[msgdataindex]; // obj pointer
1640 int data3 = msgdata[msgdataindex]; // lock
1642 int data4 = msgdata[msgdataindex]; // request core
1644 // -1: redirected, 0: approved, 1: denied
1645 deny = processlockrequest(locktype, data3, data2, data4, data4, true);
1647 // this lock request is redirected
1650 // send response msg
1651 // for 32 bit machine, the size is always 4 words
1652 int tmp = deny==1?LOCKDENY:LOCKGROUNT;
1654 cache_msg_4(data4, tmp, locktype, data2, data3);
1656 send_msg_4(data4, tmp, locktype, data2, data3, true);
1661 INLINE void processmsg_lockgrount_I() {
1663 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1665 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]/*[2]*/);
1667 BAMBOO_EXIT(0xa004);
1669 int data2 = msgdata[msgdataindex];
1671 int data3 = msgdata[msgdataindex];
1673 if((lockobj == data2) && (lock2require == data3)) {
1676 BAMBOO_DEBUGPRINT(0xe882);
1685 // conflicts on lockresults
1687 BAMBOO_DEBUGPRINT_REG(data2);
1689 BAMBOO_EXIT(0xa005);
1693 INLINE void processmsg_lockdeny_I() {
1695 int data2 = msgdata[msgdataindex];
1697 int data3 = msgdata[msgdataindex];
1699 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1701 BAMBOO_DEBUGPRINT_REG(data2);
1703 BAMBOO_EXIT(0xa006);
1705 if((lockobj == data2) && (lock2require == data3)) {
1708 BAMBOO_DEBUGPRINT(0xe883);
1717 // conflicts on lockresults
1719 BAMBOO_DEBUGPRINT_REG(data2);
1721 BAMBOO_EXIT(0xa007);
1725 INLINE void processmsg_lockrelease_I() {
1726 int data1 = msgdata[msgdataindex];
1728 int data2 = msgdata[msgdataindex];
1730 // receive lock release msg
1731 processlockrelease(data1, data2, 0, false);
1734 INLINE void processmsg_redirectlock_I() {
1735 // check to see if there is a lock exist for the required obj
1736 int data1 = msgdata[msgdataindex];
1737 MSG_INDEXINC_I(); //msgdata[1]; // lock type
1738 int data2 = msgdata[msgdataindex];
1739 MSG_INDEXINC_I();//msgdata[2]; // obj pointer
1740 int data3 = msgdata[msgdataindex];
1741 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
1742 int data4 = msgdata[msgdataindex];
1743 MSG_INDEXINC_I(); //msgdata[4]; // root request core
1744 int data5 = msgdata[msgdataindex];
1745 MSG_INDEXINC_I(); //msgdata[5]; // request core
1746 deny = processlockrequest(data1, data3, data2, data5, data4, true);
1748 // this lock request is redirected
1751 // send response msg
1752 // for 32 bit machine, the size is always 4 words
1754 cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1755 data1, data2, data3);
1757 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1758 data1, data2, data3, true);
1763 INLINE void processmsg_redirectgrount_I() {
1765 int data2 = msgdata[msgdataindex];
1767 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1769 BAMBOO_DEBUGPRINT_REG(data2);
1771 BAMBOO_EXIT(0xa00a);
1773 if(lockobj == data2) {
1776 BAMBOO_DEBUGPRINT(0xe891);
1779 int data3 = msgdata[msgdataindex];
1783 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
1788 // conflicts on lockresults
1790 BAMBOO_DEBUGPRINT_REG(data2);
1792 BAMBOO_EXIT(0xa00b);
1796 INLINE void processmsg_redirectdeny_I() {
1798 int data2 = msgdata[msgdataindex];
1800 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1802 BAMBOO_DEBUGPRINT_REG(data2);
1804 BAMBOO_EXIT(0xa00c);
1806 if(lockobj == data2) {
1809 BAMBOO_DEBUGPRINT(0xe892);
1818 // conflicts on lockresults
1820 BAMBOO_DEBUGPRINT_REG(data2);
1822 BAMBOO_EXIT(0xa00d);
1826 INLINE void processmsg_redirectrelease_I() {
1827 int data1 = msgdata[msgdataindex];
1829 int data2 = msgdata[msgdataindex];
1831 int data3 = msgdata[msgdataindex];
1833 processlockrelease(data1, data2, data3, true);
1835 #endif // #ifndef MULTICORE_GC
1838 INLINE void processmsg_profileoutput_I() {
1839 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1840 // startup core can not receive profile output finish msg
1841 BAMBOO_EXIT(0xa008);
1845 BAMBOO_DEBUGPRINT(0xe885);
1849 totalexetime = msgdata[msgdataindex]; //[1]
1851 outputProfileData();
1853 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1855 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
1859 INLINE void processmsg_profilefinish_I() {
1860 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1861 // non startup core can not receive profile output finish msg
1863 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex/*1*/]);
1865 BAMBOO_EXIT(0xa009);
1869 BAMBOO_DEBUGPRINT(0xe886);
1872 int data1 = msgdata[msgdataindex];
1874 profilestatus[data1] = 0;
1876 #endif // #ifdef PROFILE
1878 INLINE void processmsg_statusconfirm_I() {
1879 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1880 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1881 // wrong core to receive such msg
1882 BAMBOO_EXIT(0xa00e);
1884 // send response msg
1887 BAMBOO_DEBUGPRINT(0xe887);
1891 cache_msg_5(STARTUPCORE, STATUSREPORT,
1892 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1893 self_numsendobjs, self_numreceiveobjs);
1895 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
1896 BAMBOO_NUM_OF_CORE, self_numsendobjs,
1897 self_numreceiveobjs, true);
1902 INLINE void processmsg_statusreport_I() {
1903 int data1 = msgdata[msgdataindex];
1905 int data2 = msgdata[msgdataindex];
1907 int data3 = msgdata[msgdataindex];
1909 int data4 = msgdata[msgdataindex];
1911 // receive a status confirm info
1912 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1913 // wrong core to receive such msg
1915 BAMBOO_DEBUGPRINT_REG(data2);
1917 BAMBOO_EXIT(0xa00f);
1921 BAMBOO_DEBUGPRINT(0xe888);
1927 corestatus[data2] = data1;
1928 numsendobjs[data2] = data3;
1929 numreceiveobjs[data2] = data4;
1933 INLINE void processmsg_terminate_I() {
1936 BAMBOO_DEBUGPRINT(0xe889);
1943 INLINE void processmsg_memrequest_I() {
1944 int data1 = msgdata[msgdataindex];
1946 int data2 = msgdata[msgdataindex];
1948 // receive a shared memory request msg
1949 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1950 // wrong core to receive such msg
1952 BAMBOO_DEBUGPRINT_REG(data2);
1954 BAMBOO_EXIT(0xa010);
1958 BAMBOO_DEBUGPRINT(0xe88a);
1965 // is currently doing gc, dump this msg
1966 if(INITPHASE == gcphase) {
1967 // if still in the initphase of gc, send a startinit msg again
1969 cache_msg_1(data2, GCSTARTINIT);
1971 send_msg_1(data2, GCSTARTINIT, true);
1976 mem = smemalloc_I(data2, data1, &allocsize);
1978 // send the start_va to request core
1980 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
1982 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
1984 } // if mem == NULL, the gcflag of the startup core has been set
1985 // and the gc should be started later, then a GCSTARTINIT msg
1986 // will be sent to the requesting core to notice it to start gc
1987 // and try malloc again
1994 INLINE void processmsg_memresponse_I() {
1995 int data1 = msgdata[msgdataindex];
1997 int data2 = msgdata[msgdataindex];
1999 // receive a shared memory response msg
2002 BAMBOO_DEBUGPRINT(0xe88b);
2006 // if is currently doing gc, dump this msg
2010 bamboo_smem_size = 0;
2014 // fill header to store the size of this mem block
2015 memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2016 (*((int*)data1)) = data2;
2017 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2018 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2020 bamboo_smem_size = data2;
2021 bamboo_cur_msp =(void*)(data1);
2031 INLINE void processmsg_gcstartinit_I() {
2033 gcphase = INITPHASE;
2035 // is waiting for response of mem request
2036 // let it return NULL and start gc
2037 bamboo_smem_size = 0;
2038 bamboo_cur_msp = NULL;
2043 INLINE void processmsg_gcstart_I() {
2046 BAMBOO_DEBUGPRINT(0xe88c);
2050 gcphase = MARKPHASE;
2053 INLINE void processmsg_gcstartcompact_I() {
2054 gcblock2fill = msgdata[msgdataindex];
2055 MSG_INDEXINC_I(); //msgdata[1];
2056 gcphase = COMPACTPHASE;
2059 INLINE void processmsg_gcstartflush_I() {
2060 gcphase = FLUSHPHASE;
2063 INLINE void processmsg_gcfinishinit_I() {
2064 int data1 = msgdata[msgdataindex];
2066 // received a init phase finish msg
2067 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2068 // non startup core can not receive this msg
2070 BAMBOO_DEBUGPRINT_REG(data1);
2072 BAMBOO_EXIT(0xb001);
2075 BAMBOO_DEBUGPRINT(0xe88c);
2076 BAMBOO_DEBUGPRINT_REG(data1);
2078 // All cores should do init GC
2079 if(data1 < NUMCORESACTIVE) {
2080 gccorestatus[data1] = 0;
2084 INLINE void processmsg_gcfinishmark_I() {
2085 int data1 = msgdata[msgdataindex];
2087 int data2 = msgdata[msgdataindex];
2089 int data3 = msgdata[msgdataindex];
2091 // received a mark phase finish msg
2092 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2093 // non startup core can not receive this msg
2095 BAMBOO_DEBUGPRINT_REG(data1);
2097 BAMBOO_EXIT(0xb002);
2099 // all cores should do mark
2100 if(data1 < NUMCORESACTIVE) {
2101 gccorestatus[data1] = 0;
2102 gcnumsendobjs[data1] = data2;
2103 gcnumreceiveobjs[data1] = data3;
2107 INLINE void processmsg_gcfinishcompact_I() {
2108 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2109 // non startup core can not receive this msg
2112 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]/*[1]*/);
2114 BAMBOO_EXIT(0xb003);
2116 int cnum = msgdata[msgdataindex];
2117 MSG_INDEXINC_I(); //msgdata[1];
2118 int filledblocks = msgdata[msgdataindex];
2119 MSG_INDEXINC_I(); //msgdata[2];
2120 int heaptop = msgdata[msgdataindex];
2121 MSG_INDEXINC_I(); //msgdata[3];
2122 int data4 = msgdata[msgdataindex];
2123 MSG_INDEXINC_I(); //msgdata[4];
2124 // only gc cores need to do compact
2125 if(cnum < NUMCORES4GC) {
2126 if(COMPACTPHASE == gcphase) {
2127 gcfilledblocks[cnum] = filledblocks;
2128 gcloads[cnum] = heaptop;
2135 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2137 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2139 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2143 gccorestatus[cnum] = 0;
2145 } // if(cnum < NUMCORES4GC)
2148 INLINE void processmsg_gcfinishflush_I() {
2149 int data1 = msgdata[msgdataindex];
2151 // received a flush phase finish msg
2152 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2153 // non startup core can not receive this msg
2156 BAMBOO_DEBUGPRINT_REG(data1);
2158 BAMBOO_EXIT(0xb004);
2160 // all cores should do flush
2161 if(data1 < NUMCORESACTIVE) {
2162 gccorestatus[data1] = 0;
2166 INLINE void processmsg_gcmarkconfirm_I() {
2167 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2168 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2169 // wrong core to receive such msg
2170 BAMBOO_EXIT(0xb005);
2172 // send response msg
2174 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2175 gcbusystatus, gcself_numsendobjs,
2176 gcself_numreceiveobjs);
2178 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2179 gcbusystatus, gcself_numsendobjs,
2180 gcself_numreceiveobjs, true);
2185 INLINE void processmsg_gcmarkreport_I() {
2186 int data1 = msgdata[msgdataindex];
2188 int data2 = msgdata[msgdataindex];
2190 int data3 = msgdata[msgdataindex];
2192 int data4 = msgdata[msgdataindex];
2194 // received a marked phase finish confirm response msg
2195 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2196 // wrong core to receive such msg
2198 BAMBOO_DEBUGPRINT_REG(data2);
2200 BAMBOO_EXIT(0xb006);
2205 gccorestatus[data1] = data2;
2206 gcnumsendobjs[data1] = data3;
2207 gcnumreceiveobjs[data1] = data4;
2211 INLINE void processmsg_gcmarkedobj_I() {
2212 int data1 = msgdata[msgdataindex];
2214 // received a markedObj msg
2215 if(((int *)data1)[6] == INIT) {
2216 // this is the first time that this object is discovered,
2217 // set the flag as DISCOVERED
2218 ((int *)data1)[6] = DISCOVERED;
2219 gc_enqueue_I(data1);
2221 gcself_numreceiveobjs++;
2222 gcbusystatus = true;
2225 INLINE void processmsg_gcmovestart_I() {
2227 gcdstcore = msgdata[msgdataindex];
2228 MSG_INDEXINC_I(); //msgdata[1];
2229 gcmovestartaddr = msgdata[msgdataindex];
2230 MSG_INDEXINC_I(); //msgdata[2];
2231 gcblock2fill = msgdata[msgdataindex];
2232 MSG_INDEXINC_I(); //msgdata[3];
2235 INLINE void processmsg_gcmaprequest_I() {
2237 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2239 void * dstptr = NULL;
2240 int data1 = msgdata[msgdataindex];
2242 //dstptr = mgchashSearch(msgdata[1]);
2244 unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2246 RuntimeHashget(gcpointertbl, data1, &dstptr);
2248 flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2250 int data2 = msgdata[msgdataindex];
2252 //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2254 unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2256 if(NULL == dstptr) {
2257 // no such pointer in this core, something is wrong
2259 BAMBOO_DEBUGPRINT_REG(data1);
2260 BAMBOO_DEBUGPRINT_REG(data2);
2262 BAMBOO_EXIT(0xb007);
2263 //assume that the object was not moved, use the original address
2264 /*if(isMsgSending) {
2265 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2267 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1], true);
2270 // send back the mapping info
2272 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2274 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2278 flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2279 //num_mapinforequest_i++;
2283 INLINE void processmsg_gcmapinfo_I() {
2285 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2287 int data1 = msgdata[msgdataindex];
2289 if(data1 != gcobj2map) {
2290 // obj not matched, something is wrong
2292 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2293 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2295 BAMBOO_EXIT(0xb008);
2297 gcmappedobj = msgdata[msgdataindex]; // [2]
2299 //mgchashReplace_I(msgdata[1], msgdata[2]);
2300 //mgchashInsert_I(gcobj2map, gcmappedobj);
2301 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2302 //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2306 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2310 INLINE void processmsg_gclobjinfo_I() {
2313 int data1 = msgdata[msgdataindex];
2315 int data2 = msgdata[msgdataindex];
2317 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2319 BAMBOO_DEBUGPRINT_REG(data2);
2321 BAMBOO_EXIT(0xb009);
2323 // store the mark result info
2325 gcloads[cnum] = msgdata[msgdataindex];
2326 MSG_INDEXINC_I(); // msgdata[3];
2327 int data4 = msgdata[msgdataindex];
2329 if(gcheaptop < data4) {
2332 // large obj info here
2333 for(int k = 5; k < data1;) {
2334 int lobj = msgdata[msgdataindex];
2335 MSG_INDEXINC_I(); //msgdata[k++];
2336 int length = msgdata[msgdataindex];
2337 MSG_INDEXINC_I(); //msgdata[k++];
2338 gc_lobjenqueue_I(lobj, length, cnum);
2340 } // for(int k = 5; k < msgdata[1];)
2343 INLINE void processmsg_gclobjmapping_I() {
2344 int data1 = msgdata[msgdataindex];
2346 int data2 = msgdata[msgdataindex];
2348 //mgchashInsert_I(msgdata[1], msgdata[2]);
2349 RuntimeHashadd_I(gcpointertbl, data1, data2);
2350 //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2352 #endif // #ifdef MULTICORE_GC
2354 // receive object transferred from other cores
2355 // or the terminate message from other cores
2356 // Should be invoked in critical sections!!
2357 // NOTICE: following format is for threadsimulate version only
2358 // RAW version please see previous description
2359 // format: type + object
2360 // type: -1--stall msg
2362 // return value: 0--received an object
2363 // 1--received nothing
2364 // 2--received a Stall Msg
2365 // 3--received a lock Msg
2366 // RAW version: -1 -- received nothing
2367 // otherwise -- received msg type
2368 int receiveObject() {
2372 // get the incoming msgs
2373 if(receiveMsg() == -1) {
2377 // processing received msgs
2379 MSG_REMAINSIZE_I(&size);
2380 if(checkMsgLength_I(size) == -1) {
2382 // have new coming msg
2383 if(BAMBOO_MSG_AVAIL() != 0) {
2390 if(msglength <= size) {
2391 // have some whole msg
2392 //if(msgdataindex == msglength) {
2393 // received a whole msg
2395 type = msgdata[msgdataindex]; //[0]
2397 msgdatafull = false;
2399 //tprintf("msg type: %x\n", type);
2402 // receive a object transfer msg
2403 processmsg_transobj_I();
2408 // receive a stall msg
2409 processmsg_transtall_I();
2413 // GC version have no lock msgs
2414 #ifndef MULTICORE_GC
2416 // receive lock request msg, handle it right now
2417 processmsg_lockrequest_I();
2419 } // case LOCKREQUEST
2422 // receive lock grount msg
2423 processmsg_lockgrount_I();
2425 } // case LOCKGROUNT
2428 // receive lock deny msg
2429 processmsg_lockdeny_I();
2434 processmsg_lockrelease_I();
2436 } // case LOCKRELEASE
2437 #endif // #ifndef MULTICORE_GC
2440 case PROFILEOUTPUT: {
2441 // receive an output profile data request msg
2442 processmsg_profileoutput_I();
2444 } // case PROFILEOUTPUT
2446 case PROFILEFINISH: {
2447 // receive a profile output finish msg
2448 processmsg_profilefinish_I();
2450 } // case PROFILEFINISH
2451 #endif // #ifdef PROFILE
2453 // GC version has no lock msgs
2454 #ifndef MULTICORE_GC
2455 case REDIRECTLOCK: {
2456 // receive a redirect lock request msg, handle it right now
2457 processmsg_redirectlock_I();
2459 } // case REDIRECTLOCK
2461 case REDIRECTGROUNT: {
2462 // receive a lock grant msg with redirect info
2463 processmsg_redirectgrount_I();
2465 } // case REDIRECTGROUNT
2467 case REDIRECTDENY: {
2468 // receive a lock deny msg with redirect info
2469 processmsg_redirectdeny_I();
2471 } // case REDIRECTDENY
2473 case REDIRECTRELEASE: {
2474 // receive a lock release msg with redirect info
2475 processmsg_redirectrelease_I();
2477 } // case REDIRECTRELEASE
2478 #endif // #ifndef MULTICORE_GC
2480 case STATUSCONFIRM: {
2481 // receive a status confirm info
2482 processmsg_statusconfirm_I();
2484 } // case STATUSCONFIRM
2486 case STATUSREPORT: {
2487 processmsg_statusreport_I();
2489 } // case STATUSREPORT
2492 // receive a terminate msg
2493 processmsg_terminate_I();
2498 processmsg_memrequest_I();
2500 } // case MEMREQUEST
2503 processmsg_memresponse_I();
2505 } // case MEMRESPONSE
2510 processmsg_gcstartinit_I();
2512 } // case GCSTARTINIT
2515 // receive a start GC msg
2516 processmsg_gcstart_I();
2520 case GCSTARTCOMPACT: {
2521 // a compact phase start msg
2522 processmsg_gcstartcompact_I();
2524 } // case GCSTARTCOMPACT
2526 case GCSTARTFLUSH: {
2527 // received a flush phase start msg
2528 processmsg_gcstartflush_I();
2530 } // case GCSTARTFLUSH
2532 case GCFINISHINIT: {
2533 processmsg_gcfinishinit_I();
2535 } // case GCFINISHINIT
2537 case GCFINISHMARK: {
2538 processmsg_gcfinishmark_I();
2540 } // case GCFINISHMARK
2542 case GCFINISHCOMPACT: {
2543 // received a compact phase finish msg
2544 processmsg_gcfinishcompact_I();
2546 } // case GCFINISHCOMPACT
2548 case GCFINISHFLUSH: {
2549 processmsg_gcfinishflush_I();
2551 } // case GCFINISHFLUSH
2554 // received a GC finish msg
2555 gcphase = FINISHPHASE;
2559 case GCMARKCONFIRM: {
2560 // received a marked phase finish confirm request msg
2561 // all cores should do mark
2562 processmsg_gcmarkconfirm_I();
2564 } // case GCMARKCONFIRM
2566 case GCMARKREPORT: {
2567 processmsg_gcmarkreport_I();
2569 } // case GCMARKREPORT
2572 processmsg_gcmarkedobj_I();
2574 } // case GCMARKEDOBJ
2577 // received a start moving objs msg
2578 processmsg_gcmovestart_I();
2580 } // case GCMOVESTART
2582 case GCMAPREQUEST: {
2583 // received a mapping info request msg
2584 processmsg_gcmaprequest_I();
2586 } // case GCMAPREQUEST
2589 // received a mapping info response msg
2590 processmsg_gcmapinfo_I();
2594 case GCLOBJREQUEST: {
2595 // received a large objs info request msg
2596 transferMarkResults_I();
2598 } // case GCLOBJREQUEST
2601 // received a large objs info response msg
2602 processmsg_gclobjinfo_I();
2604 } // case GCLOBJINFO
2606 case GCLOBJMAPPING: {
2607 // received a large obj mapping info msg
2608 processmsg_gclobjmapping_I();
2610 } // case GCLOBJMAPPING
2612 #endif // #ifdef MULTICORE_GC
2617 //memset(msgdata, '\0', sizeof(int) * msgdataindex);
2619 msglength = BAMBOO_MSG_BUF_LENGTH;
2621 //printf("++ msg: %x \n", type);
2622 if(msgdataindex != msgdatalast) {
2623 // still have available msg
2628 BAMBOO_DEBUGPRINT(0xe88d);
2632 // have new coming msg
2633 if(BAMBOO_MSG_AVAIL() != 0) {
2647 BAMBOO_DEBUGPRINT(0xe88e);
2651 /* if(isInterrupt) {
2659 int enqueuetasks(struct parameterwrapper *parameter,
2660 struct parameterwrapper *prevptr,
2661 struct ___Object___ *ptr,
2663 int numenterflags) {
2664 void * taskpointerarray[MAXTASKPARAMS];
2666 //int numparams=parameter->task->numParameters;
2667 int numiterators=parameter->task->numTotal-1;
2670 struct taskdescriptor * task=parameter->task;
2672 //this add the object to parameterwrapper
2673 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
2674 numenterflags, enterflags==NULL);
2676 /* Add enqueued object to parameter vector */
2677 taskpointerarray[parameter->slot]=ptr;
2679 /* Reset iterators */
2680 for(j=0; j<numiterators; j++) {
2681 toiReset(¶meter->iterators[j]);
2684 /* Find initial state */
2685 for(j=0; j<numiterators; j++) {
2687 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2688 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2690 /* Need to backtrack */
2691 toiReset(¶meter->iterators[j]);
2695 /* Nothing to enqueue */
2701 /* Enqueue current state */
2703 struct taskparamdescriptor *tpd=
2704 RUNMALLOC(sizeof(struct taskparamdescriptor));
2706 tpd->numParameters=numiterators+1;
2707 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2709 for(j=0; j<=numiterators; j++) {
2710 //store the actual parameters
2711 tpd->parameterArray[j]=taskpointerarray[j];
2714 if ((/*!gencontains(failedtasks, tpd)&&*/
2715 !gencontains(activetasks,tpd))) {
2716 genputtable(activetasks, tpd, tpd);
2718 RUNFREE(tpd->parameterArray);
2722 /* This loop iterates to the next parameter combination */
2723 if (numiterators==0)
2726 for(j=numiterators-1; j<numiterators; j++) {
2728 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2729 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2731 /* Need to backtrack */
2732 toiReset(¶meter->iterators[j]);
2736 /* Nothing more to enqueue */
2744 int enqueuetasks_I(struct parameterwrapper *parameter,
2745 struct parameterwrapper *prevptr,
2746 struct ___Object___ *ptr,
2748 int numenterflags) {
2749 void * taskpointerarray[MAXTASKPARAMS];
2751 //int numparams=parameter->task->numParameters;
2752 int numiterators=parameter->task->numTotal-1;
2757 struct taskdescriptor * task=parameter->task;
2759 //this add the object to parameterwrapper
2760 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2761 numenterflags, enterflags==NULL);
2763 /* Add enqueued object to parameter vector */
2764 taskpointerarray[parameter->slot]=ptr;
2766 /* Reset iterators */
2767 for(j=0; j<numiterators; j++) {
2768 toiReset(¶meter->iterators[j]);
2771 /* Find initial state */
2772 for(j=0; j<numiterators; j++) {
2774 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2775 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2777 /* Need to backtrack */
2778 toiReset(¶meter->iterators[j]);
2782 /* Nothing to enqueue */
2788 /* Enqueue current state */
2790 struct taskparamdescriptor *tpd=
2791 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2793 tpd->numParameters=numiterators+1;
2794 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2796 for(j=0; j<=numiterators; j++) {
2797 //store the actual parameters
2798 tpd->parameterArray[j]=taskpointerarray[j];
2801 if ((/*!gencontains(failedtasks, tpd)&&*/
2802 !gencontains(activetasks,tpd))) {
2803 genputtable_I(activetasks, tpd, tpd);
2805 RUNFREE(tpd->parameterArray);
2809 /* This loop iterates to the next parameter combination */
2810 if (numiterators==0)
2813 for(j=numiterators-1; j<numiterators; j++) {
2815 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2816 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2818 /* Need to backtrack */
2819 toiReset(¶meter->iterators[j]);
2823 /* Nothing more to enqueue */
2837 int containstag(struct ___Object___ *ptr,
2838 struct ___TagDescriptor___ *tag);
2840 #ifndef MULTICORE_GC
2841 void releasewritelock_r(void * lock, void * redirectlock) {
2843 int reallock = (int)lock;
2844 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2847 BAMBOO_DEBUGPRINT(0xe671);
2848 BAMBOO_DEBUGPRINT_REG((int)lock);
2849 BAMBOO_DEBUGPRINT_REG(reallock);
2850 BAMBOO_DEBUGPRINT_REG(targetcore);
2853 if(targetcore == BAMBOO_NUM_OF_CORE) {
2854 BAMBOO_START_CRITICAL_SECTION_LOCK();
2856 BAMBOO_DEBUGPRINT(0xf001);
2858 // reside on this core
2859 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2860 // no locks for this object, something is wrong
2861 BAMBOO_EXIT(0xa011);
2864 struct LockValue * lockvalue = NULL;
2866 BAMBOO_DEBUGPRINT(0xe672);
2868 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2869 lockvalue = (struct LockValue *)rwlock_obj;
2871 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2874 lockvalue->redirectlock = (int)redirectlock;
2876 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2879 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2881 BAMBOO_DEBUGPRINT(0xf000);
2885 // send lock release with redirect info msg
2886 // for 32 bit machine, the size is always 4 words
2887 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
2888 (int)redirectlock, false);
2893 void executetasks() {
2894 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2897 struct ___Object___ * tmpparam = NULL;
2898 struct parameterdescriptor * pd=NULL;
2899 struct parameterwrapper *pw=NULL;
2909 while(hashsize(activetasks)>0) {
2914 BAMBOO_DEBUGPRINT(0xe990);
2917 /* See if there are any active tasks */
2918 //if (hashsize(activetasks)>0) {
2921 #ifdef ACCURATEPROFILE
2922 profileTaskStart("tpd checking");
2926 //clock1 = BAMBOO_GET_EXE_TIME();
2929 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2930 genfreekey(activetasks, currtpd);
2932 numparams=currtpd->task->numParameters;
2933 numtotal=currtpd->task->numTotal;
2935 // clear the lockRedirectTbl
2936 // (TODO, this table should be empty after all locks are released)
2938 /*for(j = 0; j < MAXTASKPARAMS; j++) {
2939 runtime_locks[j].redirectlock = 0;
2940 runtime_locks[j].value = 0;
2942 // get all required locks
2943 runtime_locklen = 0;
2944 // check which locks are needed
2945 for(i = 0; i < numparams; i++) {
2946 void * param = currtpd->parameterArray[i];
2950 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2952 taskpointerarray[i+OFFSET]=param;
2955 if(((struct ___Object___ *)param)->lock == NULL) {
2956 tmplock = (int)param;
2958 tmplock = (int)(((struct ___Object___ *)param)->lock);
2960 // insert into the locks array
2961 for(j = 0; j < runtime_locklen; j++) {
2962 if(runtime_locks[j].value == tmplock) {
2965 } else if(runtime_locks[j].value > tmplock) {
2970 int h = runtime_locklen;
2972 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
2973 runtime_locks[h].value = runtime_locks[h-1].value;
2975 runtime_locks[j].value = tmplock;
2976 runtime_locks[j].redirectlock = (int)param;
2979 } // line 2713: for(i = 0; i < numparams; i++)
2980 // grab these required locks
2982 BAMBOO_DEBUGPRINT(0xe991);
2985 //clock2 = BAMBOO_GET_EXE_TIME();
2987 for(i = 0; i < runtime_locklen; i++) {
2988 int * lock = (int *)(runtime_locks[i].redirectlock);
2990 // require locks for this parameter if it is not a startup object
2992 BAMBOO_DEBUGPRINT_REG((int)lock);
2993 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
2996 BAMBOO_START_CRITICAL_SECTION();
2998 BAMBOO_DEBUGPRINT(0xf001);
3001 //isInterrupt = false;
3004 BAMBOO_WAITING_FOR_LOCK();
3008 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
3012 grount = lockresult;
3022 //isInterrupt = true;
3024 BAMBOO_CLOSE_CRITICAL_SECTION();
3026 BAMBOO_DEBUGPRINT(0xf000);
3031 BAMBOO_DEBUGPRINT(0xe992);
3032 BAMBOO_DEBUGPRINT_REG(lock);
3034 // check if has the lock already
3035 // can not get the lock, try later
3036 // release all grabbed locks for previous parameters
3037 for(j = 0; j < i; ++j) {
3038 lock = (int*)(runtime_locks[j].redirectlock);
3039 releasewritelock(lock);
3041 genputtable(activetasks, currtpd, currtpd);
3042 if(hashsize(activetasks) == 1) {
3043 // only one task right now, wait a little while before next try
3049 #ifdef ACCURATEPROFILE
3050 // fail, set the end of the checkTaskInfo
3057 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3060 clock3 = BAMBOO_GET_EXE_TIME();
3061 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3064 BAMBOO_DEBUGPRINT(0xe993);
3066 /* Make sure that the parameters are still in the queues */
3067 for(i=0; i<numparams; i++) {
3068 void * parameter=currtpd->parameterArray[i];
3072 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3073 classsize[((struct ___Object___ *)parameter)->type]);
3075 tmpparam = (struct ___Object___ *)parameter;
3076 pd=currtpd->task->descriptorarray[i];
3077 pw=(struct parameterwrapper *) pd->queue;
3078 /* Check that object is still in queue */
3080 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3082 BAMBOO_DEBUGPRINT(0xe994);
3083 BAMBOO_DEBUGPRINT_REG(parameter);
3085 // release grabbed locks
3086 for(j = 0; j < runtime_locklen; ++j) {
3087 int * lock = (int *)(runtime_locks[j].redirectlock);
3088 releasewritelock(lock);
3090 RUNFREE(currtpd->parameterArray);
3096 /* Check if the object's flags still meets requirements */
3100 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3101 andmask=pw->intarray[tmpi*2];
3102 checkmask=pw->intarray[tmpi*2+1];
3103 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3109 // flags are never suitable
3110 // remove this obj from the queue
3112 int UNUSED, UNUSED2;
3115 BAMBOO_DEBUGPRINT(0xe995);
3116 BAMBOO_DEBUGPRINT_REG(parameter);
3118 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3119 (int *) &enterflags, &UNUSED, &UNUSED2);
3120 ObjectHashremove(pw->objectset, (int)parameter);
3121 if (enterflags!=NULL)
3122 RUNFREE(enterflags);
3123 // release grabbed locks
3124 for(j = 0; j < runtime_locklen; ++j) {
3125 int * lock = (int *)(runtime_locks[j].redirectlock);
3126 releasewritelock(lock);
3128 RUNFREE(currtpd->parameterArray);
3132 #ifdef ACCURATEPROFILE
3133 // fail, set the end of the checkTaskInfo
3138 } // line 2878: if (!ismet)
3142 /* Check that object still has necessary tags */
3143 for(j=0; j<pd->numbertags; j++) {
3144 int slotid=pd->tagarray[2*j]+numparams;
3145 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3146 if (!containstag(parameter, tagd)) {
3148 BAMBOO_DEBUGPRINT(0xe996);
3151 // release grabbed locks
3153 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3154 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3155 releasewritelock(lock);
3158 RUNFREE(currtpd->parameterArray);
3162 } // line2911: if (!containstag(parameter, tagd))
3163 } // line 2808: for(j=0; j<pd->numbertags; j++)
3165 taskpointerarray[i+OFFSET]=parameter;
3166 } // line 2824: for(i=0; i<numparams; i++)
3168 for(; i<numtotal; i++) {
3169 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3174 /* Actually call task */
3176 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3177 taskpointerarray[1]=NULL;
3180 #ifdef ACCURATEPROFILE
3181 // check finish, set the end of the checkTaskInfo
3184 profileTaskStart(currtpd->task->name);
3188 //clock4 = BAMBOO_GET_EXE_TIME();
3189 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3192 BAMBOO_DEBUGPRINT(0xe997);
3194 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
3197 //clock5 = BAMBOO_GET_EXE_TIME();
3198 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3201 #ifdef ACCURATEPROFILE
3202 // task finish, set the end of the checkTaskInfo
3204 // new a PostTaskInfo for the post-task execution
3205 profileTaskStart("post task execution");
3209 BAMBOO_DEBUGPRINT(0xe998);
3210 BAMBOO_DEBUGPRINT_REG(islock);
3215 BAMBOO_DEBUGPRINT(0xe999);
3217 for(i = 0; i < runtime_locklen; ++i) {
3218 void * ptr = (void *)(runtime_locks[i].redirectlock);
3219 int * lock = (int *)(runtime_locks[i].value);
3221 BAMBOO_DEBUGPRINT_REG((int)ptr);
3222 BAMBOO_DEBUGPRINT_REG((int)lock);
3223 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3225 #ifndef MULTICORE_GC
3226 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3228 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3229 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3230 releasewritelock_r(lock, (int *)redirectlock);
3235 releasewritelock(ptr);
3238 } // line 3015: if(islock)
3241 //clock6 = BAMBOO_GET_EXE_TIME();
3242 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3245 // post task execution finish, set the end of the postTaskInfo
3249 // Free up task parameter descriptor
3250 RUNFREE(currtpd->parameterArray);
3254 BAMBOO_DEBUGPRINT(0xe99a);
3257 //clock7 = BAMBOO_GET_EXE_TIME();
3258 //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));
3261 //} // if (hashsize(activetasks)>0)
3262 } // while(hashsize(activetasks)>0)
3264 BAMBOO_DEBUGPRINT(0xe99b);
3268 /* This function processes an objects tags */
3269 void processtags(struct parameterdescriptor *pd,
3271 struct parameterwrapper *parameter,
3272 int * iteratorcount,
3277 for(i=0; i<pd->numbertags; i++) {
3278 int slotid=pd->tagarray[2*i];
3279 int tagid=pd->tagarray[2*i+1];
3281 if (statusarray[slotid+numparams]==0) {
3282 parameter->iterators[*iteratorcount].istag=1;
3283 parameter->iterators[*iteratorcount].tagid=tagid;
3284 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3285 parameter->iterators[*iteratorcount].tagobjectslot=index;
3286 statusarray[slotid+numparams]=1;
3293 void processobject(struct parameterwrapper *parameter,
3295 struct parameterdescriptor *pd,
3301 struct ObjectHash * objectset=
3302 ((struct parameterwrapper *)pd->queue)->objectset;
3304 parameter->iterators[*iteratorcount].istag=0;
3305 parameter->iterators[*iteratorcount].slot=index;
3306 parameter->iterators[*iteratorcount].objectset=objectset;
3307 statusarray[index]=1;
3309 for(i=0; i<pd->numbertags; i++) {
3310 int slotid=pd->tagarray[2*i];
3311 //int tagid=pd->tagarray[2*i+1];
3312 if (statusarray[slotid+numparams]!=0) {
3313 /* This tag has already been enqueued, use it to narrow search */
3314 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3319 parameter->iterators[*iteratorcount].numtags=tagcount;
3324 /* This function builds the iterators for a task & parameter */
3326 void builditerators(struct taskdescriptor * task,
3328 struct parameterwrapper * parameter) {
3329 int statusarray[MAXTASKPARAMS];
3331 int numparams=task->numParameters;
3332 int iteratorcount=0;
3333 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3335 statusarray[index]=1; /* Initial parameter */
3336 /* Process tags for initial iterator */
3338 processtags(task->descriptorarray[index], index, parameter,
3339 &iteratorcount, statusarray, numparams);
3343 /* Check for objects with existing tags */
3344 for(i=0; i<numparams; i++) {
3345 if (statusarray[i]==0) {
3346 struct parameterdescriptor *pd=task->descriptorarray[i];
3348 for(j=0; j<pd->numbertags; j++) {
3349 int slotid=pd->tagarray[2*j];
3350 if(statusarray[slotid+numparams]!=0) {
3351 processobject(parameter, i, pd, &iteratorcount, statusarray,
3353 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3360 /* Next do objects w/ unbound tags*/
3362 for(i=0; i<numparams; i++) {
3363 if (statusarray[i]==0) {
3364 struct parameterdescriptor *pd=task->descriptorarray[i];
3365 if (pd->numbertags>0) {
3366 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3367 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3373 /* Nothing with a tag enqueued */
3375 for(i=0; i<numparams; i++) {
3376 if (statusarray[i]==0) {
3377 struct parameterdescriptor *pd=task->descriptorarray[i];
3378 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3379 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3392 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3395 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3396 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3398 printf("%s\n", task->name);
3400 for(j=0; j<task->numParameters; j++) {
3401 struct parameterdescriptor *param=task->descriptorarray[j];
3402 struct parameterwrapper *parameter=param->queue;
3403 struct ObjectHash * set=parameter->objectset;
3404 struct ObjectIterator objit;
3406 printf(" Parameter %d\n", j);
3408 ObjectHashiterator(set, &objit);
3409 while(ObjhasNext(&objit)) {
3410 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3411 struct ___Object___ * tagptr=obj->___tags___;
3412 int nonfailed=Objdata4(&objit);
3413 int numflags=Objdata3(&objit);
3414 int flags=Objdata2(&objit);
3417 printf(" Contains %lx\n", obj);
3418 printf(" flag=%d\n", obj->flag);
3421 } else if (tagptr->type==TAGTYPE) {
3423 printf(" tag=%lx\n",tagptr);
3429 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3430 for(; tagindex<ao->___cachedCode___; tagindex++) {
3432 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3445 /* This function processes the task information to create queues for
3446 each parameter type. */
3448 void processtasks() {
3450 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3453 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3454 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3457 /* Build objectsets */
3458 for(j=0; j<task->numParameters; j++) {
3459 struct parameterdescriptor *param=task->descriptorarray[j];
3460 struct parameterwrapper *parameter=param->queue;
3461 parameter->objectset=allocateObjectHash(10);
3462 parameter->task=task;
3465 /* Build iterators for parameters */
3466 for(j=0; j<task->numParameters; j++) {
3467 struct parameterdescriptor *param=task->descriptorarray[j];
3468 struct parameterwrapper *parameter=param->queue;
3469 builditerators(task, j, parameter);
3474 void toiReset(struct tagobjectiterator * it) {
3477 } else if (it->numtags>0) {
3480 ObjectHashiterator(it->objectset, &it->it);
3484 int toiHasNext(struct tagobjectiterator *it,
3485 void ** objectarray OPTARG(int * failed)) {
3488 /* Get object with tags */
3489 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3490 struct ___Object___ *tagptr=obj->___tags___;
3491 if (tagptr->type==TAGTYPE) {
3492 if ((it->tagobjindex==0)&& /* First object */
3493 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3498 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3499 int tagindex=it->tagobjindex;
3500 for(; tagindex<ao->___cachedCode___; tagindex++) {
3501 struct ___TagDescriptor___ *td=
3502 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3503 if (td->flag==it->tagid) {
3504 it->tagobjindex=tagindex; /* Found right type of tag */
3510 } else if (it->numtags>0) {
3511 /* Use tags to locate appropriate objects */
3512 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3513 struct ___Object___ *objptr=tag->flagptr;
3515 if (objptr->type!=OBJECTARRAYTYPE) {
3516 if (it->tagobjindex>0)
3518 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3520 for(i=1; i<it->numtags; i++) {
3521 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3522 if (!containstag(objptr,tag2))
3527 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3530 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
3531 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3532 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3534 for(i=1; i<it->numtags; i++) {
3535 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3536 if (!containstag(objptr,tag2))
3539 it->tagobjindex=tagindex;
3544 it->tagobjindex=tagindex;
3548 return ObjhasNext(&it->it);
3552 int containstag(struct ___Object___ *ptr,
3553 struct ___TagDescriptor___ *tag) {
3555 struct ___Object___ * objptr=tag->flagptr;
3556 if (objptr->type==OBJECTARRAYTYPE) {
3557 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3558 for(j=0; j<ao->___cachedCode___; j++) {
3559 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3569 void toiNext(struct tagobjectiterator *it,
3570 void ** objectarray OPTARG(int * failed)) {
3571 /* hasNext has all of the intelligence */
3574 /* Get object with tags */
3575 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3576 struct ___Object___ *tagptr=obj->___tags___;
3577 if (tagptr->type==TAGTYPE) {
3579 objectarray[it->slot]=tagptr;
3581 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3582 objectarray[it->slot]=
3583 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3585 } else if (it->numtags>0) {
3586 /* Use tags to locate appropriate objects */
3587 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3588 struct ___Object___ *objptr=tag->flagptr;
3589 if (objptr->type!=OBJECTARRAYTYPE) {
3591 objectarray[it->slot]=objptr;
3593 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3594 objectarray[it->slot]=
3595 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3598 /* Iterate object */
3599 objectarray[it->slot]=(void *)Objkey(&it->it);
3605 inline void profileTaskStart(char * taskname) {
3606 if(!taskInfoOverflow) {
3607 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
3608 taskInfoArray[taskInfoIndex] = taskInfo;
3609 taskInfo->taskName = taskname;
3610 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
3611 taskInfo->endTime = -1;
3612 taskInfo->exitIndex = -1;
3613 taskInfo->newObjs = NULL;
3617 inline void profileTaskEnd() {
3618 if(!taskInfoOverflow) {
3619 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
3621 if(taskInfoIndex == TASKINFOLENGTH) {
3622 taskInfoOverflow = true;
3623 //taskInfoIndex = 0;
3628 // output the profiling data
3629 void outputProfileData() {
3632 unsigned long long totaltasktime = 0;
3633 unsigned long long preprocessingtime = 0;
3634 unsigned long long objqueuecheckingtime = 0;
3635 unsigned long long postprocessingtime = 0;
3636 //int interruptiontime = 0;
3637 unsigned long long other = 0;
3638 unsigned long long averagetasktime = 0;
3641 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
3642 // output task related info
3643 for(i = 0; i < taskInfoIndex; i++) {
3644 TaskInfo* tmpTInfo = taskInfoArray[i];
3645 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
3646 printf("%s, %lld, %lld, %lld, %lld",
3647 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
3648 duration, tmpTInfo->exitIndex);
3649 // summarize new obj info
3650 if(tmpTInfo->newObjs != NULL) {
3651 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3652 struct RuntimeIterator * iter = NULL;
3653 while(0 == isEmpty(tmpTInfo->newObjs)) {
3654 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3655 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3657 RuntimeHashget(nobjtbl, (int)objtype, &num);
3658 RuntimeHashremovekey(nobjtbl, (int)objtype);
3660 RuntimeHashadd(nobjtbl, (int)objtype, num);
3662 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3664 //printf(stderr, "new obj!\n");
3667 // output all new obj info
3668 iter = RuntimeHashcreateiterator(nobjtbl);
3669 while(RunhasNext(iter)) {
3670 char * objtype = (char *)Runkey(iter);
3671 int num = Runnext(iter);
3672 printf(", %s, %d", objtype, num);
3676 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
3677 preprocessingtime += duration;
3678 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
3679 postprocessingtime += duration;
3680 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
3681 objqueuecheckingtime += duration;
3683 totaltasktime += duration;
3684 averagetasktime += duration;
3689 if(taskInfoOverflow) {
3690 printf("Caution: task info overflow!\n");
3693 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
3694 averagetasktime /= tasknum;
3696 printf("\nTotal time: %lld\n", totalexetime);
3697 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
3698 (int)(((double)totaltasktime/(double)totalexetime)*100));
3699 printf("Total objqueue checking time: %lld (%d%%)\n",
3700 objqueuecheckingtime,
3701 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
3702 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
3703 (int)(((double)preprocessingtime/(double)totalexetime)*100));
3704 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
3705 (int)(((double)postprocessingtime/(double)totalexetime)*100));
3706 printf("Other time: %lld (%d%%)\n", other,
3707 (int)(((double)other/(double)totalexetime)*100));
3709 printf("\nAverage task execution time: %lld\n", averagetasktime);
3714 BAMBOO_DEBUGPRINT(0xdddd);
3715 // output task related info
3716 for(i= 0; i < taskInfoIndex; i++) {
3717 TaskInfo* tmpTInfo = taskInfoArray[i];
3718 char* tmpName = tmpTInfo->taskName;
3719 int nameLen = strlen(tmpName);
3720 BAMBOO_DEBUGPRINT(0xddda);
3721 for(j = 0; j < nameLen; j++) {
3722 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
3724 BAMBOO_DEBUGPRINT(0xdddb);
3725 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
3726 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
3727 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
3728 if(tmpTInfo->newObjs != NULL) {
3729 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3730 struct RuntimeIterator * iter = NULL;
3731 while(0 == isEmpty(tmpTInfo->newObjs)) {
3732 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3733 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3735 RuntimeHashget(nobjtbl, (int)objtype, &num);
3736 RuntimeHashremovekey(nobjtbl, (int)objtype);
3738 RuntimeHashadd(nobjtbl, (int)objtype, num);
3740 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3744 // ouput all new obj info
3745 iter = RuntimeHashcreateiterator(nobjtbl);
3746 while(RunhasNext(iter)) {
3747 char * objtype = (char *)Runkey(iter);
3748 int num = Runnext(iter);
3749 int nameLen = strlen(objtype);
3750 BAMBOO_DEBUGPRINT(0xddda);
3751 for(j = 0; j < nameLen; j++) {
3752 BAMBOO_DEBUGPRINT_REG(objtype[j]);
3754 BAMBOO_DEBUGPRINT(0xdddb);
3755 BAMBOO_DEBUGPRINT_REG(num);
3758 BAMBOO_DEBUGPRINT(0xdddc);
3761 if(taskInfoOverflow) {
3762 BAMBOO_DEBUGPRINT(0xefee);
3765 // output interrupt related info
3766 /*for(i = 0; i < interruptInfoIndex; i++) {
3767 InterruptInfo* tmpIInfo = interruptInfoArray[i];
3768 BAMBOO_DEBUGPRINT(0xddde);
3769 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
3770 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
3771 BAMBOO_DEBUGPRINT(0xdddf);
3774 if(interruptInfoOverflow) {
3775 BAMBOO_DEBUGPRINT(0xefef);
3778 BAMBOO_DEBUGPRINT(0xeeee);
3781 #endif // #ifdef PROFILE