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);
124 //gcismapped = false;
133 gcsbstarttbl = BAMBOO_BASE_VA;
134 bamboo_smemtbl = (void *)gcsbstarttbl
135 + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
136 if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
137 int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
138 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
139 gcsharedptbl = mgcsharedhashCreate(t_size,0.30);//allocateGCSharedHash_I(20);
143 BAMBOO_MEMSET_WH(gcrpointertbls,0,sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
144 //sizeof(struct RuntimeHash *)*NUMCORES4GC);
146 // create the lock table, lockresult table and obj queue
149 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
150 /* Set allocation blocks*/
151 locktable.listhead=NULL;
152 locktable.listtail=NULL;
154 locktable.numelements = 0;
159 lockRedirectTbl = allocateRuntimeHash_I(20);
160 objRedirectLockTbl = allocateRuntimeHash_I(20);
165 objqueue.head = NULL;
166 objqueue.tail = NULL;
172 //isInterrupt = true;
176 taskInfoOverflow = false;
178 interruptInfoIndex = 0;
179 interruptInfoOverflow = false;
182 for(i = 0; i < MAXTASKPARAMS; i++) {
183 runtime_locks[i].redirectlock = 0;
184 runtime_locks[i].value = 0;
189 inline __attribute__((always_inline))
190 void disruntimedata() {
193 freeRuntimeHash(gcpointertbl);
194 //freeMGCHash(gcpointertbl);
195 freeMGCHash(gcforwardobjtbl);
196 // for mapping info structures
197 //freeRuntimeHash(gcrcoretbl);
199 freeRuntimeHash(lockRedirectTbl);
200 freeRuntimeHash(objRedirectLockTbl);
201 RUNFREE(locktable.bucket);
203 if(activetasks != NULL) {
204 genfreehashtable(activetasks);
206 if(currtpd != NULL) {
207 RUNFREE(currtpd->parameterArray);
211 BAMBOO_LOCAL_MEM_CLOSE();
212 BAMBOO_SHARE_MEM_CLOSE();
215 inline __attribute__((always_inline))
216 bool checkObjQueue() {
218 struct transObjInfo * objInfo = NULL;
222 #ifdef ACCURATEPROFILE
223 bool isChecking = false;
224 if(!isEmpty(&objqueue)) {
225 profileTaskStart("objqueue checking");
227 } // if(!isEmpty(&objqueue))
231 while(!isEmpty(&objqueue)) {
233 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
235 BAMBOO_DEBUGPRINT(0xf001);
238 //isInterrupt = false;
241 BAMBOO_DEBUGPRINT(0xeee1);
244 objInfo = (struct transObjInfo *)getItem(&objqueue);
245 obj = objInfo->objptr;
247 BAMBOO_DEBUGPRINT_REG((int)obj);
249 // grab lock and flush the obj
253 BAMBOO_WAITING_FOR_LOCK(0);
254 // check for outgoing sends
255 /*if (isMsgHanging) {
256 extern inline void send_hanging_msg(bool);
257 send_hanging_msg(true);
259 } // while(!lockflag)
262 BAMBOO_DEBUGPRINT_REG(grount);
277 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
278 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
279 classsize[((struct ___Object___ *)obj)->type]);
281 // enqueue the object
282 for(k = 0; k < objInfo->length; ++k) {
283 int taskindex = objInfo->queues[2 * k];
284 int paramindex = objInfo->queues[2 * k + 1];
285 struct parameterwrapper ** queues =
286 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
288 BAMBOO_DEBUGPRINT_REG(taskindex);
289 BAMBOO_DEBUGPRINT_REG(paramindex);
290 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
291 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
292 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
293 (long)obj, tmpptr->flag);
295 enqueueObject_I(obj, queues, 1);
297 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
299 } // for(k = 0; k < objInfo->length; ++k)
300 releasewritelock_I(obj);
301 RUNFREE(objInfo->queues);
305 // put it at the end of the queue if no update version in the queue
306 struct QueueItem * qitem = getHead(&objqueue);
307 struct QueueItem * prev = NULL;
308 while(qitem != NULL) {
309 struct transObjInfo * tmpinfo =
310 (struct transObjInfo *)(qitem->objectptr);
311 if(tmpinfo->objptr == obj) {
312 // the same object in the queue, which should be enqueued
313 // recently. Current one is outdate, do not re-enqueue it
314 RUNFREE(objInfo->queues);
319 } // if(tmpinfo->objptr == obj)
320 qitem = getNextQueueItem(prev);
321 } // while(qitem != NULL)
322 // try to execute active tasks already enqueued first
323 addNewItem_I(&objqueue, objInfo);
325 //isInterrupt = true;
328 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
330 BAMBOO_DEBUGPRINT(0xf000);
334 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
336 BAMBOO_DEBUGPRINT(0xf000);
338 } // while(!isEmpty(&objqueue))
341 #ifdef ACCURATEPROFILE
349 BAMBOO_DEBUGPRINT(0xee02);
354 inline __attribute__((always_inline))
355 void checkCoreStatus() {
356 bool allStall = false;
360 (waitconfirm && (numconfirm == 0))) {
362 BAMBOO_DEBUGPRINT(0xee04);
363 BAMBOO_DEBUGPRINT_REG(waitconfirm);
365 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
367 BAMBOO_DEBUGPRINT(0xf001);
369 corestatus[BAMBOO_NUM_OF_CORE] = 0;
370 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
371 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
372 // check the status of all cores
375 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
377 for(i = 0; i < NUMCORESACTIVE; ++i) {
379 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
381 if(corestatus[i] != 0) {
385 } // for(i = 0; i < NUMCORESACTIVE; ++i)
387 // check if the sum of send objs and receive obj are the same
388 // yes->check if the info is the latest; no->go on executing
390 for(i = 0; i < NUMCORESACTIVE; ++i) {
391 sumsendobj += numsendobjs[i];
393 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
395 } // for(i = 0; i < NUMCORESACTIVE; ++i)
396 for(i = 0; i < NUMCORESACTIVE; ++i) {
397 sumsendobj -= numreceiveobjs[i];
399 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
401 } // for(i = 0; i < NUMCORESACTIVE; ++i)
402 if(0 == sumsendobj) {
404 // the first time found all cores stall
405 // send out status confirm msg to all other cores
406 // reset the corestatus array too
408 BAMBOO_DEBUGPRINT(0xee05);
410 corestatus[BAMBOO_NUM_OF_CORE] = 1;
412 numconfirm = NUMCORESACTIVE - 1;
413 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
414 for(i = 1; i < NUMCORESACTIVE; ++i) {
416 // send status confirm msg to core i
417 send_msg_1(i, STATUSCONFIRM, false);
418 } // for(i = 1; i < NUMCORESACTIVE; ++i)
421 // all the core status info are the latest
422 // terminate; for profiling mode, send request to all
423 // other cores to pour out profiling data
425 BAMBOO_DEBUGPRINT(0xee06);
429 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
432 //BAMBOO_DEBUGPRINT_REG(interrupttime);
435 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
436 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
437 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
439 // profile mode, send msgs to other cores to request pouring
440 // out progiling data
442 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
444 BAMBOO_DEBUGPRINT(0xf000);
446 for(i = 1; i < NUMCORESACTIVE; ++i) {
447 // send profile request msg to core i
448 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
449 } // for(i = 1; i < NUMCORESACTIVE; ++i)
450 // pour profiling data on startup core
453 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
455 BAMBOO_DEBUGPRINT(0xf001);
457 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
458 // check the status of all cores
461 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
463 for(i = 0; i < NUMCORESACTIVE; ++i) {
465 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
467 if(profilestatus[i] != 0) {
471 } // for(i = 0; i < NUMCORESACTIVE; ++i)
474 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
476 BAMBOO_DEBUGPRINT(0xf000);
481 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
487 // gc_profile mode, ourput gc prfiling data
490 gc_outputProfileData();
491 #endif // #ifdef GC_PROFILE
492 #endif // #ifdef MULTICORE_GC
494 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
495 terminate(); // All done.
496 } // if(!waitconfirm)
498 // still some objects on the fly on the network
499 // reset the waitconfirm and numconfirm
501 BAMBOO_DEBUGPRINT(0xee07);
505 } // if(0 == sumsendobj)
507 // not all cores are stall, keep on waiting
509 BAMBOO_DEBUGPRINT(0xee08);
514 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
516 BAMBOO_DEBUGPRINT(0xf000);
518 } // if((!waitconfirm) ||
521 // main function for each core
522 inline void run(void * arg) {
526 bool sendStall = false;
528 bool tocontinue = false;
530 corenum = BAMBOO_GET_NUM_OF_CORE();
532 BAMBOO_DEBUGPRINT(0xeeee);
533 BAMBOO_DEBUGPRINT_REG(corenum);
534 BAMBOO_DEBUGPRINT(STARTUPCORE);
537 // initialize runtime data structures
540 // other architecture related initialization
544 initializeexithandler();
546 // main process of the execution module
547 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
548 // non-executing cores, only processing communications
551 BAMBOO_DEBUGPRINT(0xee01);
552 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
553 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
554 profileTaskStart("msg handling");
558 //isInterrupt = false;
562 /* Create queue of active tasks */
564 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
565 (int (*)(void *,void *)) &comparetpd);
567 /* Process task information */
570 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
571 /* Create startup object */
572 createstartupobject(argc, argv);
576 BAMBOO_DEBUGPRINT(0xee00);
581 // check if need to do GC
585 // check if there are new active tasks can be executed
592 while(receiveObject() != -1) {
597 BAMBOO_DEBUGPRINT(0xee01);
600 // check if there are some pending objects,
601 // if yes, enqueue them and executetasks again
602 tocontinue = checkObjQueue();
606 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
609 BAMBOO_DEBUGPRINT(0xee03);
617 BAMBOO_DEBUGPRINT(0xee09);
623 // wait for some time
626 BAMBOO_DEBUGPRINT(0xee0a);
632 // send StallMsg to startup core
634 BAMBOO_DEBUGPRINT(0xee0b);
637 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
638 self_numsendobjs, self_numreceiveobjs, false);
650 BAMBOO_DEBUGPRINT(0xee0c);
653 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
656 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
660 struct ___createstartupobject____I_locals {
663 struct ___StartupObject___ * ___startupobject___;
664 struct ArrayObject * ___stringarray___;
665 }; // struct ___createstartupobject____I_locals
667 void createstartupobject(int argc,
671 /* Allocate startup object */
673 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
674 struct ___StartupObject___ *startupobject=
675 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
676 ___locals___.___startupobject___ = startupobject;
677 struct ArrayObject * stringarray=
678 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
679 ___locals___.___stringarray___ = stringarray;
681 struct ___StartupObject___ *startupobject=
682 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
683 struct ArrayObject * stringarray=
684 allocate_newarray(STRINGARRAYTYPE, argc-1);
686 /* Build array of strings */
687 startupobject->___parameters___=stringarray;
688 for(i=1; i<argc; i++) {
689 int length=strlen(argv[i]);
691 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
693 struct ___String___ *newstring=NewString(argv[i],length);
695 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
699 startupobject->version = 0;
700 startupobject->lock = NULL;
702 /* Set initialized flag for startup object */
703 flagorandinit(startupobject,1,0xFFFFFFFF);
704 enqueueObject(startupobject, NULL, 0);
706 BAMBOO_CACHE_FLUSH_ALL();
710 int hashCodetpd(struct taskparamdescriptor *ftd) {
711 int hash=(int)ftd->task;
713 for(i=0; i<ftd->numParameters; i++) {
714 hash^=(int)ftd->parameterArray[i];
719 int comparetpd(struct taskparamdescriptor *ftd1,
720 struct taskparamdescriptor *ftd2) {
722 if (ftd1->task!=ftd2->task)
724 for(i=0; i<ftd1->numParameters; i++)
725 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
730 /* This function sets a tag. */
732 void tagset(void *ptr,
733 struct ___Object___ * obj,
734 struct ___TagDescriptor___ * tagd) {
736 void tagset(struct ___Object___ * obj,
737 struct ___TagDescriptor___ * tagd) {
739 struct ArrayObject * ao=NULL;
740 struct ___Object___ * tagptr=obj->___tags___;
742 obj->___tags___=(struct ___Object___ *)tagd;
744 /* Have to check if it is already set */
745 if (tagptr->type==TAGTYPE) {
746 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
751 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
752 struct ArrayObject * ao=
753 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
754 obj=(struct ___Object___ *)ptrarray[2];
755 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
756 td=(struct ___TagDescriptor___ *) obj->___tags___;
758 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
761 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
762 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
763 obj->___tags___=(struct ___Object___ *) ao;
764 ao->___cachedCode___=2;
768 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
769 for(i=0; i<ao->___cachedCode___; i++) {
770 struct ___TagDescriptor___ * td=
771 ARRAYGET(ao, struct ___TagDescriptor___*, i);
776 if (ao->___cachedCode___<ao->___length___) {
777 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
778 ao->___cachedCode___++;
781 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
782 struct ArrayObject * aonew=
783 allocate_newarray(&ptrarray,TAGARRAYTYPE,
784 TAGARRAYINTERVAL+ao->___length___);
785 obj=(struct ___Object___ *)ptrarray[2];
786 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
787 ao=(struct ArrayObject *)obj->___tags___;
789 struct ArrayObject * aonew=
790 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
793 aonew->___cachedCode___=ao->___length___+1;
794 for(i=0; i<ao->___length___; i++) {
795 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
796 ARRAYGET(ao, struct ___TagDescriptor___*, i));
798 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
804 struct ___Object___ * tagset=tagd->flagptr;
807 } else if (tagset->type!=OBJECTARRAYTYPE) {
809 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
810 struct ArrayObject * ao=
811 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
812 obj=(struct ___Object___ *)ptrarray[2];
813 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
815 struct ArrayObject * ao=
816 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
818 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
819 ARRAYSET(ao, struct ___Object___ *, 1, obj);
820 ao->___cachedCode___=2;
821 tagd->flagptr=(struct ___Object___ *)ao;
823 struct ArrayObject *ao=(struct ArrayObject *) tagset;
824 if (ao->___cachedCode___<ao->___length___) {
825 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
829 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
830 struct ArrayObject * aonew=
831 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
832 OBJECTARRAYINTERVAL+ao->___length___);
833 obj=(struct ___Object___ *)ptrarray[2];
834 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
835 ao=(struct ArrayObject *)tagd->flagptr;
837 struct ArrayObject * aonew=
838 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
840 aonew->___cachedCode___=ao->___cachedCode___+1;
841 for(i=0; i<ao->___length___; i++) {
842 ARRAYSET(aonew, struct ___Object___*, i,
843 ARRAYGET(ao, struct ___Object___*, i));
845 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
846 tagd->flagptr=(struct ___Object___ *) aonew;
852 /* This function clears a tag. */
854 void tagclear(void *ptr,
855 struct ___Object___ * obj,
856 struct ___TagDescriptor___ * tagd) {
858 void tagclear(struct ___Object___ * obj,
859 struct ___TagDescriptor___ * tagd) {
861 /* We'll assume that tag is alway there.
862 Need to statically check for this of course. */
863 struct ___Object___ * tagptr=obj->___tags___;
865 if (tagptr->type==TAGTYPE) {
866 if ((struct ___TagDescriptor___ *)tagptr==tagd)
867 obj->___tags___=NULL;
869 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
871 for(i=0; i<ao->___cachedCode___; i++) {
872 struct ___TagDescriptor___ * td=
873 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
875 ao->___cachedCode___--;
876 if (i<ao->___cachedCode___)
877 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
878 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
879 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
880 if (ao->___cachedCode___==0)
881 obj->___tags___=NULL;
888 struct ___Object___ *tagset=tagd->flagptr;
889 if (tagset->type!=OBJECTARRAYTYPE) {
893 struct ArrayObject *ao=(struct ArrayObject *) tagset;
895 for(i=0; i<ao->___cachedCode___; i++) {
896 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
898 ao->___cachedCode___--;
899 if (i<ao->___cachedCode___)
900 ARRAYSET(ao, struct ___Object___ *, i,
901 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
902 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
903 if (ao->___cachedCode___==0)
914 /* This function allocates a new tag. */
916 struct ___TagDescriptor___ * allocate_tag(void *ptr,
918 struct ___TagDescriptor___ * v=
919 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
922 struct ___TagDescriptor___ * allocate_tag(int index) {
923 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
932 /* This function updates the flag for object ptr. It or's the flag
933 with the or mask and and's it with the andmask. */
935 void flagbody(struct ___Object___ *ptr,
937 struct parameterwrapper ** queues,
941 int flagcomp(const int *val1, const int *val2) {
942 return (*val1)-(*val2);
945 void flagorand(void * ptr,
948 struct parameterwrapper ** queues,
951 int oldflag=((int *)ptr)[1];
952 int flag=ormask|oldflag;
954 flagbody(ptr, flag, queues, length, false);
958 bool intflagorand(void * ptr,
962 int oldflag=((int *)ptr)[1];
963 int flag=ormask|oldflag;
965 if (flag==oldflag) /* Don't do anything */
968 flagbody(ptr, flag, NULL, 0, false);
974 void flagorandinit(void * ptr,
977 int oldflag=((int *)ptr)[1];
978 int flag=ormask|oldflag;
980 flagbody(ptr,flag,NULL,0,true);
983 void flagbody(struct ___Object___ *ptr,
985 struct parameterwrapper ** vqueues,
988 struct parameterwrapper * flagptr = NULL;
990 struct parameterwrapper ** queues = vqueues;
991 int length = vlength;
994 int * enterflags = NULL;
995 if((!isnew) && (queues == NULL)) {
996 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
997 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
998 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1005 /*Remove object from all queues */
1006 for(i = 0; i < length; ++i) {
1007 flagptr = queues[i];
1008 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1009 (int *) &enterflags, &UNUSED, &UNUSED2);
1010 ObjectHashremove(flagptr->objectset, (int)ptr);
1011 if (enterflags!=NULL)
1012 RUNFREE(enterflags);
1016 void enqueueObject(void * vptr,
1017 struct parameterwrapper ** vqueues,
1019 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1022 //struct QueueItem *tmpptr;
1023 struct parameterwrapper * parameter=NULL;
1026 struct parameterwrapper * prevptr=NULL;
1027 struct ___Object___ *tagptr=NULL;
1028 struct parameterwrapper ** queues = vqueues;
1029 int length = vlength;
1030 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1033 if(queues == NULL) {
1034 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1035 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1037 tagptr=ptr->___tags___;
1039 /* Outer loop iterates through all parameter queues an object of
1040 this type could be in. */
1041 for(j = 0; j < length; ++j) {
1042 parameter = queues[j];
1044 if (parameter->numbertags>0) {
1046 goto nextloop; //that means the object has no tag
1047 //but that param needs tag
1048 else if(tagptr->type==TAGTYPE) { //one tag
1049 //struct ___TagDescriptor___ * tag=
1050 //(struct ___TagDescriptor___*) tagptr;
1051 for(i=0; i<parameter->numbertags; i++) {
1052 //slotid is parameter->tagarray[2*i];
1053 int tagid=parameter->tagarray[2*i+1];
1054 if (tagid!=tagptr->flag)
1055 goto nextloop; /*We don't have this tag */
1057 } else { //multiple tags
1058 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1059 for(i=0; i<parameter->numbertags; i++) {
1060 //slotid is parameter->tagarray[2*i];
1061 int tagid=parameter->tagarray[2*i+1];
1063 for(j=0; j<ao->___cachedCode___; j++) {
1064 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1075 for(i=0; i<parameter->numberofterms; i++) {
1076 int andmask=parameter->intarray[i*2];
1077 int checkmask=parameter->intarray[i*2+1];
1078 if ((ptr->flag&andmask)==checkmask) {
1079 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1090 void enqueueObject_I(void * vptr,
1091 struct parameterwrapper ** vqueues,
1093 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1096 //struct QueueItem *tmpptr;
1097 struct parameterwrapper * parameter=NULL;
1100 struct parameterwrapper * prevptr=NULL;
1101 struct ___Object___ *tagptr=NULL;
1102 struct parameterwrapper ** queues = vqueues;
1103 int length = vlength;
1104 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1107 if(queues == NULL) {
1108 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1109 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1111 tagptr=ptr->___tags___;
1113 /* Outer loop iterates through all parameter queues an object of
1114 this type could be in. */
1115 for(j = 0; j < length; ++j) {
1116 parameter = queues[j];
1118 if (parameter->numbertags>0) {
1120 goto nextloop; //that means the object has no tag
1121 //but that param needs tag
1122 else if(tagptr->type==TAGTYPE) { //one tag
1123 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1124 for(i=0; i<parameter->numbertags; i++) {
1125 //slotid is parameter->tagarray[2*i];
1126 int tagid=parameter->tagarray[2*i+1];
1127 if (tagid!=tagptr->flag)
1128 goto nextloop; /*We don't have this tag */
1130 } else { //multiple tags
1131 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1132 for(i=0; i<parameter->numbertags; i++) {
1133 //slotid is parameter->tagarray[2*i];
1134 int tagid=parameter->tagarray[2*i+1];
1136 for(j=0; j<ao->___cachedCode___; j++) {
1137 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1148 for(i=0; i<parameter->numberofterms; i++) {
1149 int andmask=parameter->intarray[i*2];
1150 int checkmask=parameter->intarray[i*2+1];
1151 if ((ptr->flag&andmask)==checkmask) {
1152 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1164 int * getAliasLock(void ** ptrs,
1166 struct RuntimeHash * tbl) {
1168 return (int*)(RUNMALLOC(sizeof(int)));
1173 bool redirect = false;
1174 int redirectlock = 0;
1175 for(; i < length; i++) {
1176 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1179 if(ptr->lock == NULL) {
1182 lock = (int)(ptr->lock);
1185 if(lock != redirectlock) {
1186 RuntimeHashadd(tbl, lock, redirectlock);
1189 if(RuntimeHashcontainskey(tbl, lock)) {
1190 // already redirected
1192 RuntimeHashget(tbl, lock, &redirectlock);
1193 for(; j < locklen; j++) {
1194 if(locks[j] != redirectlock) {
1195 RuntimeHashadd(tbl, locks[j], redirectlock);
1200 for(j = 0; j < locklen; j++) {
1201 if(locks[j] == lock) {
1204 } else if(locks[j] > lock) {
1211 locks[h] = locks[h-1];
1220 return (int *)redirectlock;
1222 return (int *)(locks[0]);
1227 void addAliasLock(void * ptr,
1229 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1230 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1231 // originally no alias lock associated or have a different alias lock
1232 // flush it as the new one
1233 obj->lock = (int *)lock;
1238 inline void setTaskExitIndex(int index) {
1239 taskInfoArray[taskInfoIndex]->exitIndex = index;
1242 inline void addNewObjInfo(void * nobj) {
1243 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1244 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1246 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1251 void * localmalloc_I(int coren,
1257 int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1258 int totest = tofindb;
1259 int bound = BAMBOO_SMEM_SIZE_L;
1263 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1264 int nsize = bamboo_smemtbl[totest];
1265 bool islocal = true;
1267 bool tocheck = true;
1268 // have some space in the block
1269 if(totest == tofindb) {
1270 // the first partition
1271 size = bound - nsize;
1272 } else if(nsize == 0) {
1273 // an empty partition, can be appended
1276 // not an empty partition, can not be appended
1277 // the last continuous block is not big enough, go to check the next
1281 } // if(totest == tofindb) else if(nsize == 0) else ...
1284 // have enough space in the block, malloc
1288 // no enough space yet, try to append next continuous block
1290 } // if(size > isize) else ...
1292 } // if(nsize < bound)
1294 // no space in the block, go to check the next block
1300 tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1303 } // if(islocal) else ...
1304 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1305 // no more local mem, do not find suitable block
1308 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1311 if(foundsmem == 1) {
1312 // find suitable block
1313 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1314 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1315 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1317 // set bamboo_smemtbl
1318 for(i = tofindb; i <= totest; i++) {
1319 bamboo_smemtbl[i]=(i<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1321 } else if(foundsmem == 2) {
1322 // no suitable block
1327 } // void * localmalloc_I(int, int, int *)
1329 void * globalmalloc_I(int coren,
1333 int tofindb = bamboo_free_block; //0;
1334 int totest = tofindb;
1335 int bound = BAMBOO_SMEM_SIZE_L;
1338 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1343 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1344 int nsize = bamboo_smemtbl[totest];
1345 bool isnext = false;
1347 bool tocheck = true;
1348 // have some space in the block
1349 if(totest == tofindb) {
1350 // the first partition
1351 size = bound - nsize;
1352 } else if(nsize == 0) {
1353 // an empty partition, can be appended
1356 // not an empty partition, can not be appended
1357 // the last continuous block is not big enough, start another block
1360 } // if(totest == tofindb) else if(nsize == 0) else ...
1363 // have enough space in the block, malloc
1366 } // if(size > isize)
1370 } // if(nsize < bound) else ...
1372 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1373 // no more local mem, do not find suitable block
1376 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1378 // start another block
1383 if(foundsmem == 1) {
1384 // find suitable block
1385 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1386 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1387 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1389 // set bamboo_smemtbl
1390 for(int i = tofindb; i <= totest; i++) {
1391 bamboo_smemtbl[i]=(i<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1393 if(tofindb == bamboo_free_block) {
1394 bamboo_free_block = totest+1;
1396 } else if(foundsmem == 2) {
1397 // no suitable block
1403 } // void * globalmalloc_I(int, int, int *)
1404 #endif // #ifdef MULTICORE_GC
1406 // malloc from the shared memory
1407 void * smemalloc_I(int coren,
1412 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1414 // go through the bamboo_smemtbl for suitable partitions
1415 switch(bamboo_smem_mode) {
1417 mem = localmalloc_I(coren, isize, allocsize);
1422 // TODO not supported yet
1423 BAMBOO_EXIT(0xe001);
1428 // TODO not supported yet
1429 BAMBOO_EXIT(0xe002);
1434 mem = globalmalloc_I(coren, isize, allocsize);
1446 /*if(!interruptInfoOverflow) {
1447 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1448 interruptInfoArray[interruptInfoIndex] = intInfo;
1449 intInfo->startTime = BAMBOO_GET_EXE_TIME();
1450 intInfo->endTime = -1;
1453 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1454 //mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1455 if(toallocate > bamboo_free_smem_size) {
1459 mem = (void *)bamboo_free_smemp;
1460 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1461 bamboo_free_smem_size -= toallocate;
1462 //BAMBOO_MEMSET_WH(mem, '\0', toallocate);
1464 *allocsize = toallocate;
1466 /*if(!interruptInfoOverflow) {
1467 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1468 interruptInfoIndex++;
1469 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1470 interruptInfoOverflow = true;
1475 #endif // MULTICORE_GC
1476 // no enough shared global memory
1482 BAMBOO_DEBUGPRINT(0xa001);
1483 BAMBOO_EXIT(0xa001);
1487 } // void * smemalloc_I(int, int, int)
1489 INLINE int checkMsgLength_I(int size) {
1492 BAMBOO_DEBUGPRINT(0xcccc);
1495 int type = msgdata[msgdataindex];
1502 case GCSTARTMAPINFO:
1516 case GCSTARTCOMPACT:
1519 case GCFINISHMAPINFO:
1544 case REDIRECTGROUNT:
1546 case REDIRECTRELEASE:
1559 case GCFINISHCOMPACT:
1573 case TRANSOBJ: // nonfixed size
1579 msglength = msgdata[msgdataindex+1];
1588 BAMBOO_DEBUGPRINT_REG(type);
1589 BAMBOO_DEBUGPRINT_REG(size);
1590 BAMBOO_DEBUGPRINT_REG(msgdataindex);
1591 BAMBOO_DEBUGPRINT_REG(msgdatalast);
1592 BAMBOO_DEBUGPRINT_REG(msgdatafull);
1595 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1597 BAMBOO_EXIT(0xd005);
1603 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1608 BAMBOO_DEBUGPRINT(0xffff);
1614 INLINE void processmsg_transobj_I() {
1616 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
1620 BAMBOO_DEBUGPRINT(0xe880);
1623 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1625 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
1627 BAMBOO_EXIT(0xa002);
1629 // store the object and its corresponding queue info, enqueue it later
1630 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
1632 transObj->length = (msglength - 3) / 2;
1633 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1634 for(k = 0; k < transObj->length; ++k) {
1635 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
1639 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1642 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
1646 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1650 // check if there is an existing duplicate item
1652 struct QueueItem * qitem = getHead(&objqueue);
1653 struct QueueItem * prev = NULL;
1654 while(qitem != NULL) {
1655 struct transObjInfo * tmpinfo =
1656 (struct transObjInfo *)(qitem->objectptr);
1657 if(tmpinfo->objptr == transObj->objptr) {
1658 // the same object, remove outdate one
1659 RUNFREE(tmpinfo->queues);
1661 removeItem(&objqueue, qitem);
1667 qitem = getHead(&objqueue);
1669 qitem = getNextQueueItem(prev);
1672 addNewItem_I(&objqueue, (void *)transObj);
1674 ++(self_numreceiveobjs);
1677 INLINE void processmsg_transtall_I() {
1678 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1679 // non startup core can not receive stall msg
1681 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
1683 BAMBOO_EXIT(0xa003);
1685 int num_core = msgdata[msgdataindex]; //[1]
1687 if(num_core < NUMCORESACTIVE) {
1690 BAMBOO_DEBUGPRINT(0xe881);
1693 corestatus[num_core] = 0;
1694 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
1696 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
1701 #ifndef MULTICORE_GC
1702 INLINE void processmsg_lockrequest_I() {
1703 // check to see if there is a lock exist for the required obj
1704 // msgdata[1] -> lock type
1705 int locktype = msgdata[msgdataindex]; //[1];
1707 int data2 = msgdata[msgdataindex]; // obj pointer
1709 int data3 = msgdata[msgdataindex]; // lock
1711 int data4 = msgdata[msgdataindex]; // request core
1713 // -1: redirected, 0: approved, 1: denied
1714 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
1716 // this lock request is redirected
1719 // send response msg
1720 // for 32 bit machine, the size is always 4 words, cache the msg first
1721 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
1722 if(BAMBOO_CHECK_SEND_MODE()) {
1723 cache_msg_4(data4, tmp, locktype, data2, data3);
1725 send_msg_4(data4, tmp, locktype, data2, data3, true);
1730 INLINE void processmsg_lockgrount_I() {
1732 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1734 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
1736 BAMBOO_EXIT(0xa004);
1738 int data2 = msgdata[msgdataindex];
1740 int data3 = msgdata[msgdataindex];
1742 if((lockobj == data2) && (lock2require == data3)) {
1745 BAMBOO_DEBUGPRINT(0xe882);
1754 // conflicts on lockresults
1756 BAMBOO_DEBUGPRINT_REG(data2);
1758 BAMBOO_EXIT(0xa005);
1762 INLINE void processmsg_lockdeny_I() {
1764 int data2 = msgdata[msgdataindex];
1766 int data3 = msgdata[msgdataindex];
1768 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1770 BAMBOO_DEBUGPRINT_REG(data2);
1772 BAMBOO_EXIT(0xa006);
1774 if((lockobj == data2) && (lock2require == data3)) {
1777 BAMBOO_DEBUGPRINT(0xe883);
1786 // conflicts on lockresults
1788 BAMBOO_DEBUGPRINT_REG(data2);
1790 BAMBOO_EXIT(0xa007);
1794 INLINE void processmsg_lockrelease_I() {
1795 int data1 = msgdata[msgdataindex];
1797 int data2 = msgdata[msgdataindex];
1799 // receive lock release msg
1800 processlockrelease(data1, data2, 0, false);
1803 INLINE void processmsg_redirectlock_I() {
1804 // check to see if there is a lock exist for the required obj
1805 int data1 = msgdata[msgdataindex];
1806 MSG_INDEXINC_I(); //msgdata[1]; // lock type
1807 int data2 = msgdata[msgdataindex];
1808 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
1809 int data3 = msgdata[msgdataindex];
1810 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
1811 int data4 = msgdata[msgdataindex];
1812 MSG_INDEXINC_I(); //msgdata[4]; // root request core
1813 int data5 = msgdata[msgdataindex];
1814 MSG_INDEXINC_I(); //msgdata[5]; // request core
1815 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
1817 // this lock request is redirected
1820 // send response msg
1821 // for 32 bit machine, the size is always 4 words, cache the msg first
1822 if(BAMBOO_CHECK_SEND_MODE()) {
1823 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
1824 data1, data2, data3);
1826 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1827 data1, data2, data3, true);
1832 INLINE void processmsg_redirectgrount_I() {
1834 int data2 = msgdata[msgdataindex];
1836 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1838 BAMBOO_DEBUGPRINT_REG(data2);
1840 BAMBOO_EXIT(0xa00a);
1842 if(lockobj == data2) {
1845 BAMBOO_DEBUGPRINT(0xe891);
1848 int data3 = msgdata[msgdataindex];
1852 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
1857 // conflicts on lockresults
1859 BAMBOO_DEBUGPRINT_REG(data2);
1861 BAMBOO_EXIT(0xa00b);
1865 INLINE void processmsg_redirectdeny_I() {
1867 int data2 = msgdata[msgdataindex];
1869 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1871 BAMBOO_DEBUGPRINT_REG(data2);
1873 BAMBOO_EXIT(0xa00c);
1875 if(lockobj == data2) {
1878 BAMBOO_DEBUGPRINT(0xe892);
1887 // conflicts on lockresults
1889 BAMBOO_DEBUGPRINT_REG(data2);
1891 BAMBOO_EXIT(0xa00d);
1895 INLINE void processmsg_redirectrelease_I() {
1896 int data1 = msgdata[msgdataindex];
1898 int data2 = msgdata[msgdataindex];
1900 int data3 = msgdata[msgdataindex];
1902 processlockrelease(data1, data2, data3, true);
1904 #endif // #ifndef MULTICORE_GC
1907 INLINE void processmsg_profileoutput_I() {
1908 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1909 // startup core can not receive profile output finish msg
1910 BAMBOO_EXIT(0xa008);
1914 BAMBOO_DEBUGPRINT(0xe885);
1918 totalexetime = msgdata[msgdataindex]; //[1]
1920 outputProfileData();
1921 // cache the msg first
1922 if(BAMBOO_CHECK_SEND_MODE()) {
1923 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1925 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
1929 INLINE void processmsg_profilefinish_I() {
1930 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1931 // non startup core can not receive profile output finish msg
1933 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
1935 BAMBOO_EXIT(0xa009);
1939 BAMBOO_DEBUGPRINT(0xe886);
1942 int data1 = msgdata[msgdataindex];
1944 profilestatus[data1] = 0;
1946 #endif // #ifdef PROFILE
1948 INLINE void processmsg_statusconfirm_I() {
1949 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1950 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1951 // wrong core to receive such msg
1952 BAMBOO_EXIT(0xa00e);
1954 // send response msg
1957 BAMBOO_DEBUGPRINT(0xe887);
1960 // cache the msg first
1961 if(BAMBOO_CHECK_SEND_MODE()) {
1962 cache_msg_5(STARTUPCORE, STATUSREPORT,
1963 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
1964 self_numsendobjs, self_numreceiveobjs);
1966 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
1967 BAMBOO_NUM_OF_CORE, self_numsendobjs,
1968 self_numreceiveobjs, true);
1973 INLINE void processmsg_statusreport_I() {
1974 int data1 = msgdata[msgdataindex];
1976 int data2 = msgdata[msgdataindex];
1978 int data3 = msgdata[msgdataindex];
1980 int data4 = msgdata[msgdataindex];
1982 // receive a status confirm info
1983 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1984 // wrong core to receive such msg
1986 BAMBOO_DEBUGPRINT_REG(data2);
1988 BAMBOO_EXIT(0xa00f);
1992 BAMBOO_DEBUGPRINT(0xe888);
1998 corestatus[data2] = data1;
1999 numsendobjs[data2] = data3;
2000 numreceiveobjs[data2] = data4;
2004 INLINE void processmsg_terminate_I() {
2007 BAMBOO_DEBUGPRINT(0xe889);
2014 INLINE void processmsg_memrequest_I() {
2016 if(!interruptInfoOverflow) {
2017 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2018 interruptInfoArray[interruptInfoIndex] = intInfo;
2019 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2020 intInfo->endTime = -1;
2023 int data1 = msgdata[msgdataindex];
2025 int data2 = msgdata[msgdataindex];
2027 // receive a shared memory request msg
2028 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2029 // wrong core to receive such msg
2031 BAMBOO_DEBUGPRINT_REG(data2);
2033 BAMBOO_EXIT(0xa010);
2037 BAMBOO_DEBUGPRINT(0xe88a);
2044 // is currently doing gc, dump this msg
2045 if(INITPHASE == gcphase) {
2046 // if still in the initphase of gc, send a startinit msg again,
2047 // cache the msg first
2048 if(BAMBOO_CHECK_SEND_MODE()) {
2049 cache_msg_1(data2, GCSTARTINIT);
2051 send_msg_1(data2, GCSTARTINIT, true);
2056 mem = smemalloc_I(data2, data1, &allocsize);
2058 // send the start_va to request core, cache the msg first
2059 if(BAMBOO_CHECK_SEND_MODE()) {
2060 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2062 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2064 } // if mem == NULL, the gcflag of the startup core has been set
2065 // and the gc should be started later, then a GCSTARTINIT msg
2066 // will be sent to the requesting core to notice it to start gc
2067 // and try malloc again
2073 if(!interruptInfoOverflow) {
2074 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2075 interruptInfoIndex++;
2076 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2077 interruptInfoOverflow = true;
2083 INLINE void processmsg_memresponse_I() {
2084 int data1 = msgdata[msgdataindex];
2086 int data2 = msgdata[msgdataindex];
2088 // receive a shared memory response msg
2091 BAMBOO_DEBUGPRINT(0xe88b);
2095 // if is currently doing gc, dump this msg
2099 bamboo_smem_size = 0;
2103 // fill header to store the size of this mem block
2104 memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2105 (*((int*)data1)) = data2;
2106 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2107 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2109 bamboo_smem_size = data2;
2110 bamboo_cur_msp =(void*)(data1);
2120 INLINE void processmsg_gcstartinit_I() {
2122 gcphase = INITPHASE;
2124 // is waiting for response of mem request
2125 // let it return NULL and start gc
2126 bamboo_smem_size = 0;
2127 bamboo_cur_msp = NULL;
2132 INLINE void processmsg_gcstart_I() {
2135 BAMBOO_DEBUGPRINT(0xe88c);
2139 gcphase = MARKPHASE;
2142 INLINE void processmsg_gcstartcompact_I() {
2143 gcblock2fill = msgdata[msgdataindex];
2144 MSG_INDEXINC_I(); //msgdata[1];
2145 gcphase = COMPACTPHASE;
2148 INLINE void processmsg_gcstartmapinfo_I() {
2152 INLINE void processmsg_gcstartflush_I() {
2153 gcphase = FLUSHPHASE;
2156 INLINE void processmsg_gcfinishinit_I() {
2157 int data1 = msgdata[msgdataindex];
2159 // received a init phase finish msg
2160 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2161 // non startup core can not receive this msg
2163 BAMBOO_DEBUGPRINT_REG(data1);
2165 BAMBOO_EXIT(0xb001);
2168 BAMBOO_DEBUGPRINT(0xe88c);
2169 BAMBOO_DEBUGPRINT_REG(data1);
2171 // All cores should do init GC
2172 if(data1 < NUMCORESACTIVE) {
2173 gccorestatus[data1] = 0;
2177 INLINE void processmsg_gcfinishmark_I() {
2178 int data1 = msgdata[msgdataindex];
2180 int data2 = msgdata[msgdataindex];
2182 int data3 = msgdata[msgdataindex];
2184 // received a mark phase finish msg
2185 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2186 // non startup core can not receive this msg
2188 BAMBOO_DEBUGPRINT_REG(data1);
2190 BAMBOO_EXIT(0xb002);
2192 // all cores should do mark
2193 if(data1 < NUMCORESACTIVE) {
2194 gccorestatus[data1] = 0;
2195 gcnumsendobjs[data1] = data2;
2196 gcnumreceiveobjs[data1] = data3;
2200 INLINE void processmsg_gcfinishcompact_I() {
2201 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2202 // non startup core can not receive this msg
2205 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2207 BAMBOO_EXIT(0xb003);
2209 int cnum = msgdata[msgdataindex];
2210 MSG_INDEXINC_I(); //msgdata[1];
2211 int filledblocks = msgdata[msgdataindex];
2212 MSG_INDEXINC_I(); //msgdata[2];
2213 int heaptop = msgdata[msgdataindex];
2214 MSG_INDEXINC_I(); //msgdata[3];
2215 int data4 = msgdata[msgdataindex];
2216 MSG_INDEXINC_I(); //msgdata[4];
2217 // only gc cores need to do compact
2218 if(cnum < NUMCORES4GC) {
2219 if(COMPACTPHASE == gcphase) {
2220 gcfilledblocks[cnum] = filledblocks;
2221 gcloads[cnum] = heaptop;
2228 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2229 // cache the msg first
2230 if(BAMBOO_CHECK_SEND_MODE()) {
2231 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2233 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2237 gccorestatus[cnum] = 0;
2239 } // if(cnum < NUMCORES4GC)
2242 INLINE void processmsg_gcfinishmapinfo_I() {
2243 int data1 = msgdata[msgdataindex];
2245 // received a map phase finish msg
2246 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2247 // non startup core can not receive this msg
2250 BAMBOO_DEBUGPRINT_REG(data1);
2252 BAMBOO_EXIT(0xb004);
2254 // all cores should do flush
2255 if(data1 < NUMCORES4GC) {
2256 gccorestatus[data1] = 0;
2261 INLINE void processmsg_gcfinishflush_I() {
2262 int data1 = msgdata[msgdataindex];
2264 // received a flush phase finish msg
2265 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2266 // non startup core can not receive this msg
2269 BAMBOO_DEBUGPRINT_REG(data1);
2271 BAMBOO_EXIT(0xb005);
2273 // all cores should do flush
2274 if(data1 < NUMCORESACTIVE) {
2275 gccorestatus[data1] = 0;
2279 INLINE void processmsg_gcmarkconfirm_I() {
2280 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2281 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2282 // wrong core to receive such msg
2283 BAMBOO_EXIT(0xb006);
2285 // send response msg, cahce the msg first
2286 if(BAMBOO_CHECK_SEND_MODE()) {
2287 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2288 gcbusystatus, gcself_numsendobjs,
2289 gcself_numreceiveobjs);
2291 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2292 gcbusystatus, gcself_numsendobjs,
2293 gcself_numreceiveobjs, true);
2298 INLINE void processmsg_gcmarkreport_I() {
2299 int data1 = msgdata[msgdataindex];
2301 int data2 = msgdata[msgdataindex];
2303 int data3 = msgdata[msgdataindex];
2305 int data4 = msgdata[msgdataindex];
2307 // received a marked phase finish confirm response msg
2308 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2309 // wrong core to receive such msg
2311 BAMBOO_DEBUGPRINT_REG(data2);
2313 BAMBOO_EXIT(0xb007);
2318 gccorestatus[data1] = data2;
2319 gcnumsendobjs[data1] = data3;
2320 gcnumreceiveobjs[data1] = data4;
2324 INLINE void processmsg_gcmarkedobj_I() {
2325 int data1 = msgdata[msgdataindex];
2327 // received a markedObj msg
2328 if(((int *)data1)[6] == INIT) {
2329 // this is the first time that this object is discovered,
2330 // set the flag as DISCOVERED
2331 ((int *)data1)[6] |= DISCOVERED;
2332 gc_enqueue_I(data1);
2334 // set the remote flag
2335 ((int *)data1)[6] |= REMOTEM;
2336 gcself_numreceiveobjs++;
2337 gcbusystatus = true;
2340 INLINE void processmsg_gcmovestart_I() {
2342 gcdstcore = msgdata[msgdataindex];
2343 MSG_INDEXINC_I(); //msgdata[1];
2344 gcmovestartaddr = msgdata[msgdataindex];
2345 MSG_INDEXINC_I(); //msgdata[2];
2346 gcblock2fill = msgdata[msgdataindex];
2347 MSG_INDEXINC_I(); //msgdata[3];
2350 INLINE void processmsg_gcmaprequest_I() {
2352 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2354 void * dstptr = NULL;
2355 int data1 = msgdata[msgdataindex];
2357 //dstptr = mgchashSearch(msgdata[1]);
2359 // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2361 RuntimeHashget(gcpointertbl, data1, &dstptr);
2363 // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2365 int data2 = msgdata[msgdataindex];
2367 //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2369 // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2371 if(NULL == dstptr) {
2372 // no such pointer in this core, something is wrong
2374 BAMBOO_DEBUGPRINT_REG(data1);
2375 BAMBOO_DEBUGPRINT_REG(data2);
2377 BAMBOO_EXIT(0xb009);
2378 //assume that the object was not moved, use the original address
2379 /*if(isMsgSending) {
2380 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2382 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2385 // send back the mapping info, cache the msg first
2386 if(BAMBOO_CHECK_SEND_MODE()) {
2387 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2389 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2393 // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2394 //num_mapinforequest_i++;
2398 INLINE void processmsg_gcmapinfo_I() {
2400 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2402 int data1 = msgdata[msgdataindex];
2405 if(data1 != gcobj2map) {
2406 // obj not matched, something is wrong
2408 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2409 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2411 BAMBOO_EXIT(0xb00a);
2414 gcmappedobj = msgdata[msgdataindex]; // [2]
2416 //mgchashReplace_I(msgdata[1], msgdata[2]);
2417 //mgchashInsert_I(gcobj2map, gcmappedobj);
2418 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2419 /*struct nodemappinginfo * nodeinfo =
2420 (struct nodemappinginfo *)RUNMALLOC_I(sizeof(struct nodemappinginfo));
2421 nodeinfo->ptr = (void *)gcmappedobj;
2422 nodeinfo->cores = NULL;
2423 RuntimeHashadd_I(gcpointertbl, data1, (int)nodeinfo);*/
2424 //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2426 if(data1 == gcobj2map) {
2430 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2434 INLINE void processmsg_gcmaptbl_I() {
2435 int data1 = msgdata[msgdataindex];
2437 int data2 = msgdata[msgdataindex];
2439 gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
2442 INLINE void processmsg_gclobjinfo_I() {
2445 int data1 = msgdata[msgdataindex];
2447 int data2 = msgdata[msgdataindex];
2449 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2451 BAMBOO_DEBUGPRINT_REG(data2);
2453 BAMBOO_EXIT(0xb00b);
2455 // store the mark result info
2457 gcloads[cnum] = msgdata[msgdataindex];
2458 MSG_INDEXINC_I(); // msgdata[3];
2459 int data4 = msgdata[msgdataindex];
2461 if(gcheaptop < data4) {
2464 // large obj info here
2465 for(int k = 5; k < data1; ) {
2466 int lobj = msgdata[msgdataindex];
2467 MSG_INDEXINC_I(); //msgdata[k++];
2468 int length = msgdata[msgdataindex];
2469 MSG_INDEXINC_I(); //msgdata[k++];
2470 gc_lobjenqueue_I(lobj, length, cnum);
2472 } // for(int k = 5; k < msgdata[1];)
2475 INLINE void processmsg_gclobjmapping_I() {
2476 int data1 = msgdata[msgdataindex];
2478 int data2 = msgdata[msgdataindex];
2480 //mgchashInsert_I(msgdata[1], msgdata[2]);
2481 RuntimeHashadd_I(gcpointertbl, data1, data2);
2482 mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
2483 //GCSharedHashadd_I(gcsharedptbl, data1, data2);
2484 //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2486 #endif // #ifdef MULTICORE_GC
2488 // receive object transferred from other cores
2489 // or the terminate message from other cores
2490 // Should be invoked in critical sections!!
2491 // NOTICE: following format is for threadsimulate version only
2492 // RAW version please see previous description
2493 // format: type + object
2494 // type: -1--stall msg
2496 // return value: 0--received an object
2497 // 1--received nothing
2498 // 2--received a Stall Msg
2499 // 3--received a lock Msg
2500 // RAW version: -1 -- received nothing
2501 // otherwise -- received msg type
2502 int receiveObject(int send_port_pending) {
2504 // get the incoming msgs
2505 if(receiveMsg(send_port_pending) == -1) {
2509 // processing received msgs
2511 MSG_REMAINSIZE_I(&size);
2512 if((size == 0) || (checkMsgLength_I(size) == -1)) {
2514 // have new coming msg
2515 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
2522 if(msglength <= size) {
2523 // have some whole msg
2524 //if(msgdataindex == msglength) {
2525 // received a whole msg
2527 type = msgdata[msgdataindex]; //[0]
2529 msgdatafull = false;
2531 //tprintf("msg type: %x\n", type);
2534 // receive a object transfer msg
2535 processmsg_transobj_I();
2540 // receive a stall msg
2541 processmsg_transtall_I();
2545 // GC version have no lock msgs
2546 #ifndef MULTICORE_GC
2548 // receive lock request msg, handle it right now
2549 processmsg_lockrequest_I();
2551 } // case LOCKREQUEST
2554 // receive lock grount msg
2555 processmsg_lockgrount_I();
2557 } // case LOCKGROUNT
2560 // receive lock deny msg
2561 processmsg_lockdeny_I();
2566 processmsg_lockrelease_I();
2568 } // case LOCKRELEASE
2569 #endif // #ifndef MULTICORE_GC
2572 case PROFILEOUTPUT: {
2573 // receive an output profile data request msg
2574 processmsg_profileoutput_I();
2576 } // case PROFILEOUTPUT
2578 case PROFILEFINISH: {
2579 // receive a profile output finish msg
2580 processmsg_profilefinish_I();
2582 } // case PROFILEFINISH
2583 #endif // #ifdef PROFILE
2585 // GC version has no lock msgs
2586 #ifndef MULTICORE_GC
2587 case REDIRECTLOCK: {
2588 // receive a redirect lock request msg, handle it right now
2589 processmsg_redirectlock_I();
2591 } // case REDIRECTLOCK
2593 case REDIRECTGROUNT: {
2594 // receive a lock grant msg with redirect info
2595 processmsg_redirectgrount_I();
2597 } // case REDIRECTGROUNT
2599 case REDIRECTDENY: {
2600 // receive a lock deny msg with redirect info
2601 processmsg_redirectdeny_I();
2603 } // case REDIRECTDENY
2605 case REDIRECTRELEASE: {
2606 // receive a lock release msg with redirect info
2607 processmsg_redirectrelease_I();
2609 } // case REDIRECTRELEASE
2610 #endif // #ifndef MULTICORE_GC
2612 case STATUSCONFIRM: {
2613 // receive a status confirm info
2614 processmsg_statusconfirm_I();
2616 } // case STATUSCONFIRM
2618 case STATUSREPORT: {
2619 processmsg_statusreport_I();
2621 } // case STATUSREPORT
2624 // receive a terminate msg
2625 processmsg_terminate_I();
2630 processmsg_memrequest_I();
2632 } // case MEMREQUEST
2635 processmsg_memresponse_I();
2637 } // case MEMRESPONSE
2642 processmsg_gcstartinit_I();
2644 } // case GCSTARTINIT
2647 // receive a start GC msg
2648 processmsg_gcstart_I();
2652 case GCSTARTCOMPACT: {
2653 // a compact phase start msg
2654 processmsg_gcstartcompact_I();
2656 } // case GCSTARTCOMPACT
2658 case GCSTARTMAPINFO: {
2659 // received a flush phase start msg
2660 processmsg_gcstartmapinfo_I();
2662 } // case GCSTARTFLUSH
2664 case GCSTARTFLUSH: {
2665 // received a flush phase start msg
2666 processmsg_gcstartflush_I();
2668 } // case GCSTARTFLUSH
2670 case GCFINISHINIT: {
2671 processmsg_gcfinishinit_I();
2673 } // case GCFINISHINIT
2675 case GCFINISHMARK: {
2676 processmsg_gcfinishmark_I();
2678 } // case GCFINISHMARK
2680 case GCFINISHCOMPACT: {
2681 // received a compact phase finish msg
2682 processmsg_gcfinishcompact_I();
2684 } // case GCFINISHCOMPACT
2686 case GCFINISHMAPINFO: {
2687 processmsg_gcfinishmapinfo_I();
2689 } // case GCFINISHMAPINFO
2691 case GCFINISHFLUSH: {
2692 processmsg_gcfinishflush_I();
2694 } // case GCFINISHFLUSH
2697 // received a GC finish msg
2698 gcphase = FINISHPHASE;
2702 case GCMARKCONFIRM: {
2703 // received a marked phase finish confirm request msg
2704 // all cores should do mark
2705 processmsg_gcmarkconfirm_I();
2707 } // case GCMARKCONFIRM
2709 case GCMARKREPORT: {
2710 processmsg_gcmarkreport_I();
2712 } // case GCMARKREPORT
2715 processmsg_gcmarkedobj_I();
2717 } // case GCMARKEDOBJ
2720 // received a start moving objs msg
2721 processmsg_gcmovestart_I();
2723 } // case GCMOVESTART
2725 case GCMAPREQUEST: {
2726 // received a mapping info request msg
2727 processmsg_gcmaprequest_I();
2729 } // case GCMAPREQUEST
2732 // received a mapping info response msg
2733 processmsg_gcmapinfo_I();
2738 // received a mapping tbl response msg
2739 processmsg_gcmaptbl_I();
2743 case GCLOBJREQUEST: {
2744 // received a large objs info request msg
2745 transferMarkResults_I();
2747 } // case GCLOBJREQUEST
2750 // received a large objs info response msg
2751 processmsg_gclobjinfo_I();
2753 } // case GCLOBJINFO
2755 case GCLOBJMAPPING: {
2756 // received a large obj mapping info msg
2757 processmsg_gclobjmapping_I();
2759 } // case GCLOBJMAPPING
2761 #endif // #ifdef MULTICORE_GC
2766 //memset(msgdata, '\0', sizeof(int) * msgdataindex);
2768 msglength = BAMBOO_MSG_BUF_LENGTH;
2770 //printf("++ msg: %x \n", type);
2772 if(msgdataindex != msgdatalast) {
2773 // still have available msg
2778 BAMBOO_DEBUGPRINT(0xe88d);
2782 // have new coming msg
2783 if(BAMBOO_MSG_AVAIL() != 0) {
2797 BAMBOO_DEBUGPRINT(0xe88e);
2801 /* if(isInterrupt) {
2809 int enqueuetasks(struct parameterwrapper *parameter,
2810 struct parameterwrapper *prevptr,
2811 struct ___Object___ *ptr,
2813 int numenterflags) {
2814 void * taskpointerarray[MAXTASKPARAMS];
2816 //int numparams=parameter->task->numParameters;
2817 int numiterators=parameter->task->numTotal-1;
2820 struct taskdescriptor * task=parameter->task;
2822 //this add the object to parameterwrapper
2823 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
2824 numenterflags, enterflags==NULL);
2826 /* Add enqueued object to parameter vector */
2827 taskpointerarray[parameter->slot]=ptr;
2829 /* Reset iterators */
2830 for(j=0; j<numiterators; j++) {
2831 toiReset(¶meter->iterators[j]);
2834 /* Find initial state */
2835 for(j=0; j<numiterators; j++) {
2837 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2838 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2840 /* Need to backtrack */
2841 toiReset(¶meter->iterators[j]);
2845 /* Nothing to enqueue */
2851 /* Enqueue current state */
2853 struct taskparamdescriptor *tpd=
2854 RUNMALLOC(sizeof(struct taskparamdescriptor));
2856 tpd->numParameters=numiterators+1;
2857 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2859 for(j=0; j<=numiterators; j++) {
2860 //store the actual parameters
2861 tpd->parameterArray[j]=taskpointerarray[j];
2864 if (( /*!gencontains(failedtasks, tpd)&&*/
2865 !gencontains(activetasks,tpd))) {
2866 genputtable(activetasks, tpd, tpd);
2868 RUNFREE(tpd->parameterArray);
2872 /* This loop iterates to the next parameter combination */
2873 if (numiterators==0)
2876 for(j=numiterators-1; j<numiterators; j++) {
2878 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2879 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2881 /* Need to backtrack */
2882 toiReset(¶meter->iterators[j]);
2886 /* Nothing more to enqueue */
2894 int enqueuetasks_I(struct parameterwrapper *parameter,
2895 struct parameterwrapper *prevptr,
2896 struct ___Object___ *ptr,
2898 int numenterflags) {
2899 void * taskpointerarray[MAXTASKPARAMS];
2901 //int numparams=parameter->task->numParameters;
2902 int numiterators=parameter->task->numTotal-1;
2907 struct taskdescriptor * task=parameter->task;
2909 //this add the object to parameterwrapper
2910 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2911 numenterflags, enterflags==NULL);
2913 /* Add enqueued object to parameter vector */
2914 taskpointerarray[parameter->slot]=ptr;
2916 /* Reset iterators */
2917 for(j=0; j<numiterators; j++) {
2918 toiReset(¶meter->iterators[j]);
2921 /* Find initial state */
2922 for(j=0; j<numiterators; j++) {
2924 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2925 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2927 /* Need to backtrack */
2928 toiReset(¶meter->iterators[j]);
2932 /* Nothing to enqueue */
2938 /* Enqueue current state */
2940 struct taskparamdescriptor *tpd=
2941 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2943 tpd->numParameters=numiterators+1;
2944 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2946 for(j=0; j<=numiterators; j++) {
2947 //store the actual parameters
2948 tpd->parameterArray[j]=taskpointerarray[j];
2951 if (( /*!gencontains(failedtasks, tpd)&&*/
2952 !gencontains(activetasks,tpd))) {
2953 genputtable_I(activetasks, tpd, tpd);
2955 RUNFREE(tpd->parameterArray);
2959 /* This loop iterates to the next parameter combination */
2960 if (numiterators==0)
2963 for(j=numiterators-1; j<numiterators; j++) {
2965 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2966 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2968 /* Need to backtrack */
2969 toiReset(¶meter->iterators[j]);
2973 /* Nothing more to enqueue */
2987 int containstag(struct ___Object___ *ptr,
2988 struct ___TagDescriptor___ *tag);
2990 #ifndef MULTICORE_GC
2991 void releasewritelock_r(void * lock, void * redirectlock) {
2993 int reallock = (int)lock;
2994 targetcore = (reallock >> 5) % NUMCORES;
2997 BAMBOO_DEBUGPRINT(0xe671);
2998 BAMBOO_DEBUGPRINT_REG((int)lock);
2999 BAMBOO_DEBUGPRINT_REG(reallock);
3000 BAMBOO_DEBUGPRINT_REG(targetcore);
3003 if(targetcore == BAMBOO_NUM_OF_CORE) {
3004 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3006 BAMBOO_DEBUGPRINT(0xf001);
3008 // reside on this core
3009 if(!RuntimeHashcontainskey(locktbl, reallock)) {
3010 // no locks for this object, something is wrong
3011 BAMBOO_EXIT(0xa00b);
3014 struct LockValue * lockvalue = NULL;
3016 BAMBOO_DEBUGPRINT(0xe672);
3018 RuntimeHashget(locktbl, reallock, &rwlock_obj);
3019 lockvalue = (struct LockValue *)rwlock_obj;
3021 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3024 lockvalue->redirectlock = (int)redirectlock;
3026 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3029 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3031 BAMBOO_DEBUGPRINT(0xf000);
3035 // send lock release with redirect info msg
3036 // for 32 bit machine, the size is always 4 words
3037 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3038 (int)redirectlock, false);
3043 void executetasks() {
3044 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3047 struct ___Object___ * tmpparam = NULL;
3048 struct parameterdescriptor * pd=NULL;
3049 struct parameterwrapper *pw=NULL;
3059 while(hashsize(activetasks)>0) {
3064 BAMBOO_DEBUGPRINT(0xe990);
3067 /* See if there are any active tasks */
3068 //if (hashsize(activetasks)>0) {
3071 #ifdef ACCURATEPROFILE
3072 profileTaskStart("tpd checking");
3076 //clock1 = BAMBOO_GET_EXE_TIME();
3079 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3080 genfreekey(activetasks, currtpd);
3082 numparams=currtpd->task->numParameters;
3083 numtotal=currtpd->task->numTotal;
3085 // clear the lockRedirectTbl
3086 // (TODO, this table should be empty after all locks are released)
3088 /*for(j = 0; j < MAXTASKPARAMS; j++) {
3089 runtime_locks[j].redirectlock = 0;
3090 runtime_locks[j].value = 0;
3092 // get all required locks
3093 runtime_locklen = 0;
3094 // check which locks are needed
3095 for(i = 0; i < numparams; i++) {
3096 void * param = currtpd->parameterArray[i];
3100 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3102 taskpointerarray[i+OFFSET]=param;
3105 if(((struct ___Object___ *)param)->lock == NULL) {
3106 tmplock = (int)param;
3108 tmplock = (int)(((struct ___Object___ *)param)->lock);
3110 // insert into the locks array
3111 for(j = 0; j < runtime_locklen; j++) {
3112 if(runtime_locks[j].value == tmplock) {
3115 } else if(runtime_locks[j].value > tmplock) {
3120 int h = runtime_locklen;
3122 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3123 runtime_locks[h].value = runtime_locks[h-1].value;
3125 runtime_locks[j].value = tmplock;
3126 runtime_locks[j].redirectlock = (int)param;
3129 } // line 2713: for(i = 0; i < numparams; i++)
3130 // grab these required locks
3132 BAMBOO_DEBUGPRINT(0xe991);
3135 //clock2 = BAMBOO_GET_EXE_TIME();
3137 for(i = 0; i < runtime_locklen; i++) {
3138 int * lock = (int *)(runtime_locks[i].redirectlock);
3140 // require locks for this parameter if it is not a startup object
3142 BAMBOO_DEBUGPRINT_REG((int)lock);
3143 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3146 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3148 BAMBOO_DEBUGPRINT(0xf001);
3151 //isInterrupt = false;
3154 BAMBOO_WAITING_FOR_LOCK(0);
3155 // check for outgoing sends
3156 /*if (isMsgHanging) {
3157 extern inline void send_hanging_msg(bool);
3158 send_hanging_msg(true);
3163 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3164 // check for outgoing sends
3165 /*if (isMsgHanging) {
3166 extern inline void send_hanging_msg(bool);
3167 send_hanging_msg(true);
3172 grount = lockresult;
3182 //isInterrupt = true;
3184 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3186 BAMBOO_DEBUGPRINT(0xf000);
3191 BAMBOO_DEBUGPRINT(0xe992);
3192 BAMBOO_DEBUGPRINT_REG(lock);
3194 // check if has the lock already
3195 // can not get the lock, try later
3196 // release all grabbed locks for previous parameters
3197 for(j = 0; j < i; ++j) {
3198 lock = (int*)(runtime_locks[j].redirectlock);
3199 releasewritelock(lock);
3201 genputtable(activetasks, currtpd, currtpd);
3202 if(hashsize(activetasks) == 1) {
3203 // only one task right now, wait a little while before next try
3209 #ifdef ACCURATEPROFILE
3210 // fail, set the end of the checkTaskInfo
3217 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3220 clock3 = BAMBOO_GET_EXE_TIME();
3221 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3224 BAMBOO_DEBUGPRINT(0xe993);
3226 /* Make sure that the parameters are still in the queues */
3227 for(i=0; i<numparams; i++) {
3228 void * parameter=currtpd->parameterArray[i];
3232 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3233 classsize[((struct ___Object___ *)parameter)->type]);
3235 tmpparam = (struct ___Object___ *)parameter;
3236 pd=currtpd->task->descriptorarray[i];
3237 pw=(struct parameterwrapper *) pd->queue;
3238 /* Check that object is still in queue */
3240 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3242 BAMBOO_DEBUGPRINT(0xe994);
3243 BAMBOO_DEBUGPRINT_REG(parameter);
3245 // release grabbed locks
3246 for(j = 0; j < runtime_locklen; ++j) {
3247 int * lock = (int *)(runtime_locks[j].redirectlock);
3248 releasewritelock(lock);
3250 RUNFREE(currtpd->parameterArray);
3256 /* Check if the object's flags still meets requirements */
3260 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3261 andmask=pw->intarray[tmpi*2];
3262 checkmask=pw->intarray[tmpi*2+1];
3263 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3269 // flags are never suitable
3270 // remove this obj from the queue
3272 int UNUSED, UNUSED2;
3275 BAMBOO_DEBUGPRINT(0xe995);
3276 BAMBOO_DEBUGPRINT_REG(parameter);
3278 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3279 (int *) &enterflags, &UNUSED, &UNUSED2);
3280 ObjectHashremove(pw->objectset, (int)parameter);
3281 if (enterflags!=NULL)
3282 RUNFREE(enterflags);
3283 // release grabbed locks
3284 for(j = 0; j < runtime_locklen; ++j) {
3285 int * lock = (int *)(runtime_locks[j].redirectlock);
3286 releasewritelock(lock);
3288 RUNFREE(currtpd->parameterArray);
3292 #ifdef ACCURATEPROFILE
3293 // fail, set the end of the checkTaskInfo
3298 } // line 2878: if (!ismet)
3302 /* Check that object still has necessary tags */
3303 for(j=0; j<pd->numbertags; j++) {
3304 int slotid=pd->tagarray[2*j]+numparams;
3305 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3306 if (!containstag(parameter, tagd)) {
3308 BAMBOO_DEBUGPRINT(0xe996);
3311 // release grabbed locks
3313 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3314 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3315 releasewritelock(lock);
3318 RUNFREE(currtpd->parameterArray);
3322 } // line2911: if (!containstag(parameter, tagd))
3323 } // line 2808: for(j=0; j<pd->numbertags; j++)
3325 taskpointerarray[i+OFFSET]=parameter;
3326 } // line 2824: for(i=0; i<numparams; i++)
3328 for(; i<numtotal; i++) {
3329 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3334 /* Actually call task */
3336 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3337 taskpointerarray[1]=NULL;
3340 #ifdef ACCURATEPROFILE
3341 // check finish, set the end of the checkTaskInfo
3344 profileTaskStart(currtpd->task->name);
3348 //clock4 = BAMBOO_GET_EXE_TIME();
3349 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3352 BAMBOO_DEBUGPRINT(0xe997);
3354 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3357 //clock5 = BAMBOO_GET_EXE_TIME();
3358 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3361 #ifdef ACCURATEPROFILE
3362 // task finish, set the end of the checkTaskInfo
3364 // new a PostTaskInfo for the post-task execution
3365 profileTaskStart("post task execution");
3369 BAMBOO_DEBUGPRINT(0xe998);
3370 BAMBOO_DEBUGPRINT_REG(islock);
3375 BAMBOO_DEBUGPRINT(0xe999);
3377 for(i = 0; i < runtime_locklen; ++i) {
3378 void * ptr = (void *)(runtime_locks[i].redirectlock);
3379 int * lock = (int *)(runtime_locks[i].value);
3381 BAMBOO_DEBUGPRINT_REG((int)ptr);
3382 BAMBOO_DEBUGPRINT_REG((int)lock);
3383 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3385 #ifndef MULTICORE_GC
3386 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3388 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3389 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3390 releasewritelock_r(lock, (int *)redirectlock);
3395 releasewritelock(ptr);
3398 } // line 3015: if(islock)
3401 //clock6 = BAMBOO_GET_EXE_TIME();
3402 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3405 // post task execution finish, set the end of the postTaskInfo
3409 // Free up task parameter descriptor
3410 RUNFREE(currtpd->parameterArray);
3414 BAMBOO_DEBUGPRINT(0xe99a);
3417 //clock7 = BAMBOO_GET_EXE_TIME();
3418 //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));
3421 //} // if (hashsize(activetasks)>0)
3422 } // while(hashsize(activetasks)>0)
3424 BAMBOO_DEBUGPRINT(0xe99b);
3428 /* This function processes an objects tags */
3429 void processtags(struct parameterdescriptor *pd,
3431 struct parameterwrapper *parameter,
3432 int * iteratorcount,
3437 for(i=0; i<pd->numbertags; i++) {
3438 int slotid=pd->tagarray[2*i];
3439 int tagid=pd->tagarray[2*i+1];
3441 if (statusarray[slotid+numparams]==0) {
3442 parameter->iterators[*iteratorcount].istag=1;
3443 parameter->iterators[*iteratorcount].tagid=tagid;
3444 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3445 parameter->iterators[*iteratorcount].tagobjectslot=index;
3446 statusarray[slotid+numparams]=1;
3453 void processobject(struct parameterwrapper *parameter,
3455 struct parameterdescriptor *pd,
3461 struct ObjectHash * objectset=
3462 ((struct parameterwrapper *)pd->queue)->objectset;
3464 parameter->iterators[*iteratorcount].istag=0;
3465 parameter->iterators[*iteratorcount].slot=index;
3466 parameter->iterators[*iteratorcount].objectset=objectset;
3467 statusarray[index]=1;
3469 for(i=0; i<pd->numbertags; i++) {
3470 int slotid=pd->tagarray[2*i];
3471 //int tagid=pd->tagarray[2*i+1];
3472 if (statusarray[slotid+numparams]!=0) {
3473 /* This tag has already been enqueued, use it to narrow search */
3474 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3479 parameter->iterators[*iteratorcount].numtags=tagcount;
3484 /* This function builds the iterators for a task & parameter */
3486 void builditerators(struct taskdescriptor * task,
3488 struct parameterwrapper * parameter) {
3489 int statusarray[MAXTASKPARAMS];
3491 int numparams=task->numParameters;
3492 int iteratorcount=0;
3493 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3495 statusarray[index]=1; /* Initial parameter */
3496 /* Process tags for initial iterator */
3498 processtags(task->descriptorarray[index], index, parameter,
3499 &iteratorcount, statusarray, numparams);
3503 /* Check for objects with existing tags */
3504 for(i=0; i<numparams; i++) {
3505 if (statusarray[i]==0) {
3506 struct parameterdescriptor *pd=task->descriptorarray[i];
3508 for(j=0; j<pd->numbertags; j++) {
3509 int slotid=pd->tagarray[2*j];
3510 if(statusarray[slotid+numparams]!=0) {
3511 processobject(parameter, i, pd, &iteratorcount, statusarray,
3513 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3520 /* Next do objects w/ unbound tags*/
3522 for(i=0; i<numparams; i++) {
3523 if (statusarray[i]==0) {
3524 struct parameterdescriptor *pd=task->descriptorarray[i];
3525 if (pd->numbertags>0) {
3526 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3527 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3533 /* Nothing with a tag enqueued */
3535 for(i=0; i<numparams; i++) {
3536 if (statusarray[i]==0) {
3537 struct parameterdescriptor *pd=task->descriptorarray[i];
3538 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3539 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3552 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3555 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3556 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3558 printf("%s\n", task->name);
3560 for(j=0; j<task->numParameters; j++) {
3561 struct parameterdescriptor *param=task->descriptorarray[j];
3562 struct parameterwrapper *parameter=param->queue;
3563 struct ObjectHash * set=parameter->objectset;
3564 struct ObjectIterator objit;
3566 printf(" Parameter %d\n", j);
3568 ObjectHashiterator(set, &objit);
3569 while(ObjhasNext(&objit)) {
3570 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3571 struct ___Object___ * tagptr=obj->___tags___;
3572 int nonfailed=Objdata4(&objit);
3573 int numflags=Objdata3(&objit);
3574 int flags=Objdata2(&objit);
3577 printf(" Contains %lx\n", obj);
3578 printf(" flag=%d\n", obj->flag);
3581 } else if (tagptr->type==TAGTYPE) {
3583 printf(" tag=%lx\n",tagptr);
3589 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3590 for(; tagindex<ao->___cachedCode___; tagindex++) {
3592 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3605 /* This function processes the task information to create queues for
3606 each parameter type. */
3608 void processtasks() {
3610 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3613 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3614 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3617 /* Build objectsets */
3618 for(j=0; j<task->numParameters; j++) {
3619 struct parameterdescriptor *param=task->descriptorarray[j];
3620 struct parameterwrapper *parameter=param->queue;
3621 parameter->objectset=allocateObjectHash(10);
3622 parameter->task=task;
3625 /* Build iterators for parameters */
3626 for(j=0; j<task->numParameters; j++) {
3627 struct parameterdescriptor *param=task->descriptorarray[j];
3628 struct parameterwrapper *parameter=param->queue;
3629 builditerators(task, j, parameter);
3634 void toiReset(struct tagobjectiterator * it) {
3637 } else if (it->numtags>0) {
3640 ObjectHashiterator(it->objectset, &it->it);
3644 int toiHasNext(struct tagobjectiterator *it,
3645 void ** objectarray OPTARG(int * failed)) {
3648 /* Get object with tags */
3649 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3650 struct ___Object___ *tagptr=obj->___tags___;
3651 if (tagptr->type==TAGTYPE) {
3652 if ((it->tagobjindex==0)&& /* First object */
3653 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3658 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3659 int tagindex=it->tagobjindex;
3660 for(; tagindex<ao->___cachedCode___; tagindex++) {
3661 struct ___TagDescriptor___ *td=
3662 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3663 if (td->flag==it->tagid) {
3664 it->tagobjindex=tagindex; /* Found right type of tag */
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;
3675 if (objptr->type!=OBJECTARRAYTYPE) {
3676 if (it->tagobjindex>0)
3678 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3680 for(i=1; i<it->numtags; i++) {
3681 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3682 if (!containstag(objptr,tag2))
3687 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3690 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
3691 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3692 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3694 for(i=1; i<it->numtags; i++) {
3695 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3696 if (!containstag(objptr,tag2))
3699 it->tagobjindex=tagindex;
3704 it->tagobjindex=tagindex;
3708 return ObjhasNext(&it->it);
3712 int containstag(struct ___Object___ *ptr,
3713 struct ___TagDescriptor___ *tag) {
3715 struct ___Object___ * objptr=tag->flagptr;
3716 if (objptr->type==OBJECTARRAYTYPE) {
3717 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3718 for(j=0; j<ao->___cachedCode___; j++) {
3719 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3729 void toiNext(struct tagobjectiterator *it,
3730 void ** objectarray OPTARG(int * failed)) {
3731 /* hasNext has all of the intelligence */
3734 /* Get object with tags */
3735 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3736 struct ___Object___ *tagptr=obj->___tags___;
3737 if (tagptr->type==TAGTYPE) {
3739 objectarray[it->slot]=tagptr;
3741 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3742 objectarray[it->slot]=
3743 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3745 } else if (it->numtags>0) {
3746 /* Use tags to locate appropriate objects */
3747 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3748 struct ___Object___ *objptr=tag->flagptr;
3749 if (objptr->type!=OBJECTARRAYTYPE) {
3751 objectarray[it->slot]=objptr;
3753 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3754 objectarray[it->slot]=
3755 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3758 /* Iterate object */
3759 objectarray[it->slot]=(void *)Objkey(&it->it);
3765 inline void profileTaskStart(char * taskname) {
3766 if(!taskInfoOverflow) {
3767 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
3768 taskInfoArray[taskInfoIndex] = taskInfo;
3769 taskInfo->taskName = taskname;
3770 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
3771 taskInfo->endTime = -1;
3772 taskInfo->exitIndex = -1;
3773 taskInfo->newObjs = NULL;
3777 inline void profileTaskEnd() {
3778 if(!taskInfoOverflow) {
3779 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
3781 if(taskInfoIndex == TASKINFOLENGTH) {
3782 taskInfoOverflow = true;
3783 //taskInfoIndex = 0;
3788 // output the profiling data
3789 void outputProfileData() {
3792 unsigned long long totaltasktime = 0;
3793 unsigned long long preprocessingtime = 0;
3794 unsigned long long objqueuecheckingtime = 0;
3795 unsigned long long postprocessingtime = 0;
3796 //int interruptiontime = 0;
3797 unsigned long long other = 0;
3798 unsigned long long averagetasktime = 0;
3801 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
3802 // output task related info
3803 for(i = 0; i < taskInfoIndex; i++) {
3804 TaskInfo* tmpTInfo = taskInfoArray[i];
3805 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
3806 printf("%s, %lld, %lld, %lld, %lld",
3807 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
3808 duration, tmpTInfo->exitIndex);
3809 // summarize new obj info
3810 if(tmpTInfo->newObjs != NULL) {
3811 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3812 struct RuntimeIterator * iter = NULL;
3813 while(0 == isEmpty(tmpTInfo->newObjs)) {
3814 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3815 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3817 RuntimeHashget(nobjtbl, (int)objtype, &num);
3818 RuntimeHashremovekey(nobjtbl, (int)objtype);
3820 RuntimeHashadd(nobjtbl, (int)objtype, num);
3822 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3824 //printf(stderr, "new obj!\n");
3827 // output all new obj info
3828 iter = RuntimeHashcreateiterator(nobjtbl);
3829 while(RunhasNext(iter)) {
3830 char * objtype = (char *)Runkey(iter);
3831 int num = Runnext(iter);
3832 printf(", %s, %d", objtype, num);
3836 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
3837 preprocessingtime += duration;
3838 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
3839 postprocessingtime += duration;
3840 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
3841 objqueuecheckingtime += duration;
3843 totaltasktime += duration;
3844 averagetasktime += duration;
3849 if(taskInfoOverflow) {
3850 printf("Caution: task info overflow!\n");
3853 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
3854 averagetasktime /= tasknum;
3856 printf("\nTotal time: %lld\n", totalexetime);
3857 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
3858 (int)(((double)totaltasktime/(double)totalexetime)*100));
3859 printf("Total objqueue checking time: %lld (%d%%)\n",
3860 objqueuecheckingtime,
3861 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
3862 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
3863 (int)(((double)preprocessingtime/(double)totalexetime)*100));
3864 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
3865 (int)(((double)postprocessingtime/(double)totalexetime)*100));
3866 printf("Other time: %lld (%d%%)\n", other,
3867 (int)(((double)other/(double)totalexetime)*100));
3870 printf("\nAverage task execution time: %lld\n", averagetasktime);
3872 //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
3877 BAMBOO_DEBUGPRINT(0xdddd);
3878 // output task related info
3879 for(i= 0; i < taskInfoIndex; i++) {
3880 TaskInfo* tmpTInfo = taskInfoArray[i];
3881 char* tmpName = tmpTInfo->taskName;
3882 int nameLen = strlen(tmpName);
3883 BAMBOO_DEBUGPRINT(0xddda);
3884 for(j = 0; j < nameLen; j++) {
3885 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
3887 BAMBOO_DEBUGPRINT(0xdddb);
3888 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
3889 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
3890 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
3891 if(tmpTInfo->newObjs != NULL) {
3892 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3893 struct RuntimeIterator * iter = NULL;
3894 while(0 == isEmpty(tmpTInfo->newObjs)) {
3895 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3896 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3898 RuntimeHashget(nobjtbl, (int)objtype, &num);
3899 RuntimeHashremovekey(nobjtbl, (int)objtype);
3901 RuntimeHashadd(nobjtbl, (int)objtype, num);
3903 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3907 // ouput all new obj info
3908 iter = RuntimeHashcreateiterator(nobjtbl);
3909 while(RunhasNext(iter)) {
3910 char * objtype = (char *)Runkey(iter);
3911 int num = Runnext(iter);
3912 int nameLen = strlen(objtype);
3913 BAMBOO_DEBUGPRINT(0xddda);
3914 for(j = 0; j < nameLen; j++) {
3915 BAMBOO_DEBUGPRINT_REG(objtype[j]);
3917 BAMBOO_DEBUGPRINT(0xdddb);
3918 BAMBOO_DEBUGPRINT_REG(num);
3921 BAMBOO_DEBUGPRINT(0xdddc);
3924 if(taskInfoOverflow) {
3925 BAMBOO_DEBUGPRINT(0xefee);
3928 // output interrupt related info
3929 for(i = 0; i < interruptInfoIndex; i++) {
3930 InterruptInfo* tmpIInfo = interruptInfoArray[i];
3931 BAMBOO_DEBUGPRINT(0xddde);
3932 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
3933 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
3934 BAMBOO_DEBUGPRINT(0xdddf);
3937 if(interruptInfoOverflow) {
3938 BAMBOO_DEBUGPRINT(0xefef);
3941 BAMBOO_DEBUGPRINT(0xeeee);
3944 #endif // #ifdef PROFILE