3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5 #include "GenericHashtable.h"
8 #define INLINE inline __attribute__((always_inline))
9 #endif // #ifndef INLINE
11 // data structures for task invocation
12 struct genhashtable * activetasks;
13 struct taskparamdescriptor * currtpd;
14 struct LockValue runtime_locks[MAXTASKPARAMS];
17 // specific functions used inside critical sections
18 void enqueueObject_I(void * ptr,
19 struct parameterwrapper ** queues,
21 int enqueuetasks_I(struct parameterwrapper *parameter,
22 struct parameterwrapper *prevptr,
23 struct ___Object___ *ptr,
28 inline __attribute__((always_inline))
29 void setupsmemmode(void) {
31 bamboo_smem_mode = SMEMLOCAL;
33 bamboo_smem_mode = SMEMFIXED;
35 bamboo_smem_mode = SMEMMIXED;
37 bamboo_smem_mode = SMEMGLOBAL;
39 // defaultly using local mode
40 //bamboo_smem_mode = SMEMLOCAL;
41 bamboo_smem_mode = SMEMGLOBAL;
43 } // void setupsmemmode(void)
46 inline __attribute__((always_inline))
47 void initruntimedata() {
49 // initialize the arrays
50 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
51 // startup core to initialize corestatus[]
52 for(i = 0; i < NUMCORESACTIVE; ++i) {
55 numreceiveobjs[i] = 0;
57 // initialize the profile data arrays
63 gcnumreceiveobjs[i] = 0;
65 } // for(i = 0; i < NUMCORESACTIVE; ++i)
67 for(i = 0; i < NUMCORES4GC; ++i) {
69 gcrequiredmems[i] = 0;
71 gcfilledblocks[i] = 0;
72 } // for(i = 0; i < NUMCORES4GC; ++i)
75 gc_infoOverflow = false;
87 self_numreceiveobjs = 0;
89 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
94 msglength = BAMBOO_MSG_BUF_LENGTH;
96 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
102 isMsgHanging = false;
103 //isMsgSending = false;
106 bamboo_cur_msp = NULL;
107 bamboo_smem_size = 0;
108 totransobjqueue = createQueue_I();
112 gcprocessing = false;
113 gcphase = FINISHPHASE;
115 gcself_numsendobjs = 0;
116 gcself_numreceiveobjs = 0;
117 gcmarkedptrbound = 0;
118 //mgchashCreate(2000, 0.75);
119 gcpointertbl = allocateRuntimeHash_I(20);
120 //gcpointertbl = allocateMGCHash(20);
121 gcforwardobjtbl = allocateMGCHash_I(20, 3);
133 gcsbstarttbl = BAMBOO_BASE_VA;
134 bamboo_smemtbl = (void *)gcsbstarttbl
135 + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
137 // create the lock table, lockresult table and obj queue
140 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
141 /* Set allocation blocks*/
142 locktable.listhead=NULL;
143 locktable.listtail=NULL;
145 locktable.numelements = 0;
150 lockRedirectTbl = allocateRuntimeHash_I(20);
151 objRedirectLockTbl = allocateRuntimeHash_I(20);
156 objqueue.head = NULL;
157 objqueue.tail = NULL;
163 //isInterrupt = true;
167 taskInfoOverflow = false;
169 interruptInfoIndex = 0;
170 interruptInfoOverflow = false;
173 for(i = 0; i < MAXTASKPARAMS; i++) {
174 runtime_locks[i].redirectlock = 0;
175 runtime_locks[i].value = 0;
180 inline __attribute__((always_inline))
181 void disruntimedata() {
184 freeRuntimeHash(gcpointertbl);
185 //freeMGCHash(gcpointertbl);
186 freeMGCHash(gcforwardobjtbl);
188 freeRuntimeHash(lockRedirectTbl);
189 freeRuntimeHash(objRedirectLockTbl);
190 RUNFREE(locktable.bucket);
192 if(activetasks != NULL) {
193 genfreehashtable(activetasks);
195 if(currtpd != NULL) {
196 RUNFREE(currtpd->parameterArray);
200 BAMBOO_LOCAL_MEM_CLOSE();
201 BAMBOO_SHARE_MEM_CLOSE();
204 inline __attribute__((always_inline))
205 bool checkObjQueue() {
207 struct transObjInfo * objInfo = NULL;
211 #ifdef ACCURATEPROFILE
212 bool isChecking = false;
213 if(!isEmpty(&objqueue)) {
214 profileTaskStart("objqueue checking");
216 } // if(!isEmpty(&objqueue))
220 while(!isEmpty(&objqueue)) {
222 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
224 BAMBOO_DEBUGPRINT(0xf001);
227 //isInterrupt = false;
230 BAMBOO_DEBUGPRINT(0xeee1);
233 objInfo = (struct transObjInfo *)getItem(&objqueue);
234 obj = objInfo->objptr;
236 BAMBOO_DEBUGPRINT_REG((int)obj);
238 // grab lock and flush the obj
242 BAMBOO_WAITING_FOR_LOCK(0);
243 // check for outgoing sends
244 /*if (isMsgHanging) {
245 extern inline void send_hanging_msg(bool);
246 send_hanging_msg(true);
248 } // while(!lockflag)
251 BAMBOO_DEBUGPRINT_REG(grount);
266 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
267 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
268 classsize[((struct ___Object___ *)obj)->type]);
270 // enqueue the object
271 for(k = 0; k < objInfo->length; ++k) {
272 int taskindex = objInfo->queues[2 * k];
273 int paramindex = objInfo->queues[2 * k + 1];
274 struct parameterwrapper ** queues =
275 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
277 BAMBOO_DEBUGPRINT_REG(taskindex);
278 BAMBOO_DEBUGPRINT_REG(paramindex);
279 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
280 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
281 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
282 (long)obj, tmpptr->flag);
284 enqueueObject_I(obj, queues, 1);
286 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
288 } // for(k = 0; k < objInfo->length; ++k)
289 releasewritelock_I(obj);
290 RUNFREE(objInfo->queues);
294 // put it at the end of the queue if no update version in the queue
295 struct QueueItem * qitem = getHead(&objqueue);
296 struct QueueItem * prev = NULL;
297 while(qitem != NULL) {
298 struct transObjInfo * tmpinfo =
299 (struct transObjInfo *)(qitem->objectptr);
300 if(tmpinfo->objptr == obj) {
301 // the same object in the queue, which should be enqueued
302 // recently. Current one is outdate, do not re-enqueue it
303 RUNFREE(objInfo->queues);
308 } // if(tmpinfo->objptr == obj)
309 qitem = getNextQueueItem(prev);
310 } // while(qitem != NULL)
311 // try to execute active tasks already enqueued first
312 addNewItem_I(&objqueue, objInfo);
314 //isInterrupt = true;
317 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
319 BAMBOO_DEBUGPRINT(0xf000);
323 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
325 BAMBOO_DEBUGPRINT(0xf000);
327 } // while(!isEmpty(&objqueue))
330 #ifdef ACCURATEPROFILE
338 BAMBOO_DEBUGPRINT(0xee02);
343 inline __attribute__((always_inline))
344 void checkCoreStatus() {
345 bool allStall = false;
349 (waitconfirm && (numconfirm == 0))) {
351 BAMBOO_DEBUGPRINT(0xee04);
352 BAMBOO_DEBUGPRINT_REG(waitconfirm);
354 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
356 BAMBOO_DEBUGPRINT(0xf001);
358 corestatus[BAMBOO_NUM_OF_CORE] = 0;
359 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
360 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
361 // check the status of all cores
364 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
366 for(i = 0; i < NUMCORESACTIVE; ++i) {
368 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
370 if(corestatus[i] != 0) {
374 } // for(i = 0; i < NUMCORESACTIVE; ++i)
376 // check if the sum of send objs and receive obj are the same
377 // yes->check if the info is the latest; no->go on executing
379 for(i = 0; i < NUMCORESACTIVE; ++i) {
380 sumsendobj += numsendobjs[i];
382 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
384 } // for(i = 0; i < NUMCORESACTIVE; ++i)
385 for(i = 0; i < NUMCORESACTIVE; ++i) {
386 sumsendobj -= numreceiveobjs[i];
388 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
390 } // for(i = 0; i < NUMCORESACTIVE; ++i)
391 if(0 == sumsendobj) {
393 // the first time found all cores stall
394 // send out status confirm msg to all other cores
395 // reset the corestatus array too
397 BAMBOO_DEBUGPRINT(0xee05);
399 corestatus[BAMBOO_NUM_OF_CORE] = 1;
401 numconfirm = NUMCORESACTIVE - 1;
402 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
403 for(i = 1; i < NUMCORESACTIVE; ++i) {
405 // send status confirm msg to core i
406 send_msg_1(i, STATUSCONFIRM, false);
407 } // for(i = 1; i < NUMCORESACTIVE; ++i)
410 // all the core status info are the latest
411 // terminate; for profiling mode, send request to all
412 // other cores to pour out profiling data
414 BAMBOO_DEBUGPRINT(0xee06);
418 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
421 //BAMBOO_DEBUGPRINT_REG(interrupttime);
424 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
425 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
426 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
428 // profile mode, send msgs to other cores to request pouring
429 // out progiling data
431 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
433 BAMBOO_DEBUGPRINT(0xf000);
435 for(i = 1; i < NUMCORESACTIVE; ++i) {
436 // send profile request msg to core i
437 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
438 } // for(i = 1; i < NUMCORESACTIVE; ++i)
439 // pour profiling data on startup core
442 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
444 BAMBOO_DEBUGPRINT(0xf001);
446 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
447 // check the status of all cores
450 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
452 for(i = 0; i < NUMCORESACTIVE; ++i) {
454 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
456 if(profilestatus[i] != 0) {
460 } // for(i = 0; i < NUMCORESACTIVE; ++i)
463 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
465 BAMBOO_DEBUGPRINT(0xf000);
470 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
476 // gc_profile mode, ourput gc prfiling data
479 gc_outputProfileData();
480 #endif // #ifdef GC_PROFILE
481 #endif // #ifdef MULTICORE_GC
483 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
484 terminate(); // All done.
485 } // if(!waitconfirm)
487 // still some objects on the fly on the network
488 // reset the waitconfirm and numconfirm
490 BAMBOO_DEBUGPRINT(0xee07);
494 } // if(0 == sumsendobj)
496 // not all cores are stall, keep on waiting
498 BAMBOO_DEBUGPRINT(0xee08);
503 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
505 BAMBOO_DEBUGPRINT(0xf000);
507 } // if((!waitconfirm) ||
510 // main function for each core
511 inline void run(void * arg) {
515 bool sendStall = false;
517 bool tocontinue = false;
519 corenum = BAMBOO_GET_NUM_OF_CORE();
521 BAMBOO_DEBUGPRINT(0xeeee);
522 BAMBOO_DEBUGPRINT_REG(corenum);
523 BAMBOO_DEBUGPRINT(STARTUPCORE);
526 // initialize runtime data structures
529 // other architecture related initialization
533 initializeexithandler();
535 // main process of the execution module
536 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
537 // non-executing cores, only processing communications
540 BAMBOO_DEBUGPRINT(0xee01);
541 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
542 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
543 profileTaskStart("msg handling");
547 //isInterrupt = false;
551 /* Create queue of active tasks */
553 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
554 (int (*)(void *,void *)) &comparetpd);
556 /* Process task information */
559 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
560 /* Create startup object */
561 createstartupobject(argc, argv);
565 BAMBOO_DEBUGPRINT(0xee00);
570 // check if need to do GC
574 // check if there are new active tasks can be executed
581 while(receiveObject() != -1) {
586 BAMBOO_DEBUGPRINT(0xee01);
589 // check if there are some pending objects,
590 // if yes, enqueue them and executetasks again
591 tocontinue = checkObjQueue();
595 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
598 BAMBOO_DEBUGPRINT(0xee03);
606 BAMBOO_DEBUGPRINT(0xee09);
612 // wait for some time
615 BAMBOO_DEBUGPRINT(0xee0a);
621 // send StallMsg to startup core
623 BAMBOO_DEBUGPRINT(0xee0b);
626 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
627 self_numsendobjs, self_numreceiveobjs, false);
639 BAMBOO_DEBUGPRINT(0xee0c);
642 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
645 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
649 struct ___createstartupobject____I_locals {
652 struct ___StartupObject___ * ___startupobject___;
653 struct ArrayObject * ___stringarray___;
654 }; // struct ___createstartupobject____I_locals
656 void createstartupobject(int argc,
660 /* Allocate startup object */
662 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
663 struct ___StartupObject___ *startupobject=
664 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
665 ___locals___.___startupobject___ = startupobject;
666 struct ArrayObject * stringarray=
667 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
668 ___locals___.___stringarray___ = stringarray;
670 struct ___StartupObject___ *startupobject=
671 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
672 struct ArrayObject * stringarray=
673 allocate_newarray(STRINGARRAYTYPE, argc-1);
675 /* Build array of strings */
676 startupobject->___parameters___=stringarray;
677 for(i=1; i<argc; i++) {
678 int length=strlen(argv[i]);
680 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
682 struct ___String___ *newstring=NewString(argv[i],length);
684 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
688 startupobject->version = 0;
689 startupobject->lock = NULL;
691 /* Set initialized flag for startup object */
692 flagorandinit(startupobject,1,0xFFFFFFFF);
693 enqueueObject(startupobject, NULL, 0);
695 BAMBOO_CACHE_FLUSH_ALL();
699 int hashCodetpd(struct taskparamdescriptor *ftd) {
700 int hash=(int)ftd->task;
702 for(i=0; i<ftd->numParameters; i++) {
703 hash^=(int)ftd->parameterArray[i];
708 int comparetpd(struct taskparamdescriptor *ftd1,
709 struct taskparamdescriptor *ftd2) {
711 if (ftd1->task!=ftd2->task)
713 for(i=0; i<ftd1->numParameters; i++)
714 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
719 /* This function sets a tag. */
721 void tagset(void *ptr,
722 struct ___Object___ * obj,
723 struct ___TagDescriptor___ * tagd) {
725 void tagset(struct ___Object___ * obj,
726 struct ___TagDescriptor___ * tagd) {
728 struct ArrayObject * ao=NULL;
729 struct ___Object___ * tagptr=obj->___tags___;
731 obj->___tags___=(struct ___Object___ *)tagd;
733 /* Have to check if it is already set */
734 if (tagptr->type==TAGTYPE) {
735 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
740 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
741 struct ArrayObject * ao=
742 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
743 obj=(struct ___Object___ *)ptrarray[2];
744 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
745 td=(struct ___TagDescriptor___ *) obj->___tags___;
747 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
750 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
751 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
752 obj->___tags___=(struct ___Object___ *) ao;
753 ao->___cachedCode___=2;
757 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
758 for(i=0; i<ao->___cachedCode___; i++) {
759 struct ___TagDescriptor___ * td=
760 ARRAYGET(ao, struct ___TagDescriptor___*, i);
765 if (ao->___cachedCode___<ao->___length___) {
766 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
767 ao->___cachedCode___++;
770 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
771 struct ArrayObject * aonew=
772 allocate_newarray(&ptrarray,TAGARRAYTYPE,
773 TAGARRAYINTERVAL+ao->___length___);
774 obj=(struct ___Object___ *)ptrarray[2];
775 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
776 ao=(struct ArrayObject *)obj->___tags___;
778 struct ArrayObject * aonew=
779 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
782 aonew->___cachedCode___=ao->___length___+1;
783 for(i=0; i<ao->___length___; i++) {
784 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
785 ARRAYGET(ao, struct ___TagDescriptor___*, i));
787 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
793 struct ___Object___ * tagset=tagd->flagptr;
796 } else if (tagset->type!=OBJECTARRAYTYPE) {
798 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
799 struct ArrayObject * ao=
800 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
801 obj=(struct ___Object___ *)ptrarray[2];
802 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
804 struct ArrayObject * ao=
805 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
807 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
808 ARRAYSET(ao, struct ___Object___ *, 1, obj);
809 ao->___cachedCode___=2;
810 tagd->flagptr=(struct ___Object___ *)ao;
812 struct ArrayObject *ao=(struct ArrayObject *) tagset;
813 if (ao->___cachedCode___<ao->___length___) {
814 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
818 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
819 struct ArrayObject * aonew=
820 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
821 OBJECTARRAYINTERVAL+ao->___length___);
822 obj=(struct ___Object___ *)ptrarray[2];
823 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
824 ao=(struct ArrayObject *)tagd->flagptr;
826 struct ArrayObject * aonew=
827 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
829 aonew->___cachedCode___=ao->___cachedCode___+1;
830 for(i=0; i<ao->___length___; i++) {
831 ARRAYSET(aonew, struct ___Object___*, i,
832 ARRAYGET(ao, struct ___Object___*, i));
834 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
835 tagd->flagptr=(struct ___Object___ *) aonew;
841 /* This function clears a tag. */
843 void tagclear(void *ptr,
844 struct ___Object___ * obj,
845 struct ___TagDescriptor___ * tagd) {
847 void tagclear(struct ___Object___ * obj,
848 struct ___TagDescriptor___ * tagd) {
850 /* We'll assume that tag is alway there.
851 Need to statically check for this of course. */
852 struct ___Object___ * tagptr=obj->___tags___;
854 if (tagptr->type==TAGTYPE) {
855 if ((struct ___TagDescriptor___ *)tagptr==tagd)
856 obj->___tags___=NULL;
858 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
860 for(i=0; i<ao->___cachedCode___; i++) {
861 struct ___TagDescriptor___ * td=
862 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
864 ao->___cachedCode___--;
865 if (i<ao->___cachedCode___)
866 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
867 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
868 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
869 if (ao->___cachedCode___==0)
870 obj->___tags___=NULL;
877 struct ___Object___ *tagset=tagd->flagptr;
878 if (tagset->type!=OBJECTARRAYTYPE) {
882 struct ArrayObject *ao=(struct ArrayObject *) tagset;
884 for(i=0; i<ao->___cachedCode___; i++) {
885 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
887 ao->___cachedCode___--;
888 if (i<ao->___cachedCode___)
889 ARRAYSET(ao, struct ___Object___ *, i,
890 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
891 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
892 if (ao->___cachedCode___==0)
903 /* This function allocates a new tag. */
905 struct ___TagDescriptor___ * allocate_tag(void *ptr,
907 struct ___TagDescriptor___ * v=
908 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
911 struct ___TagDescriptor___ * allocate_tag(int index) {
912 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
921 /* This function updates the flag for object ptr. It or's the flag
922 with the or mask and and's it with the andmask. */
924 void flagbody(struct ___Object___ *ptr,
926 struct parameterwrapper ** queues,
930 int flagcomp(const int *val1, const int *val2) {
931 return (*val1)-(*val2);
934 void flagorand(void * ptr,
937 struct parameterwrapper ** queues,
940 int oldflag=((int *)ptr)[1];
941 int flag=ormask|oldflag;
943 flagbody(ptr, flag, queues, length, false);
947 bool intflagorand(void * ptr,
951 int oldflag=((int *)ptr)[1];
952 int flag=ormask|oldflag;
954 if (flag==oldflag) /* Don't do anything */
957 flagbody(ptr, flag, NULL, 0, false);
963 void flagorandinit(void * ptr,
966 int oldflag=((int *)ptr)[1];
967 int flag=ormask|oldflag;
969 flagbody(ptr,flag,NULL,0,true);
972 void flagbody(struct ___Object___ *ptr,
974 struct parameterwrapper ** vqueues,
977 struct parameterwrapper * flagptr = NULL;
979 struct parameterwrapper ** queues = vqueues;
980 int length = vlength;
983 int * enterflags = NULL;
984 if((!isnew) && (queues == NULL)) {
985 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
986 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
987 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
994 /*Remove object from all queues */
995 for(i = 0; i < length; ++i) {
997 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
998 (int *) &enterflags, &UNUSED, &UNUSED2);
999 ObjectHashremove(flagptr->objectset, (int)ptr);
1000 if (enterflags!=NULL)
1001 RUNFREE(enterflags);
1005 void enqueueObject(void * vptr,
1006 struct parameterwrapper ** vqueues,
1008 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1011 //struct QueueItem *tmpptr;
1012 struct parameterwrapper * parameter=NULL;
1015 struct parameterwrapper * prevptr=NULL;
1016 struct ___Object___ *tagptr=NULL;
1017 struct parameterwrapper ** queues = vqueues;
1018 int length = vlength;
1019 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1022 if(queues == NULL) {
1023 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1024 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1026 tagptr=ptr->___tags___;
1028 /* Outer loop iterates through all parameter queues an object of
1029 this type could be in. */
1030 for(j = 0; j < length; ++j) {
1031 parameter = queues[j];
1033 if (parameter->numbertags>0) {
1035 goto nextloop; //that means the object has no tag
1036 //but that param needs tag
1037 else if(tagptr->type==TAGTYPE) { //one tag
1038 //struct ___TagDescriptor___ * tag=
1039 //(struct ___TagDescriptor___*) tagptr;
1040 for(i=0; i<parameter->numbertags; i++) {
1041 //slotid is parameter->tagarray[2*i];
1042 int tagid=parameter->tagarray[2*i+1];
1043 if (tagid!=tagptr->flag)
1044 goto nextloop; /*We don't have this tag */
1046 } else { //multiple tags
1047 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1048 for(i=0; i<parameter->numbertags; i++) {
1049 //slotid is parameter->tagarray[2*i];
1050 int tagid=parameter->tagarray[2*i+1];
1052 for(j=0; j<ao->___cachedCode___; j++) {
1053 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1064 for(i=0; i<parameter->numberofterms; i++) {
1065 int andmask=parameter->intarray[i*2];
1066 int checkmask=parameter->intarray[i*2+1];
1067 if ((ptr->flag&andmask)==checkmask) {
1068 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1079 void enqueueObject_I(void * vptr,
1080 struct parameterwrapper ** vqueues,
1082 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1085 //struct QueueItem *tmpptr;
1086 struct parameterwrapper * parameter=NULL;
1089 struct parameterwrapper * prevptr=NULL;
1090 struct ___Object___ *tagptr=NULL;
1091 struct parameterwrapper ** queues = vqueues;
1092 int length = vlength;
1093 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1096 if(queues == NULL) {
1097 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1098 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1100 tagptr=ptr->___tags___;
1102 /* Outer loop iterates through all parameter queues an object of
1103 this type could be in. */
1104 for(j = 0; j < length; ++j) {
1105 parameter = queues[j];
1107 if (parameter->numbertags>0) {
1109 goto nextloop; //that means the object has no tag
1110 //but that param needs tag
1111 else if(tagptr->type==TAGTYPE) { //one tag
1112 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1113 for(i=0; i<parameter->numbertags; i++) {
1114 //slotid is parameter->tagarray[2*i];
1115 int tagid=parameter->tagarray[2*i+1];
1116 if (tagid!=tagptr->flag)
1117 goto nextloop; /*We don't have this tag */
1119 } else { //multiple tags
1120 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1121 for(i=0; i<parameter->numbertags; i++) {
1122 //slotid is parameter->tagarray[2*i];
1123 int tagid=parameter->tagarray[2*i+1];
1125 for(j=0; j<ao->___cachedCode___; j++) {
1126 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1137 for(i=0; i<parameter->numberofterms; i++) {
1138 int andmask=parameter->intarray[i*2];
1139 int checkmask=parameter->intarray[i*2+1];
1140 if ((ptr->flag&andmask)==checkmask) {
1141 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1153 int * getAliasLock(void ** ptrs,
1155 struct RuntimeHash * tbl) {
1157 return (int*)(RUNMALLOC(sizeof(int)));
1162 bool redirect = false;
1163 int redirectlock = 0;
1164 for(; i < length; i++) {
1165 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1168 if(ptr->lock == NULL) {
1171 lock = (int)(ptr->lock);
1174 if(lock != redirectlock) {
1175 RuntimeHashadd(tbl, lock, redirectlock);
1178 if(RuntimeHashcontainskey(tbl, lock)) {
1179 // already redirected
1181 RuntimeHashget(tbl, lock, &redirectlock);
1182 for(; j < locklen; j++) {
1183 if(locks[j] != redirectlock) {
1184 RuntimeHashadd(tbl, locks[j], redirectlock);
1189 for(j = 0; j < locklen; j++) {
1190 if(locks[j] == lock) {
1193 } else if(locks[j] > lock) {
1200 locks[h] = locks[h-1];
1209 return (int *)redirectlock;
1211 return (int *)(locks[0]);
1216 void addAliasLock(void * ptr,
1218 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1219 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1220 // originally no alias lock associated or have a different alias lock
1221 // flush it as the new one
1222 obj->lock = (int *)lock;
1227 inline void setTaskExitIndex(int index) {
1228 taskInfoArray[taskInfoIndex]->exitIndex = index;
1231 inline void addNewObjInfo(void * nobj) {
1232 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1233 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1235 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1240 void * localmalloc_I(int coren,
1246 int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1247 int totest = tofindb;
1248 int bound = BAMBOO_SMEM_SIZE_L;
1252 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1253 int nsize = bamboo_smemtbl[totest];
1254 bool islocal = true;
1256 bool tocheck = true;
1257 // have some space in the block
1258 if(totest == tofindb) {
1259 // the first partition
1260 size = bound - nsize;
1261 } else if(nsize == 0) {
1262 // an empty partition, can be appended
1265 // not an empty partition, can not be appended
1266 // the last continuous block is not big enough, go to check the next
1270 } // if(totest == tofindb) else if(nsize == 0) else ...
1273 // have enough space in the block, malloc
1277 // no enough space yet, try to append next continuous block
1279 } // if(size > isize) else ...
1281 } // if(nsize < bound)
1283 // no space in the block, go to check the next block
1289 tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1292 } // if(islocal) else ...
1293 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1294 // no more local mem, do not find suitable block
1297 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1300 if(foundsmem == 1) {
1301 // find suitable block
1302 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1303 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1304 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1306 // set bamboo_smemtbl
1307 for(i = tofindb; i <= totest; i++) {
1308 bamboo_smemtbl[i]=(i<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1310 } else if(foundsmem == 2) {
1311 // no suitable block
1316 } // void * localmalloc_I(int, int, int *)
1318 void * globalmalloc_I(int coren,
1322 int tofindb = bamboo_free_block; //0;
1323 int totest = tofindb;
1324 int bound = BAMBOO_SMEM_SIZE_L;
1327 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1332 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1333 int nsize = bamboo_smemtbl[totest];
1334 bool isnext = false;
1336 bool tocheck = true;
1337 // have some space in the block
1338 if(totest == tofindb) {
1339 // the first partition
1340 size = bound - nsize;
1341 } else if(nsize == 0) {
1342 // an empty partition, can be appended
1345 // not an empty partition, can not be appended
1346 // the last continuous block is not big enough, start another block
1349 } // if(totest == tofindb) else if(nsize == 0) else ...
1352 // have enough space in the block, malloc
1355 } // if(size > isize)
1359 } // if(nsize < bound) else ...
1361 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1362 // no more local mem, do not find suitable block
1365 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1367 // start another block
1372 if(foundsmem == 1) {
1373 // find suitable block
1374 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1375 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1376 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1378 // set bamboo_smemtbl
1379 for(int i = tofindb; i <= totest; i++) {
1380 bamboo_smemtbl[i]=(i<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1382 if(tofindb == bamboo_free_block) {
1383 bamboo_free_block = totest+1;
1385 } else if(foundsmem == 2) {
1386 // no suitable block
1392 } // void * globalmalloc_I(int, int, int *)
1393 #endif // #ifdef MULTICORE_GC
1395 // malloc from the shared memory
1396 void * smemalloc_I(int coren,
1401 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1403 // go through the bamboo_smemtbl for suitable partitions
1404 switch(bamboo_smem_mode) {
1406 mem = localmalloc_I(coren, isize, allocsize);
1411 // TODO not supported yet
1412 BAMBOO_EXIT(0xe001);
1417 // TODO not supported yet
1418 BAMBOO_EXIT(0xe002);
1423 mem = globalmalloc_I(coren, isize, allocsize);
1435 /*if(!interruptInfoOverflow) {
1436 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1437 interruptInfoArray[interruptInfoIndex] = intInfo;
1438 intInfo->startTime = BAMBOO_GET_EXE_TIME();
1439 intInfo->endTime = -1;
1442 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1443 //mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1444 if(toallocate > bamboo_free_smem_size) {
1448 mem = (void *)bamboo_free_smemp;
1449 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1450 bamboo_free_smem_size -= toallocate;
1451 //BAMBOO_MEMSET_WH(mem, '\0', toallocate);
1453 *allocsize = toallocate;
1455 /*if(!interruptInfoOverflow) {
1456 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1457 interruptInfoIndex++;
1458 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1459 interruptInfoOverflow = true;
1464 #endif // MULTICORE_GC
1465 // no enough shared global memory
1471 BAMBOO_DEBUGPRINT(0xa001);
1472 BAMBOO_EXIT(0xa001);
1476 } // void * smemalloc_I(int, int, int)
1478 INLINE int checkMsgLength_I(int size) {
1481 BAMBOO_DEBUGPRINT(0xcccc);
1484 int type = msgdata[msgdataindex];
1504 case GCSTARTCOMPACT:
1530 case REDIRECTGROUNT:
1532 case REDIRECTRELEASE:
1545 case GCFINISHCOMPACT:
1559 case TRANSOBJ: // nonfixed size
1565 msglength = msgdata[msgdataindex+1];
1574 BAMBOO_DEBUGPRINT_REG(type);
1575 BAMBOO_DEBUGPRINT_REG(size);
1576 BAMBOO_DEBUGPRINT_REG(msgdataindex);
1577 BAMBOO_DEBUGPRINT_REG(msgdatalast);
1578 BAMBOO_DEBUGPRINT_REG(msgdatafull);
1581 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1583 BAMBOO_EXIT(0xd005);
1589 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1594 BAMBOO_DEBUGPRINT(0xffff);
1600 INLINE void processmsg_transobj_I() {
1602 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
1606 BAMBOO_DEBUGPRINT(0xe880);
1609 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1611 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
1613 BAMBOO_EXIT(0xa002);
1615 // store the object and its corresponding queue info, enqueue it later
1616 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
1618 transObj->length = (msglength - 3) / 2;
1619 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1620 for(k = 0; k < transObj->length; ++k) {
1621 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
1625 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1628 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
1632 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1636 // check if there is an existing duplicate item
1638 struct QueueItem * qitem = getHead(&objqueue);
1639 struct QueueItem * prev = NULL;
1640 while(qitem != NULL) {
1641 struct transObjInfo * tmpinfo =
1642 (struct transObjInfo *)(qitem->objectptr);
1643 if(tmpinfo->objptr == transObj->objptr) {
1644 // the same object, remove outdate one
1645 RUNFREE(tmpinfo->queues);
1647 removeItem(&objqueue, qitem);
1653 qitem = getHead(&objqueue);
1655 qitem = getNextQueueItem(prev);
1658 addNewItem_I(&objqueue, (void *)transObj);
1660 ++(self_numreceiveobjs);
1663 INLINE void processmsg_transtall_I() {
1664 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1665 // non startup core can not receive stall msg
1667 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
1669 BAMBOO_EXIT(0xa003);
1671 int num_core = msgdata[msgdataindex]; //[1]
1673 if(num_core < NUMCORESACTIVE) {
1676 BAMBOO_DEBUGPRINT(0xe881);
1679 corestatus[num_core] = 0;
1680 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
1682 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
1687 #ifndef MULTICORE_GC
1688 INLINE void processmsg_lockrequest_I() {
1689 // check to see if there is a lock exist for the required obj
1690 // msgdata[1] -> lock type
1691 int locktype = msgdata[msgdataindex]; //[1];
1693 int data2 = msgdata[msgdataindex]; // obj pointer
1695 int data3 = msgdata[msgdataindex]; // lock
1697 int data4 = msgdata[msgdataindex]; // request core
1699 // -1: redirected, 0: approved, 1: denied
1700 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
1702 // this lock request is redirected
1705 // send response msg
1706 // for 32 bit machine, the size is always 4 words, cache the msg first
1707 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
1708 if(BAMBOO_CHECK_SEND_MODE()) {
1709 cache_msg_4(data4, tmp, locktype, data2, data3);
1711 send_msg_4(data4, tmp, locktype, data2, data3, true);
1716 INLINE void processmsg_lockgrount_I() {
1718 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1720 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
1722 BAMBOO_EXIT(0xa004);
1724 int data2 = msgdata[msgdataindex];
1726 int data3 = msgdata[msgdataindex];
1728 if((lockobj == data2) && (lock2require == data3)) {
1731 BAMBOO_DEBUGPRINT(0xe882);
1740 // conflicts on lockresults
1742 BAMBOO_DEBUGPRINT_REG(data2);
1744 BAMBOO_EXIT(0xa005);
1748 INLINE void processmsg_lockdeny_I() {
1750 int data2 = msgdata[msgdataindex];
1752 int data3 = msgdata[msgdataindex];
1754 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1756 BAMBOO_DEBUGPRINT_REG(data2);
1758 BAMBOO_EXIT(0xa006);
1760 if((lockobj == data2) && (lock2require == data3)) {
1763 BAMBOO_DEBUGPRINT(0xe883);
1772 // conflicts on lockresults
1774 BAMBOO_DEBUGPRINT_REG(data2);
1776 BAMBOO_EXIT(0xa007);
1780 INLINE void processmsg_lockrelease_I() {
1781 int data1 = msgdata[msgdataindex];
1783 int data2 = msgdata[msgdataindex];
1785 // receive lock release msg
1786 processlockrelease(data1, data2, 0, false);
1789 INLINE void processmsg_redirectlock_I() {
1790 // check to see if there is a lock exist for the required obj
1791 int data1 = msgdata[msgdataindex];
1792 MSG_INDEXINC_I(); //msgdata[1]; // lock type
1793 int data2 = msgdata[msgdataindex];
1794 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
1795 int data3 = msgdata[msgdataindex];
1796 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
1797 int data4 = msgdata[msgdataindex];
1798 MSG_INDEXINC_I(); //msgdata[4]; // root request core
1799 int data5 = msgdata[msgdataindex];
1800 MSG_INDEXINC_I(); //msgdata[5]; // request core
1801 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
1803 // this lock request is redirected
1806 // send response msg
1807 // for 32 bit machine, the size is always 4 words, cache the msg first
1808 if(BAMBOO_CHECK_SEND_MODE()) {
1809 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
1810 data1, data2, data3);
1812 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1813 data1, data2, data3, true);
1818 INLINE void processmsg_redirectgrount_I() {
1820 int data2 = msgdata[msgdataindex];
1822 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1824 BAMBOO_DEBUGPRINT_REG(data2);
1826 BAMBOO_EXIT(0xa00a);
1828 if(lockobj == data2) {
1831 BAMBOO_DEBUGPRINT(0xe891);
1834 int data3 = msgdata[msgdataindex];
1838 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
1843 // conflicts on lockresults
1845 BAMBOO_DEBUGPRINT_REG(data2);
1847 BAMBOO_EXIT(0xa00b);
1851 INLINE void processmsg_redirectdeny_I() {
1853 int data2 = msgdata[msgdataindex];
1855 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1857 BAMBOO_DEBUGPRINT_REG(data2);
1859 BAMBOO_EXIT(0xa00c);
1861 if(lockobj == data2) {
1864 BAMBOO_DEBUGPRINT(0xe892);
1873 // conflicts on lockresults
1875 BAMBOO_DEBUGPRINT_REG(data2);
1877 BAMBOO_EXIT(0xa00d);
1881 INLINE void processmsg_redirectrelease_I() {
1882 int data1 = msgdata[msgdataindex];
1884 int data2 = msgdata[msgdataindex];
1886 int data3 = msgdata[msgdataindex];
1888 processlockrelease(data1, data2, data3, true);
1890 #endif // #ifndef MULTICORE_GC
1893 INLINE void processmsg_profileoutput_I() {
1894 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1895 // startup core can not receive profile output finish msg
1896 BAMBOO_EXIT(0xa008);
1900 BAMBOO_DEBUGPRINT(0xe885);
1904 totalexetime = msgdata[msgdataindex]; //[1]
1906 outputProfileData();
1907 // cache the msg first
1908 if(BAMBOO_CHECK_SEND_MODE()) {
1909 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1911 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
1915 INLINE void processmsg_profilefinish_I() {
1916 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1917 // non startup core can not receive profile output finish msg
1919 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
1921 BAMBOO_EXIT(0xa009);
1925 BAMBOO_DEBUGPRINT(0xe886);
1928 int data1 = msgdata[msgdataindex];
1930 profilestatus[data1] = 0;
1932 #endif // #ifdef PROFILE
1934 INLINE void processmsg_statusconfirm_I() {
1935 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1936 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1937 // wrong core to receive such msg
1938 BAMBOO_EXIT(0xa00e);
1940 // send response msg
1943 BAMBOO_DEBUGPRINT(0xe887);
1946 // cache the msg first
1947 if(BAMBOO_CHECK_SEND_MODE()) {
1948 cache_msg_5(STARTUPCORE, STATUSREPORT,
1949 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
1950 self_numsendobjs, self_numreceiveobjs);
1952 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
1953 BAMBOO_NUM_OF_CORE, self_numsendobjs,
1954 self_numreceiveobjs, true);
1959 INLINE void processmsg_statusreport_I() {
1960 int data1 = msgdata[msgdataindex];
1962 int data2 = msgdata[msgdataindex];
1964 int data3 = msgdata[msgdataindex];
1966 int data4 = msgdata[msgdataindex];
1968 // receive a status confirm info
1969 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1970 // wrong core to receive such msg
1972 BAMBOO_DEBUGPRINT_REG(data2);
1974 BAMBOO_EXIT(0xa00f);
1978 BAMBOO_DEBUGPRINT(0xe888);
1984 corestatus[data2] = data1;
1985 numsendobjs[data2] = data3;
1986 numreceiveobjs[data2] = data4;
1990 INLINE void processmsg_terminate_I() {
1993 BAMBOO_DEBUGPRINT(0xe889);
2000 INLINE void processmsg_memrequest_I() {
2002 if(!interruptInfoOverflow) {
2003 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2004 interruptInfoArray[interruptInfoIndex] = intInfo;
2005 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2006 intInfo->endTime = -1;
2009 int data1 = msgdata[msgdataindex];
2011 int data2 = msgdata[msgdataindex];
2013 // receive a shared memory request msg
2014 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2015 // wrong core to receive such msg
2017 BAMBOO_DEBUGPRINT_REG(data2);
2019 BAMBOO_EXIT(0xa010);
2023 BAMBOO_DEBUGPRINT(0xe88a);
2030 // is currently doing gc, dump this msg
2031 if(INITPHASE == gcphase) {
2032 // if still in the initphase of gc, send a startinit msg again,
2033 // cache the msg first
2034 if(BAMBOO_CHECK_SEND_MODE()) {
2035 cache_msg_1(data2, GCSTARTINIT);
2037 send_msg_1(data2, GCSTARTINIT, true);
2042 mem = smemalloc_I(data2, data1, &allocsize);
2044 // send the start_va to request core, cache the msg first
2045 if(BAMBOO_CHECK_SEND_MODE()) {
2046 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2048 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2050 } // if mem == NULL, the gcflag of the startup core has been set
2051 // and the gc should be started later, then a GCSTARTINIT msg
2052 // will be sent to the requesting core to notice it to start gc
2053 // and try malloc again
2059 if(!interruptInfoOverflow) {
2060 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2061 interruptInfoIndex++;
2062 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2063 interruptInfoOverflow = true;
2069 INLINE void processmsg_memresponse_I() {
2070 int data1 = msgdata[msgdataindex];
2072 int data2 = msgdata[msgdataindex];
2074 // receive a shared memory response msg
2077 BAMBOO_DEBUGPRINT(0xe88b);
2081 // if is currently doing gc, dump this msg
2085 bamboo_smem_size = 0;
2089 // fill header to store the size of this mem block
2090 memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2091 (*((int*)data1)) = data2;
2092 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2093 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2095 bamboo_smem_size = data2;
2096 bamboo_cur_msp =(void*)(data1);
2106 INLINE void processmsg_gcstartinit_I() {
2108 gcphase = INITPHASE;
2110 // is waiting for response of mem request
2111 // let it return NULL and start gc
2112 bamboo_smem_size = 0;
2113 bamboo_cur_msp = NULL;
2118 INLINE void processmsg_gcstart_I() {
2121 BAMBOO_DEBUGPRINT(0xe88c);
2125 gcphase = MARKPHASE;
2128 INLINE void processmsg_gcstartcompact_I() {
2129 gcblock2fill = msgdata[msgdataindex];
2130 MSG_INDEXINC_I(); //msgdata[1];
2131 gcphase = COMPACTPHASE;
2134 INLINE void processmsg_gcstartflush_I() {
2135 gcphase = FLUSHPHASE;
2138 INLINE void processmsg_gcfinishinit_I() {
2139 int data1 = msgdata[msgdataindex];
2141 // received a init phase finish msg
2142 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2143 // non startup core can not receive this msg
2145 BAMBOO_DEBUGPRINT_REG(data1);
2147 BAMBOO_EXIT(0xb001);
2150 BAMBOO_DEBUGPRINT(0xe88c);
2151 BAMBOO_DEBUGPRINT_REG(data1);
2153 // All cores should do init GC
2154 if(data1 < NUMCORESACTIVE) {
2155 gccorestatus[data1] = 0;
2159 INLINE void processmsg_gcfinishmark_I() {
2160 int data1 = msgdata[msgdataindex];
2162 int data2 = msgdata[msgdataindex];
2164 int data3 = msgdata[msgdataindex];
2166 // received a mark phase finish msg
2167 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2168 // non startup core can not receive this msg
2170 BAMBOO_DEBUGPRINT_REG(data1);
2172 BAMBOO_EXIT(0xb002);
2174 // all cores should do mark
2175 if(data1 < NUMCORESACTIVE) {
2176 gccorestatus[data1] = 0;
2177 gcnumsendobjs[data1] = data2;
2178 gcnumreceiveobjs[data1] = data3;
2182 INLINE void processmsg_gcfinishcompact_I() {
2183 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2184 // non startup core can not receive this msg
2187 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2189 BAMBOO_EXIT(0xb003);
2191 int cnum = msgdata[msgdataindex];
2192 MSG_INDEXINC_I(); //msgdata[1];
2193 int filledblocks = msgdata[msgdataindex];
2194 MSG_INDEXINC_I(); //msgdata[2];
2195 int heaptop = msgdata[msgdataindex];
2196 MSG_INDEXINC_I(); //msgdata[3];
2197 int data4 = msgdata[msgdataindex];
2198 MSG_INDEXINC_I(); //msgdata[4];
2199 // only gc cores need to do compact
2200 if(cnum < NUMCORES4GC) {
2201 if(COMPACTPHASE == gcphase) {
2202 gcfilledblocks[cnum] = filledblocks;
2203 gcloads[cnum] = heaptop;
2210 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2211 // cache the msg first
2212 if(BAMBOO_CHECK_SEND_MODE()) {
2213 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2215 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2219 gccorestatus[cnum] = 0;
2221 } // if(cnum < NUMCORES4GC)
2224 INLINE void processmsg_gcfinishflush_I() {
2225 int data1 = msgdata[msgdataindex];
2227 // received a flush phase finish msg
2228 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2229 // non startup core can not receive this msg
2232 BAMBOO_DEBUGPRINT_REG(data1);
2234 BAMBOO_EXIT(0xb004);
2236 // all cores should do flush
2237 if(data1 < NUMCORESACTIVE) {
2238 gccorestatus[data1] = 0;
2242 INLINE void processmsg_gcmarkconfirm_I() {
2243 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2244 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2245 // wrong core to receive such msg
2246 BAMBOO_EXIT(0xb005);
2248 // send response msg, cahce the msg first
2249 if(BAMBOO_CHECK_SEND_MODE()) {
2250 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2251 gcbusystatus, gcself_numsendobjs,
2252 gcself_numreceiveobjs);
2254 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2255 gcbusystatus, gcself_numsendobjs,
2256 gcself_numreceiveobjs, true);
2261 INLINE void processmsg_gcmarkreport_I() {
2262 int data1 = msgdata[msgdataindex];
2264 int data2 = msgdata[msgdataindex];
2266 int data3 = msgdata[msgdataindex];
2268 int data4 = msgdata[msgdataindex];
2270 // received a marked phase finish confirm response msg
2271 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2272 // wrong core to receive such msg
2274 BAMBOO_DEBUGPRINT_REG(data2);
2276 BAMBOO_EXIT(0xb006);
2281 gccorestatus[data1] = data2;
2282 gcnumsendobjs[data1] = data3;
2283 gcnumreceiveobjs[data1] = data4;
2287 INLINE void processmsg_gcmarkedobj_I() {
2288 int data1 = msgdata[msgdataindex];
2290 // received a markedObj msg
2291 if(((int *)data1)[6] == INIT) {
2292 // this is the first time that this object is discovered,
2293 // set the flag as DISCOVERED
2294 ((int *)data1)[6] = DISCOVERED;
2295 gc_enqueue_I(data1);
2297 gcself_numreceiveobjs++;
2298 gcbusystatus = true;
2301 INLINE void processmsg_gcmovestart_I() {
2303 gcdstcore = msgdata[msgdataindex];
2304 MSG_INDEXINC_I(); //msgdata[1];
2305 gcmovestartaddr = msgdata[msgdataindex];
2306 MSG_INDEXINC_I(); //msgdata[2];
2307 gcblock2fill = msgdata[msgdataindex];
2308 MSG_INDEXINC_I(); //msgdata[3];
2311 INLINE void processmsg_gcmaprequest_I() {
2313 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2315 void * dstptr = NULL;
2316 int data1 = msgdata[msgdataindex];
2318 //dstptr = mgchashSearch(msgdata[1]);
2320 unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2322 RuntimeHashget(gcpointertbl, data1, &dstptr);
2324 flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2326 int data2 = msgdata[msgdataindex];
2328 //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2330 unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2332 if(NULL == dstptr) {
2333 // no such pointer in this core, something is wrong
2335 BAMBOO_DEBUGPRINT_REG(data1);
2336 BAMBOO_DEBUGPRINT_REG(data2);
2338 BAMBOO_EXIT(0xb007);
2339 //assume that the object was not moved, use the original address
2340 /*if(isMsgSending) {
2341 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2343 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2346 // send back the mapping info, cache the msg first
2347 if(BAMBOO_CHECK_SEND_MODE()) {
2348 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2350 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2354 flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2355 //num_mapinforequest_i++;
2359 INLINE void processmsg_gcmapinfo_I() {
2361 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2363 int data1 = msgdata[msgdataindex];
2365 if(data1 != gcobj2map) {
2366 // obj not matched, something is wrong
2368 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2369 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2371 BAMBOO_EXIT(0xb008);
2373 gcmappedobj = msgdata[msgdataindex]; // [2]
2375 //mgchashReplace_I(msgdata[1], msgdata[2]);
2376 //mgchashInsert_I(gcobj2map, gcmappedobj);
2377 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2378 //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2382 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2386 INLINE void processmsg_gclobjinfo_I() {
2389 int data1 = msgdata[msgdataindex];
2391 int data2 = msgdata[msgdataindex];
2393 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2395 BAMBOO_DEBUGPRINT_REG(data2);
2397 BAMBOO_EXIT(0xb009);
2399 // store the mark result info
2401 gcloads[cnum] = msgdata[msgdataindex];
2402 MSG_INDEXINC_I(); // msgdata[3];
2403 int data4 = msgdata[msgdataindex];
2405 if(gcheaptop < data4) {
2408 // large obj info here
2409 for(int k = 5; k < data1; ) {
2410 int lobj = msgdata[msgdataindex];
2411 MSG_INDEXINC_I(); //msgdata[k++];
2412 int length = msgdata[msgdataindex];
2413 MSG_INDEXINC_I(); //msgdata[k++];
2414 gc_lobjenqueue_I(lobj, length, cnum);
2416 } // for(int k = 5; k < msgdata[1];)
2419 INLINE void processmsg_gclobjmapping_I() {
2420 int data1 = msgdata[msgdataindex];
2422 int data2 = msgdata[msgdataindex];
2424 //mgchashInsert_I(msgdata[1], msgdata[2]);
2425 RuntimeHashadd_I(gcpointertbl, data1, data2);
2426 //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2428 #endif // #ifdef MULTICORE_GC
2430 // receive object transferred from other cores
2431 // or the terminate message from other cores
2432 // Should be invoked in critical sections!!
2433 // NOTICE: following format is for threadsimulate version only
2434 // RAW version please see previous description
2435 // format: type + object
2436 // type: -1--stall msg
2438 // return value: 0--received an object
2439 // 1--received nothing
2440 // 2--received a Stall Msg
2441 // 3--received a lock Msg
2442 // RAW version: -1 -- received nothing
2443 // otherwise -- received msg type
2444 int receiveObject(int send_port_pending) {
2446 // get the incoming msgs
2447 if(receiveMsg(send_port_pending) == -1) {
2451 // processing received msgs
2453 MSG_REMAINSIZE_I(&size);
2454 if((size == 0) || (checkMsgLength_I(size) == -1)) {
2456 // have new coming msg
2457 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
2464 if(msglength <= size) {
2465 // have some whole msg
2466 //if(msgdataindex == msglength) {
2467 // received a whole msg
2469 type = msgdata[msgdataindex]; //[0]
2471 msgdatafull = false;
2473 //tprintf("msg type: %x\n", type);
2476 // receive a object transfer msg
2477 processmsg_transobj_I();
2482 // receive a stall msg
2483 processmsg_transtall_I();
2487 // GC version have no lock msgs
2488 #ifndef MULTICORE_GC
2490 // receive lock request msg, handle it right now
2491 processmsg_lockrequest_I();
2493 } // case LOCKREQUEST
2496 // receive lock grount msg
2497 processmsg_lockgrount_I();
2499 } // case LOCKGROUNT
2502 // receive lock deny msg
2503 processmsg_lockdeny_I();
2508 processmsg_lockrelease_I();
2510 } // case LOCKRELEASE
2511 #endif // #ifndef MULTICORE_GC
2514 case PROFILEOUTPUT: {
2515 // receive an output profile data request msg
2516 processmsg_profileoutput_I();
2518 } // case PROFILEOUTPUT
2520 case PROFILEFINISH: {
2521 // receive a profile output finish msg
2522 processmsg_profilefinish_I();
2524 } // case PROFILEFINISH
2525 #endif // #ifdef PROFILE
2527 // GC version has no lock msgs
2528 #ifndef MULTICORE_GC
2529 case REDIRECTLOCK: {
2530 // receive a redirect lock request msg, handle it right now
2531 processmsg_redirectlock_I();
2533 } // case REDIRECTLOCK
2535 case REDIRECTGROUNT: {
2536 // receive a lock grant msg with redirect info
2537 processmsg_redirectgrount_I();
2539 } // case REDIRECTGROUNT
2541 case REDIRECTDENY: {
2542 // receive a lock deny msg with redirect info
2543 processmsg_redirectdeny_I();
2545 } // case REDIRECTDENY
2547 case REDIRECTRELEASE: {
2548 // receive a lock release msg with redirect info
2549 processmsg_redirectrelease_I();
2551 } // case REDIRECTRELEASE
2552 #endif // #ifndef MULTICORE_GC
2554 case STATUSCONFIRM: {
2555 // receive a status confirm info
2556 processmsg_statusconfirm_I();
2558 } // case STATUSCONFIRM
2560 case STATUSREPORT: {
2561 processmsg_statusreport_I();
2563 } // case STATUSREPORT
2566 // receive a terminate msg
2567 processmsg_terminate_I();
2572 processmsg_memrequest_I();
2574 } // case MEMREQUEST
2577 processmsg_memresponse_I();
2579 } // case MEMRESPONSE
2584 processmsg_gcstartinit_I();
2586 } // case GCSTARTINIT
2589 // receive a start GC msg
2590 processmsg_gcstart_I();
2594 case GCSTARTCOMPACT: {
2595 // a compact phase start msg
2596 processmsg_gcstartcompact_I();
2598 } // case GCSTARTCOMPACT
2600 case GCSTARTFLUSH: {
2601 // received a flush phase start msg
2602 processmsg_gcstartflush_I();
2604 } // case GCSTARTFLUSH
2606 case GCFINISHINIT: {
2607 processmsg_gcfinishinit_I();
2609 } // case GCFINISHINIT
2611 case GCFINISHMARK: {
2612 processmsg_gcfinishmark_I();
2614 } // case GCFINISHMARK
2616 case GCFINISHCOMPACT: {
2617 // received a compact phase finish msg
2618 processmsg_gcfinishcompact_I();
2620 } // case GCFINISHCOMPACT
2622 case GCFINISHFLUSH: {
2623 processmsg_gcfinishflush_I();
2625 } // case GCFINISHFLUSH
2628 // received a GC finish msg
2629 gcphase = FINISHPHASE;
2633 case GCMARKCONFIRM: {
2634 // received a marked phase finish confirm request msg
2635 // all cores should do mark
2636 processmsg_gcmarkconfirm_I();
2638 } // case GCMARKCONFIRM
2640 case GCMARKREPORT: {
2641 processmsg_gcmarkreport_I();
2643 } // case GCMARKREPORT
2646 processmsg_gcmarkedobj_I();
2648 } // case GCMARKEDOBJ
2651 // received a start moving objs msg
2652 processmsg_gcmovestart_I();
2654 } // case GCMOVESTART
2656 case GCMAPREQUEST: {
2657 // received a mapping info request msg
2658 processmsg_gcmaprequest_I();
2660 } // case GCMAPREQUEST
2663 // received a mapping info response msg
2664 processmsg_gcmapinfo_I();
2668 case GCLOBJREQUEST: {
2669 // received a large objs info request msg
2670 transferMarkResults_I();
2672 } // case GCLOBJREQUEST
2675 // received a large objs info response msg
2676 processmsg_gclobjinfo_I();
2678 } // case GCLOBJINFO
2680 case GCLOBJMAPPING: {
2681 // received a large obj mapping info msg
2682 processmsg_gclobjmapping_I();
2684 } // case GCLOBJMAPPING
2686 #endif // #ifdef MULTICORE_GC
2691 //memset(msgdata, '\0', sizeof(int) * msgdataindex);
2693 msglength = BAMBOO_MSG_BUF_LENGTH;
2695 //printf("++ msg: %x \n", type);
2697 if(msgdataindex != msgdatalast) {
2698 // still have available msg
2703 BAMBOO_DEBUGPRINT(0xe88d);
2707 // have new coming msg
2708 if(BAMBOO_MSG_AVAIL() != 0) {
2722 BAMBOO_DEBUGPRINT(0xe88e);
2726 /* if(isInterrupt) {
2734 int enqueuetasks(struct parameterwrapper *parameter,
2735 struct parameterwrapper *prevptr,
2736 struct ___Object___ *ptr,
2738 int numenterflags) {
2739 void * taskpointerarray[MAXTASKPARAMS];
2741 //int numparams=parameter->task->numParameters;
2742 int numiterators=parameter->task->numTotal-1;
2745 struct taskdescriptor * task=parameter->task;
2747 //this add the object to parameterwrapper
2748 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
2749 numenterflags, enterflags==NULL);
2751 /* Add enqueued object to parameter vector */
2752 taskpointerarray[parameter->slot]=ptr;
2754 /* Reset iterators */
2755 for(j=0; j<numiterators; j++) {
2756 toiReset(¶meter->iterators[j]);
2759 /* Find initial state */
2760 for(j=0; j<numiterators; j++) {
2762 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2763 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2765 /* Need to backtrack */
2766 toiReset(¶meter->iterators[j]);
2770 /* Nothing to enqueue */
2776 /* Enqueue current state */
2778 struct taskparamdescriptor *tpd=
2779 RUNMALLOC(sizeof(struct taskparamdescriptor));
2781 tpd->numParameters=numiterators+1;
2782 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2784 for(j=0; j<=numiterators; j++) {
2785 //store the actual parameters
2786 tpd->parameterArray[j]=taskpointerarray[j];
2789 if (( /*!gencontains(failedtasks, tpd)&&*/
2790 !gencontains(activetasks,tpd))) {
2791 genputtable(activetasks, tpd, tpd);
2793 RUNFREE(tpd->parameterArray);
2797 /* This loop iterates to the next parameter combination */
2798 if (numiterators==0)
2801 for(j=numiterators-1; j<numiterators; j++) {
2803 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2804 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2806 /* Need to backtrack */
2807 toiReset(¶meter->iterators[j]);
2811 /* Nothing more to enqueue */
2819 int enqueuetasks_I(struct parameterwrapper *parameter,
2820 struct parameterwrapper *prevptr,
2821 struct ___Object___ *ptr,
2823 int numenterflags) {
2824 void * taskpointerarray[MAXTASKPARAMS];
2826 //int numparams=parameter->task->numParameters;
2827 int numiterators=parameter->task->numTotal-1;
2832 struct taskdescriptor * task=parameter->task;
2834 //this add the object to parameterwrapper
2835 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2836 numenterflags, enterflags==NULL);
2838 /* Add enqueued object to parameter vector */
2839 taskpointerarray[parameter->slot]=ptr;
2841 /* Reset iterators */
2842 for(j=0; j<numiterators; j++) {
2843 toiReset(¶meter->iterators[j]);
2846 /* Find initial state */
2847 for(j=0; j<numiterators; j++) {
2849 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2850 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2852 /* Need to backtrack */
2853 toiReset(¶meter->iterators[j]);
2857 /* Nothing to enqueue */
2863 /* Enqueue current state */
2865 struct taskparamdescriptor *tpd=
2866 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2868 tpd->numParameters=numiterators+1;
2869 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2871 for(j=0; j<=numiterators; j++) {
2872 //store the actual parameters
2873 tpd->parameterArray[j]=taskpointerarray[j];
2876 if (( /*!gencontains(failedtasks, tpd)&&*/
2877 !gencontains(activetasks,tpd))) {
2878 genputtable_I(activetasks, tpd, tpd);
2880 RUNFREE(tpd->parameterArray);
2884 /* This loop iterates to the next parameter combination */
2885 if (numiterators==0)
2888 for(j=numiterators-1; j<numiterators; j++) {
2890 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2891 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2893 /* Need to backtrack */
2894 toiReset(¶meter->iterators[j]);
2898 /* Nothing more to enqueue */
2912 int containstag(struct ___Object___ *ptr,
2913 struct ___TagDescriptor___ *tag);
2915 #ifndef MULTICORE_GC
2916 void releasewritelock_r(void * lock, void * redirectlock) {
2918 int reallock = (int)lock;
2919 targetcore = (reallock >> 5) % NUMCORES;
2922 BAMBOO_DEBUGPRINT(0xe671);
2923 BAMBOO_DEBUGPRINT_REG((int)lock);
2924 BAMBOO_DEBUGPRINT_REG(reallock);
2925 BAMBOO_DEBUGPRINT_REG(targetcore);
2928 if(targetcore == BAMBOO_NUM_OF_CORE) {
2929 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
2931 BAMBOO_DEBUGPRINT(0xf001);
2933 // reside on this core
2934 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2935 // no locks for this object, something is wrong
2936 BAMBOO_EXIT(0xa011);
2939 struct LockValue * lockvalue = NULL;
2941 BAMBOO_DEBUGPRINT(0xe672);
2943 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2944 lockvalue = (struct LockValue *)rwlock_obj;
2946 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2949 lockvalue->redirectlock = (int)redirectlock;
2951 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2954 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
2956 BAMBOO_DEBUGPRINT(0xf000);
2960 // send lock release with redirect info msg
2961 // for 32 bit machine, the size is always 4 words
2962 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
2963 (int)redirectlock, false);
2968 void executetasks() {
2969 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2972 struct ___Object___ * tmpparam = NULL;
2973 struct parameterdescriptor * pd=NULL;
2974 struct parameterwrapper *pw=NULL;
2984 while(hashsize(activetasks)>0) {
2989 BAMBOO_DEBUGPRINT(0xe990);
2992 /* See if there are any active tasks */
2993 //if (hashsize(activetasks)>0) {
2996 #ifdef ACCURATEPROFILE
2997 profileTaskStart("tpd checking");
3001 //clock1 = BAMBOO_GET_EXE_TIME();
3004 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3005 genfreekey(activetasks, currtpd);
3007 numparams=currtpd->task->numParameters;
3008 numtotal=currtpd->task->numTotal;
3010 // clear the lockRedirectTbl
3011 // (TODO, this table should be empty after all locks are released)
3013 /*for(j = 0; j < MAXTASKPARAMS; j++) {
3014 runtime_locks[j].redirectlock = 0;
3015 runtime_locks[j].value = 0;
3017 // get all required locks
3018 runtime_locklen = 0;
3019 // check which locks are needed
3020 for(i = 0; i < numparams; i++) {
3021 void * param = currtpd->parameterArray[i];
3025 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3027 taskpointerarray[i+OFFSET]=param;
3030 if(((struct ___Object___ *)param)->lock == NULL) {
3031 tmplock = (int)param;
3033 tmplock = (int)(((struct ___Object___ *)param)->lock);
3035 // insert into the locks array
3036 for(j = 0; j < runtime_locklen; j++) {
3037 if(runtime_locks[j].value == tmplock) {
3040 } else if(runtime_locks[j].value > tmplock) {
3045 int h = runtime_locklen;
3047 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3048 runtime_locks[h].value = runtime_locks[h-1].value;
3050 runtime_locks[j].value = tmplock;
3051 runtime_locks[j].redirectlock = (int)param;
3054 } // line 2713: for(i = 0; i < numparams; i++)
3055 // grab these required locks
3057 BAMBOO_DEBUGPRINT(0xe991);
3060 //clock2 = BAMBOO_GET_EXE_TIME();
3062 for(i = 0; i < runtime_locklen; i++) {
3063 int * lock = (int *)(runtime_locks[i].redirectlock);
3065 // require locks for this parameter if it is not a startup object
3067 BAMBOO_DEBUGPRINT_REG((int)lock);
3068 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3071 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3073 BAMBOO_DEBUGPRINT(0xf001);
3076 //isInterrupt = false;
3079 BAMBOO_WAITING_FOR_LOCK(0);
3080 // check for outgoing sends
3081 /*if (isMsgHanging) {
3082 extern inline void send_hanging_msg(bool);
3083 send_hanging_msg(true);
3088 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3089 // check for outgoing sends
3090 /*if (isMsgHanging) {
3091 extern inline void send_hanging_msg(bool);
3092 send_hanging_msg(true);
3097 grount = lockresult;
3107 //isInterrupt = true;
3109 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3111 BAMBOO_DEBUGPRINT(0xf000);
3116 BAMBOO_DEBUGPRINT(0xe992);
3117 BAMBOO_DEBUGPRINT_REG(lock);
3119 // check if has the lock already
3120 // can not get the lock, try later
3121 // release all grabbed locks for previous parameters
3122 for(j = 0; j < i; ++j) {
3123 lock = (int*)(runtime_locks[j].redirectlock);
3124 releasewritelock(lock);
3126 genputtable(activetasks, currtpd, currtpd);
3127 if(hashsize(activetasks) == 1) {
3128 // only one task right now, wait a little while before next try
3134 #ifdef ACCURATEPROFILE
3135 // fail, set the end of the checkTaskInfo
3142 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3145 clock3 = BAMBOO_GET_EXE_TIME();
3146 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3149 BAMBOO_DEBUGPRINT(0xe993);
3151 /* Make sure that the parameters are still in the queues */
3152 for(i=0; i<numparams; i++) {
3153 void * parameter=currtpd->parameterArray[i];
3157 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3158 classsize[((struct ___Object___ *)parameter)->type]);
3160 tmpparam = (struct ___Object___ *)parameter;
3161 pd=currtpd->task->descriptorarray[i];
3162 pw=(struct parameterwrapper *) pd->queue;
3163 /* Check that object is still in queue */
3165 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3167 BAMBOO_DEBUGPRINT(0xe994);
3168 BAMBOO_DEBUGPRINT_REG(parameter);
3170 // release grabbed locks
3171 for(j = 0; j < runtime_locklen; ++j) {
3172 int * lock = (int *)(runtime_locks[j].redirectlock);
3173 releasewritelock(lock);
3175 RUNFREE(currtpd->parameterArray);
3181 /* Check if the object's flags still meets requirements */
3185 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3186 andmask=pw->intarray[tmpi*2];
3187 checkmask=pw->intarray[tmpi*2+1];
3188 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3194 // flags are never suitable
3195 // remove this obj from the queue
3197 int UNUSED, UNUSED2;
3200 BAMBOO_DEBUGPRINT(0xe995);
3201 BAMBOO_DEBUGPRINT_REG(parameter);
3203 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3204 (int *) &enterflags, &UNUSED, &UNUSED2);
3205 ObjectHashremove(pw->objectset, (int)parameter);
3206 if (enterflags!=NULL)
3207 RUNFREE(enterflags);
3208 // release grabbed locks
3209 for(j = 0; j < runtime_locklen; ++j) {
3210 int * lock = (int *)(runtime_locks[j].redirectlock);
3211 releasewritelock(lock);
3213 RUNFREE(currtpd->parameterArray);
3217 #ifdef ACCURATEPROFILE
3218 // fail, set the end of the checkTaskInfo
3223 } // line 2878: if (!ismet)
3227 /* Check that object still has necessary tags */
3228 for(j=0; j<pd->numbertags; j++) {
3229 int slotid=pd->tagarray[2*j]+numparams;
3230 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3231 if (!containstag(parameter, tagd)) {
3233 BAMBOO_DEBUGPRINT(0xe996);
3236 // release grabbed locks
3238 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3239 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3240 releasewritelock(lock);
3243 RUNFREE(currtpd->parameterArray);
3247 } // line2911: if (!containstag(parameter, tagd))
3248 } // line 2808: for(j=0; j<pd->numbertags; j++)
3250 taskpointerarray[i+OFFSET]=parameter;
3251 } // line 2824: for(i=0; i<numparams; i++)
3253 for(; i<numtotal; i++) {
3254 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3259 /* Actually call task */
3261 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3262 taskpointerarray[1]=NULL;
3265 #ifdef ACCURATEPROFILE
3266 // check finish, set the end of the checkTaskInfo
3269 profileTaskStart(currtpd->task->name);
3273 //clock4 = BAMBOO_GET_EXE_TIME();
3274 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3277 BAMBOO_DEBUGPRINT(0xe997);
3279 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3282 //clock5 = BAMBOO_GET_EXE_TIME();
3283 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3286 #ifdef ACCURATEPROFILE
3287 // task finish, set the end of the checkTaskInfo
3289 // new a PostTaskInfo for the post-task execution
3290 profileTaskStart("post task execution");
3294 BAMBOO_DEBUGPRINT(0xe998);
3295 BAMBOO_DEBUGPRINT_REG(islock);
3300 BAMBOO_DEBUGPRINT(0xe999);
3302 for(i = 0; i < runtime_locklen; ++i) {
3303 void * ptr = (void *)(runtime_locks[i].redirectlock);
3304 int * lock = (int *)(runtime_locks[i].value);
3306 BAMBOO_DEBUGPRINT_REG((int)ptr);
3307 BAMBOO_DEBUGPRINT_REG((int)lock);
3308 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3310 #ifndef MULTICORE_GC
3311 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3313 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3314 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3315 releasewritelock_r(lock, (int *)redirectlock);
3320 releasewritelock(ptr);
3323 } // line 3015: if(islock)
3326 //clock6 = BAMBOO_GET_EXE_TIME();
3327 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3330 // post task execution finish, set the end of the postTaskInfo
3334 // Free up task parameter descriptor
3335 RUNFREE(currtpd->parameterArray);
3339 BAMBOO_DEBUGPRINT(0xe99a);
3342 //clock7 = BAMBOO_GET_EXE_TIME();
3343 //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));
3346 //} // if (hashsize(activetasks)>0)
3347 } // while(hashsize(activetasks)>0)
3349 BAMBOO_DEBUGPRINT(0xe99b);
3353 /* This function processes an objects tags */
3354 void processtags(struct parameterdescriptor *pd,
3356 struct parameterwrapper *parameter,
3357 int * iteratorcount,
3362 for(i=0; i<pd->numbertags; i++) {
3363 int slotid=pd->tagarray[2*i];
3364 int tagid=pd->tagarray[2*i+1];
3366 if (statusarray[slotid+numparams]==0) {
3367 parameter->iterators[*iteratorcount].istag=1;
3368 parameter->iterators[*iteratorcount].tagid=tagid;
3369 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3370 parameter->iterators[*iteratorcount].tagobjectslot=index;
3371 statusarray[slotid+numparams]=1;
3378 void processobject(struct parameterwrapper *parameter,
3380 struct parameterdescriptor *pd,
3386 struct ObjectHash * objectset=
3387 ((struct parameterwrapper *)pd->queue)->objectset;
3389 parameter->iterators[*iteratorcount].istag=0;
3390 parameter->iterators[*iteratorcount].slot=index;
3391 parameter->iterators[*iteratorcount].objectset=objectset;
3392 statusarray[index]=1;
3394 for(i=0; i<pd->numbertags; i++) {
3395 int slotid=pd->tagarray[2*i];
3396 //int tagid=pd->tagarray[2*i+1];
3397 if (statusarray[slotid+numparams]!=0) {
3398 /* This tag has already been enqueued, use it to narrow search */
3399 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3404 parameter->iterators[*iteratorcount].numtags=tagcount;
3409 /* This function builds the iterators for a task & parameter */
3411 void builditerators(struct taskdescriptor * task,
3413 struct parameterwrapper * parameter) {
3414 int statusarray[MAXTASKPARAMS];
3416 int numparams=task->numParameters;
3417 int iteratorcount=0;
3418 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3420 statusarray[index]=1; /* Initial parameter */
3421 /* Process tags for initial iterator */
3423 processtags(task->descriptorarray[index], index, parameter,
3424 &iteratorcount, statusarray, numparams);
3428 /* Check for objects with existing tags */
3429 for(i=0; i<numparams; i++) {
3430 if (statusarray[i]==0) {
3431 struct parameterdescriptor *pd=task->descriptorarray[i];
3433 for(j=0; j<pd->numbertags; j++) {
3434 int slotid=pd->tagarray[2*j];
3435 if(statusarray[slotid+numparams]!=0) {
3436 processobject(parameter, i, pd, &iteratorcount, statusarray,
3438 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3445 /* Next do objects w/ unbound tags*/
3447 for(i=0; i<numparams; i++) {
3448 if (statusarray[i]==0) {
3449 struct parameterdescriptor *pd=task->descriptorarray[i];
3450 if (pd->numbertags>0) {
3451 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3452 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3458 /* Nothing with a tag enqueued */
3460 for(i=0; i<numparams; i++) {
3461 if (statusarray[i]==0) {
3462 struct parameterdescriptor *pd=task->descriptorarray[i];
3463 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3464 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3477 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3480 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3481 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3483 printf("%s\n", task->name);
3485 for(j=0; j<task->numParameters; j++) {
3486 struct parameterdescriptor *param=task->descriptorarray[j];
3487 struct parameterwrapper *parameter=param->queue;
3488 struct ObjectHash * set=parameter->objectset;
3489 struct ObjectIterator objit;
3491 printf(" Parameter %d\n", j);
3493 ObjectHashiterator(set, &objit);
3494 while(ObjhasNext(&objit)) {
3495 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3496 struct ___Object___ * tagptr=obj->___tags___;
3497 int nonfailed=Objdata4(&objit);
3498 int numflags=Objdata3(&objit);
3499 int flags=Objdata2(&objit);
3502 printf(" Contains %lx\n", obj);
3503 printf(" flag=%d\n", obj->flag);
3506 } else if (tagptr->type==TAGTYPE) {
3508 printf(" tag=%lx\n",tagptr);
3514 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3515 for(; tagindex<ao->___cachedCode___; tagindex++) {
3517 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3530 /* This function processes the task information to create queues for
3531 each parameter type. */
3533 void processtasks() {
3535 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3538 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3539 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3542 /* Build objectsets */
3543 for(j=0; j<task->numParameters; j++) {
3544 struct parameterdescriptor *param=task->descriptorarray[j];
3545 struct parameterwrapper *parameter=param->queue;
3546 parameter->objectset=allocateObjectHash(10);
3547 parameter->task=task;
3550 /* Build iterators for parameters */
3551 for(j=0; j<task->numParameters; j++) {
3552 struct parameterdescriptor *param=task->descriptorarray[j];
3553 struct parameterwrapper *parameter=param->queue;
3554 builditerators(task, j, parameter);
3559 void toiReset(struct tagobjectiterator * it) {
3562 } else if (it->numtags>0) {
3565 ObjectHashiterator(it->objectset, &it->it);
3569 int toiHasNext(struct tagobjectiterator *it,
3570 void ** objectarray OPTARG(int * failed)) {
3573 /* Get object with tags */
3574 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3575 struct ___Object___ *tagptr=obj->___tags___;
3576 if (tagptr->type==TAGTYPE) {
3577 if ((it->tagobjindex==0)&& /* First object */
3578 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3583 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3584 int tagindex=it->tagobjindex;
3585 for(; tagindex<ao->___cachedCode___; tagindex++) {
3586 struct ___TagDescriptor___ *td=
3587 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3588 if (td->flag==it->tagid) {
3589 it->tagobjindex=tagindex; /* Found right type of tag */
3595 } else if (it->numtags>0) {
3596 /* Use tags to locate appropriate objects */
3597 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3598 struct ___Object___ *objptr=tag->flagptr;
3600 if (objptr->type!=OBJECTARRAYTYPE) {
3601 if (it->tagobjindex>0)
3603 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3605 for(i=1; i<it->numtags; i++) {
3606 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3607 if (!containstag(objptr,tag2))
3612 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3615 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
3616 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3617 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3619 for(i=1; i<it->numtags; i++) {
3620 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3621 if (!containstag(objptr,tag2))
3624 it->tagobjindex=tagindex;
3629 it->tagobjindex=tagindex;
3633 return ObjhasNext(&it->it);
3637 int containstag(struct ___Object___ *ptr,
3638 struct ___TagDescriptor___ *tag) {
3640 struct ___Object___ * objptr=tag->flagptr;
3641 if (objptr->type==OBJECTARRAYTYPE) {
3642 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3643 for(j=0; j<ao->___cachedCode___; j++) {
3644 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3654 void toiNext(struct tagobjectiterator *it,
3655 void ** objectarray OPTARG(int * failed)) {
3656 /* hasNext has all of the intelligence */
3659 /* Get object with tags */
3660 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3661 struct ___Object___ *tagptr=obj->___tags___;
3662 if (tagptr->type==TAGTYPE) {
3664 objectarray[it->slot]=tagptr;
3666 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3667 objectarray[it->slot]=
3668 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3670 } else if (it->numtags>0) {
3671 /* Use tags to locate appropriate objects */
3672 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3673 struct ___Object___ *objptr=tag->flagptr;
3674 if (objptr->type!=OBJECTARRAYTYPE) {
3676 objectarray[it->slot]=objptr;
3678 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3679 objectarray[it->slot]=
3680 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3683 /* Iterate object */
3684 objectarray[it->slot]=(void *)Objkey(&it->it);
3690 inline void profileTaskStart(char * taskname) {
3691 if(!taskInfoOverflow) {
3692 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
3693 taskInfoArray[taskInfoIndex] = taskInfo;
3694 taskInfo->taskName = taskname;
3695 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
3696 taskInfo->endTime = -1;
3697 taskInfo->exitIndex = -1;
3698 taskInfo->newObjs = NULL;
3702 inline void profileTaskEnd() {
3703 if(!taskInfoOverflow) {
3704 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
3706 if(taskInfoIndex == TASKINFOLENGTH) {
3707 taskInfoOverflow = true;
3708 //taskInfoIndex = 0;
3713 // output the profiling data
3714 void outputProfileData() {
3717 unsigned long long totaltasktime = 0;
3718 unsigned long long preprocessingtime = 0;
3719 unsigned long long objqueuecheckingtime = 0;
3720 unsigned long long postprocessingtime = 0;
3721 //int interruptiontime = 0;
3722 unsigned long long other = 0;
3723 unsigned long long averagetasktime = 0;
3726 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
3727 // output task related info
3728 for(i = 0; i < taskInfoIndex; i++) {
3729 TaskInfo* tmpTInfo = taskInfoArray[i];
3730 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
3731 printf("%s, %lld, %lld, %lld, %lld",
3732 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
3733 duration, tmpTInfo->exitIndex);
3734 // summarize new obj info
3735 if(tmpTInfo->newObjs != NULL) {
3736 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3737 struct RuntimeIterator * iter = NULL;
3738 while(0 == isEmpty(tmpTInfo->newObjs)) {
3739 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3740 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3742 RuntimeHashget(nobjtbl, (int)objtype, &num);
3743 RuntimeHashremovekey(nobjtbl, (int)objtype);
3745 RuntimeHashadd(nobjtbl, (int)objtype, num);
3747 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3749 //printf(stderr, "new obj!\n");
3752 // output all new obj info
3753 iter = RuntimeHashcreateiterator(nobjtbl);
3754 while(RunhasNext(iter)) {
3755 char * objtype = (char *)Runkey(iter);
3756 int num = Runnext(iter);
3757 printf(", %s, %d", objtype, num);
3761 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
3762 preprocessingtime += duration;
3763 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
3764 postprocessingtime += duration;
3765 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
3766 objqueuecheckingtime += duration;
3768 totaltasktime += duration;
3769 averagetasktime += duration;
3774 if(taskInfoOverflow) {
3775 printf("Caution: task info overflow!\n");
3778 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
3779 averagetasktime /= tasknum;
3781 printf("\nTotal time: %lld\n", totalexetime);
3782 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
3783 (int)(((double)totaltasktime/(double)totalexetime)*100));
3784 printf("Total objqueue checking time: %lld (%d%%)\n",
3785 objqueuecheckingtime,
3786 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
3787 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
3788 (int)(((double)preprocessingtime/(double)totalexetime)*100));
3789 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
3790 (int)(((double)postprocessingtime/(double)totalexetime)*100));
3791 printf("Other time: %lld (%d%%)\n", other,
3792 (int)(((double)other/(double)totalexetime)*100));
3795 printf("\nAverage task execution time: %lld\n", averagetasktime);
3797 //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
3802 BAMBOO_DEBUGPRINT(0xdddd);
3803 // output task related info
3804 for(i= 0; i < taskInfoIndex; i++) {
3805 TaskInfo* tmpTInfo = taskInfoArray[i];
3806 char* tmpName = tmpTInfo->taskName;
3807 int nameLen = strlen(tmpName);
3808 BAMBOO_DEBUGPRINT(0xddda);
3809 for(j = 0; j < nameLen; j++) {
3810 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
3812 BAMBOO_DEBUGPRINT(0xdddb);
3813 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
3814 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
3815 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
3816 if(tmpTInfo->newObjs != NULL) {
3817 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3818 struct RuntimeIterator * iter = NULL;
3819 while(0 == isEmpty(tmpTInfo->newObjs)) {
3820 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3821 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3823 RuntimeHashget(nobjtbl, (int)objtype, &num);
3824 RuntimeHashremovekey(nobjtbl, (int)objtype);
3826 RuntimeHashadd(nobjtbl, (int)objtype, num);
3828 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3832 // ouput all new obj info
3833 iter = RuntimeHashcreateiterator(nobjtbl);
3834 while(RunhasNext(iter)) {
3835 char * objtype = (char *)Runkey(iter);
3836 int num = Runnext(iter);
3837 int nameLen = strlen(objtype);
3838 BAMBOO_DEBUGPRINT(0xddda);
3839 for(j = 0; j < nameLen; j++) {
3840 BAMBOO_DEBUGPRINT_REG(objtype[j]);
3842 BAMBOO_DEBUGPRINT(0xdddb);
3843 BAMBOO_DEBUGPRINT_REG(num);
3846 BAMBOO_DEBUGPRINT(0xdddc);
3849 if(taskInfoOverflow) {
3850 BAMBOO_DEBUGPRINT(0xefee);
3853 // output interrupt related info
3854 for(i = 0; i < interruptInfoIndex; i++) {
3855 InterruptInfo* tmpIInfo = interruptInfoArray[i];
3856 BAMBOO_DEBUGPRINT(0xddde);
3857 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
3858 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
3859 BAMBOO_DEBUGPRINT(0xdddf);
3862 if(interruptInfoOverflow) {
3863 BAMBOO_DEBUGPRINT(0xefef);
3866 BAMBOO_DEBUGPRINT(0xeeee);
3869 #endif // #ifdef PROFILE