3 #include "multicoreruntime.h"
4 #include "runtime_arch.h"
5 #include "GenericHashtable.h"
7 // data structures for task invocation
8 struct genhashtable * activetasks;
9 struct taskparamdescriptor * currtpd;
10 struct LockValue runtime_locks[MAXTASKPARAMS];
13 // specific functions used inside critical sections
14 void enqueueObject_I(void * ptr,
15 struct parameterwrapper ** queues,
17 int enqueuetasks_I(struct parameterwrapper *parameter,
18 struct parameterwrapper *prevptr,
19 struct ___Object___ *ptr,
24 inline __attribute__((always_inline))
25 void setupsmemmode(void) {
27 bamboo_smem_mode = SMEMLOCAL;
29 bamboo_smem_mode = SMEMFIXED;
31 bamboo_smem_mode = SMEMMIXED;
33 bamboo_smem_mode = SMEMGLOBAL;
35 // defaultly using local mode
36 //bamboo_smem_mode = SMEMLOCAL;
37 bamboo_smem_mode = SMEMGLOBAL;
39 } // void setupsmemmode(void)
42 inline __attribute__((always_inline))
43 void initruntimedata() {
45 // initialize the arrays
46 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
47 // startup core to initialize corestatus[]
48 for(i = 0; i < NUMCORESACTIVE; ++i) {
51 numreceiveobjs[i] = 0;
53 // initialize the profile data arrays
59 gcnumreceiveobjs[i] = 0;
61 } // for(i = 0; i < NUMCORESACTIVE; ++i)
63 for(i = 0; i < NUMCORES4GC; ++i) {
65 gcrequiredmems[i] = 0;
67 gcfilledblocks[i] = 0;
68 } // for(i = 0; i < NUMCORES4GC; ++i)
71 gc_infoOverflow = false;
83 self_numreceiveobjs = 0;
85 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
89 msglength = BAMBOO_MSG_BUF_LENGTH;
90 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
100 bamboo_cur_msp = NULL;
101 bamboo_smem_size = 0;
102 totransobjqueue = createQueue();
106 gcprocessing = false;
107 gcphase = FINISHPHASE;
109 gcself_numsendobjs = 0;
110 gcself_numreceiveobjs = 0;
111 gcmarkedptrbound = 0;
112 //mgchashCreate(2000, 0.75);
113 gcpointertbl = allocateRuntimeHash(20);
114 //gcpointertbl = allocateMGCHash(20);
115 gcforwardobjtbl = allocateMGCHash(20, 3);
127 gcsbstarttbl = BAMBOO_BASE_VA;
128 bamboo_smemtbl = (void *)gcsbstarttbl
129 + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
131 // create the lock table, lockresult table and obj queue
134 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
135 /* Set allocation blocks*/
136 locktable.listhead=NULL;
137 locktable.listtail=NULL;
139 locktable.numelements = 0;
144 lockRedirectTbl = allocateRuntimeHash(20);
145 objRedirectLockTbl = allocateRuntimeHash(20);
150 objqueue.head = NULL;
151 objqueue.tail = NULL;
157 //isInterrupt = true;
160 taskInfoOverflow = false;
161 /*interruptInfoIndex = 0;
162 interruptInfoOverflow = false;*/
165 for(i = 0; i < MAXTASKPARAMS; i++) {
166 runtime_locks[i].redirectlock = 0;
167 runtime_locks[i].value = 0;
172 inline __attribute__((always_inline))
173 void disruntimedata() {
176 freeRuntimeHash(gcpointertbl);
177 //freeMGCHash(gcpointertbl);
178 freeMGCHash(gcforwardobjtbl);
180 freeRuntimeHash(lockRedirectTbl);
181 freeRuntimeHash(objRedirectLockTbl);
182 RUNFREE(locktable.bucket);
184 if(activetasks != NULL) {
185 genfreehashtable(activetasks);
187 if(currtpd != NULL) {
188 RUNFREE(currtpd->parameterArray);
194 inline __attribute__((always_inline))
195 bool checkObjQueue() {
197 struct transObjInfo * objInfo = NULL;
201 #ifdef ACCURATEPROFILE
202 bool isChecking = false;
203 if(!isEmpty(&objqueue)) {
204 profileTaskStart("objqueue checking");
206 } // if(!isEmpty(&objqueue))
210 while(!isEmpty(&objqueue)) {
212 BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE();
214 BAMBOO_DEBUGPRINT(0xf001);
217 //isInterrupt = false;
220 BAMBOO_DEBUGPRINT(0xeee1);
223 objInfo = (struct transObjInfo *)getItem(&objqueue);
224 obj = objInfo->objptr;
226 BAMBOO_DEBUGPRINT_REG((int)obj);
228 // grab lock and flush the obj
232 BAMBOO_WAITING_FOR_LOCK();
233 } // while(!lockflag)
236 BAMBOO_DEBUGPRINT_REG(grount);
251 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
252 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
253 classsize[((struct ___Object___ *)obj)->type]);
255 // enqueue the object
256 for(k = 0; k < objInfo->length; ++k) {
257 int taskindex = objInfo->queues[2 * k];
258 int paramindex = objInfo->queues[2 * k + 1];
259 struct parameterwrapper ** queues =
260 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
262 BAMBOO_DEBUGPRINT_REG(taskindex);
263 BAMBOO_DEBUGPRINT_REG(paramindex);
264 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
265 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
266 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
267 (long)obj, tmpptr->flag);
269 enqueueObject_I(obj, queues, 1);
271 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
273 } // for(k = 0; k < objInfo->length; ++k)
274 releasewritelock_I(obj);
275 RUNFREE(objInfo->queues);
279 // put it at the end of the queue if no update version in the queue
280 struct QueueItem * qitem = getHead(&objqueue);
281 struct QueueItem * prev = NULL;
282 while(qitem != NULL) {
283 struct transObjInfo * tmpinfo =
284 (struct transObjInfo *)(qitem->objectptr);
285 if(tmpinfo->objptr == obj) {
286 // the same object in the queue, which should be enqueued
287 // recently. Current one is outdate, do not re-enqueue it
288 RUNFREE(objInfo->queues);
293 } // if(tmpinfo->objptr == obj)
294 qitem = getNextQueueItem(prev);
295 } // while(qitem != NULL)
296 // try to execute active tasks already enqueued first
297 addNewItem_I(&objqueue, objInfo);
299 //isInterrupt = true;
302 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
304 BAMBOO_DEBUGPRINT(0xf000);
308 BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE();
310 BAMBOO_DEBUGPRINT(0xf000);
312 } // while(!isEmpty(&objqueue))
315 #ifdef ACCURATEPROFILE
323 BAMBOO_DEBUGPRINT(0xee02);
328 inline __attribute__((always_inline))
329 void checkCoreStatus() {
330 bool allStall = false;
334 (waitconfirm && (numconfirm == 0))) {
336 BAMBOO_DEBUGPRINT(0xee04);
337 BAMBOO_DEBUGPRINT_REG(waitconfirm);
339 BAMBOO_START_CRITICAL_SECTION_STATUS();
341 BAMBOO_DEBUGPRINT(0xf001);
343 corestatus[BAMBOO_NUM_OF_CORE] = 0;
344 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
345 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
346 // check the status of all cores
349 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
351 for(i = 0; i < NUMCORESACTIVE; ++i) {
353 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
355 if(corestatus[i] != 0) {
359 } // for(i = 0; i < NUMCORESACTIVE; ++i)
361 // check if the sum of send objs and receive obj are the same
362 // yes->check if the info is the latest; no->go on executing
364 for(i = 0; i < NUMCORESACTIVE; ++i) {
365 sumsendobj += numsendobjs[i];
367 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
369 } // for(i = 0; i < NUMCORESACTIVE; ++i)
370 for(i = 0; i < NUMCORESACTIVE; ++i) {
371 sumsendobj -= numreceiveobjs[i];
373 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
375 } // for(i = 0; i < NUMCORESACTIVE; ++i)
376 if(0 == sumsendobj) {
378 // the first time found all cores stall
379 // send out status confirm msg to all other cores
380 // reset the corestatus array too
382 BAMBOO_DEBUGPRINT(0xee05);
384 corestatus[BAMBOO_NUM_OF_CORE] = 1;
385 for(i = 1; i < NUMCORESACTIVE; ++i) {
387 // send status confirm msg to core i
388 send_msg_1(i, STATUSCONFIRM, false);
389 } // for(i = 1; i < NUMCORESACTIVE; ++i)
391 numconfirm = NUMCORESACTIVE - 1;
393 // all the core status info are the latest
394 // terminate; for profiling mode, send request to all
395 // other cores to pour out profiling data
397 BAMBOO_DEBUGPRINT(0xee06);
401 totalexetime = BAMBOO_GET_EXE_TIME();
403 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
404 BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
405 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
407 // profile mode, send msgs to other cores to request pouring
408 // out progiling data
410 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
412 BAMBOO_DEBUGPRINT(0xf000);
414 for(i = 1; i < NUMCORESACTIVE; ++i) {
415 // send profile request msg to core i
416 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
417 } // for(i = 1; i < NUMCORESACTIVE; ++i)
418 // pour profiling data on startup core
421 BAMBOO_START_CRITICAL_SECTION_STATUS();
423 BAMBOO_DEBUGPRINT(0xf001);
425 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
426 // check the status of all cores
429 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
431 for(i = 0; i < NUMCORESACTIVE; ++i) {
433 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
435 if(profilestatus[i] != 0) {
439 } // for(i = 0; i < NUMCORESACTIVE; ++i)
442 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
444 BAMBOO_DEBUGPRINT(0xf000);
454 // gc_profile mode, ourput gc prfiling data
457 gc_outputProfileData();
458 #endif // #ifdef GC_PROFILE
459 #endif // #ifdef MULTICORE_GC
461 terminate(); // All done.
462 } // if(!waitconfirm)
464 // still some objects on the fly on the network
465 // reset the waitconfirm and numconfirm
467 BAMBOO_DEBUGPRINT(0xee07);
471 } // if(0 == sumsendobj)
473 // not all cores are stall, keep on waiting
475 BAMBOO_DEBUGPRINT(0xee08);
480 BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
482 BAMBOO_DEBUGPRINT(0xf000);
484 } // if((!waitconfirm) ||
487 // main function for each core
488 inline void run(void * arg) {
492 bool sendStall = false;
494 bool tocontinue = false;
496 corenum = BAMBOO_GET_NUM_OF_CORE();
498 BAMBOO_DEBUGPRINT(0xeeee);
499 BAMBOO_DEBUGPRINT_REG(corenum);
500 BAMBOO_DEBUGPRINT(STARTUPCORE);
503 // initialize runtime data structures
506 // other architecture related initialization
510 initializeexithandler();
512 // main process of the execution module
513 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
514 // non-executing cores, only processing communications
517 BAMBOO_DEBUGPRINT(0xee01);
518 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
519 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
520 profileTaskStart("msg handling");
524 //isInterrupt = false;
528 /* Create queue of active tasks */
530 genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
531 (int(*) (void *,void *)) &comparetpd);
533 /* Process task information */
536 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
537 /* Create startup object */
538 createstartupobject(argc, argv);
542 BAMBOO_DEBUGPRINT(0xee00);
547 // check if need to do GC
551 // check if there are new active tasks can be executed
558 while(receiveObject() != -1) {
563 BAMBOO_DEBUGPRINT(0xee01);
566 // check if there are some pending objects,
567 // if yes, enqueue them and executetasks again
568 tocontinue = checkObjQueue();
572 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
575 BAMBOO_DEBUGPRINT(0xee03);
583 BAMBOO_DEBUGPRINT(0xee09);
589 // wait for some time
592 BAMBOO_DEBUGPRINT(0xee0a);
598 // send StallMsg to startup core
600 BAMBOO_DEBUGPRINT(0xee0b);
603 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
604 self_numsendobjs, self_numreceiveobjs, false);
616 BAMBOO_DEBUGPRINT(0xee0c);
619 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
622 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
626 struct ___createstartupobject____I_locals {
629 struct ___StartupObject___ * ___startupobject___;
630 struct ArrayObject * ___stringarray___;
631 }; // struct ___createstartupobject____I_locals
633 void createstartupobject(int argc,
637 /* Allocate startup object */
639 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
640 struct ___StartupObject___ *startupobject=
641 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
642 ___locals___.___startupobject___ = startupobject;
643 struct ArrayObject * stringarray=
644 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
645 ___locals___.___stringarray___ = stringarray;
647 struct ___StartupObject___ *startupobject=
648 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
649 struct ArrayObject * stringarray=
650 allocate_newarray(STRINGARRAYTYPE, argc-1);
652 /* Build array of strings */
653 startupobject->___parameters___=stringarray;
654 for(i=1; i<argc; i++) {
655 int length=strlen(argv[i]);
657 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
659 struct ___String___ *newstring=NewString(argv[i],length);
661 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
665 startupobject->version = 0;
666 startupobject->lock = NULL;
668 /* Set initialized flag for startup object */
669 flagorandinit(startupobject,1,0xFFFFFFFF);
670 enqueueObject(startupobject, NULL, 0);
672 BAMBOO_CACHE_FLUSH_ALL();
676 int hashCodetpd(struct taskparamdescriptor *ftd) {
677 int hash=(int)ftd->task;
679 for(i=0; i<ftd->numParameters; i++) {
680 hash^=(int)ftd->parameterArray[i];
685 int comparetpd(struct taskparamdescriptor *ftd1,
686 struct taskparamdescriptor *ftd2) {
688 if (ftd1->task!=ftd2->task)
690 for(i=0; i<ftd1->numParameters; i++)
691 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
696 /* This function sets a tag. */
698 void tagset(void *ptr,
699 struct ___Object___ * obj,
700 struct ___TagDescriptor___ * tagd) {
702 void tagset(struct ___Object___ * obj,
703 struct ___TagDescriptor___ * tagd) {
705 struct ArrayObject * ao=NULL;
706 struct ___Object___ * tagptr=obj->___tags___;
708 obj->___tags___=(struct ___Object___ *)tagd;
710 /* Have to check if it is already set */
711 if (tagptr->type==TAGTYPE) {
712 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
717 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
718 struct ArrayObject * ao=
719 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
720 obj=(struct ___Object___ *)ptrarray[2];
721 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
722 td=(struct ___TagDescriptor___ *) obj->___tags___;
724 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
727 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
728 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
729 obj->___tags___=(struct ___Object___ *) ao;
730 ao->___cachedCode___=2;
734 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
735 for(i=0; i<ao->___cachedCode___; i++) {
736 struct ___TagDescriptor___ * td=
737 ARRAYGET(ao, struct ___TagDescriptor___*, i);
742 if (ao->___cachedCode___<ao->___length___) {
743 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
744 ao->___cachedCode___++;
747 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
748 struct ArrayObject * aonew=
749 allocate_newarray(&ptrarray,TAGARRAYTYPE,
750 TAGARRAYINTERVAL+ao->___length___);
751 obj=(struct ___Object___ *)ptrarray[2];
752 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
753 ao=(struct ArrayObject *)obj->___tags___;
755 struct ArrayObject * aonew=
756 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
759 aonew->___cachedCode___=ao->___length___+1;
760 for(i=0; i<ao->___length___; i++) {
761 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
762 ARRAYGET(ao, struct ___TagDescriptor___*, i));
764 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
770 struct ___Object___ * tagset=tagd->flagptr;
773 } else if (tagset->type!=OBJECTARRAYTYPE) {
775 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
776 struct ArrayObject * ao=
777 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
778 obj=(struct ___Object___ *)ptrarray[2];
779 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
781 struct ArrayObject * ao=
782 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
784 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
785 ARRAYSET(ao, struct ___Object___ *, 1, obj);
786 ao->___cachedCode___=2;
787 tagd->flagptr=(struct ___Object___ *)ao;
789 struct ArrayObject *ao=(struct ArrayObject *) tagset;
790 if (ao->___cachedCode___<ao->___length___) {
791 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
795 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
796 struct ArrayObject * aonew=
797 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
798 OBJECTARRAYINTERVAL+ao->___length___);
799 obj=(struct ___Object___ *)ptrarray[2];
800 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
801 ao=(struct ArrayObject *)tagd->flagptr;
803 struct ArrayObject * aonew=
804 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
806 aonew->___cachedCode___=ao->___cachedCode___+1;
807 for(i=0; i<ao->___length___; i++) {
808 ARRAYSET(aonew, struct ___Object___*, i,
809 ARRAYGET(ao, struct ___Object___*, i));
811 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
812 tagd->flagptr=(struct ___Object___ *) aonew;
818 /* This function clears a tag. */
820 void tagclear(void *ptr,
821 struct ___Object___ * obj,
822 struct ___TagDescriptor___ * tagd) {
824 void tagclear(struct ___Object___ * obj,
825 struct ___TagDescriptor___ * tagd) {
827 /* We'll assume that tag is alway there.
828 Need to statically check for this of course. */
829 struct ___Object___ * tagptr=obj->___tags___;
831 if (tagptr->type==TAGTYPE) {
832 if ((struct ___TagDescriptor___ *)tagptr==tagd)
833 obj->___tags___=NULL;
835 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
837 for(i=0; i<ao->___cachedCode___; i++) {
838 struct ___TagDescriptor___ * td=
839 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
841 ao->___cachedCode___--;
842 if (i<ao->___cachedCode___)
843 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
844 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
845 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
846 if (ao->___cachedCode___==0)
847 obj->___tags___=NULL;
854 struct ___Object___ *tagset=tagd->flagptr;
855 if (tagset->type!=OBJECTARRAYTYPE) {
859 struct ArrayObject *ao=(struct ArrayObject *) tagset;
861 for(i=0; i<ao->___cachedCode___; i++) {
862 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
864 ao->___cachedCode___--;
865 if (i<ao->___cachedCode___)
866 ARRAYSET(ao, struct ___Object___ *, i,
867 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
868 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
869 if (ao->___cachedCode___==0)
880 /* This function allocates a new tag. */
882 struct ___TagDescriptor___ * allocate_tag(void *ptr,
884 struct ___TagDescriptor___ * v=
885 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
888 struct ___TagDescriptor___ * allocate_tag(int index) {
889 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
898 /* This function updates the flag for object ptr. It or's the flag
899 with the or mask and and's it with the andmask. */
901 void flagbody(struct ___Object___ *ptr,
903 struct parameterwrapper ** queues,
907 int flagcomp(const int *val1, const int *val2) {
908 return (*val1)-(*val2);
911 void flagorand(void * ptr,
914 struct parameterwrapper ** queues,
917 int oldflag=((int *)ptr)[1];
918 int flag=ormask|oldflag;
920 flagbody(ptr, flag, queues, length, false);
924 bool intflagorand(void * ptr,
928 int oldflag=((int *)ptr)[1];
929 int flag=ormask|oldflag;
931 if (flag==oldflag) /* Don't do anything */
934 flagbody(ptr, flag, NULL, 0, false);
940 void flagorandinit(void * ptr,
943 int oldflag=((int *)ptr)[1];
944 int flag=ormask|oldflag;
946 flagbody(ptr,flag,NULL,0,true);
949 void flagbody(struct ___Object___ *ptr,
951 struct parameterwrapper ** vqueues,
954 struct parameterwrapper * flagptr = NULL;
956 struct parameterwrapper ** queues = vqueues;
957 int length = vlength;
960 int * enterflags = NULL;
961 if((!isnew) && (queues == NULL)) {
962 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
963 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
964 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
971 /*Remove object from all queues */
972 for(i = 0; i < length; ++i) {
974 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
975 (int *) &enterflags, &UNUSED, &UNUSED2);
976 ObjectHashremove(flagptr->objectset, (int)ptr);
977 if (enterflags!=NULL)
982 void enqueueObject(void * vptr,
983 struct parameterwrapper ** vqueues,
985 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
988 //struct QueueItem *tmpptr;
989 struct parameterwrapper * parameter=NULL;
992 struct parameterwrapper * prevptr=NULL;
993 struct ___Object___ *tagptr=NULL;
994 struct parameterwrapper ** queues = vqueues;
995 int length = vlength;
996 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1000 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1001 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1003 tagptr=ptr->___tags___;
1005 /* Outer loop iterates through all parameter queues an object of
1006 this type could be in. */
1007 for(j = 0; j < length; ++j) {
1008 parameter = queues[j];
1010 if (parameter->numbertags>0) {
1012 goto nextloop; //that means the object has no tag
1013 //but that param needs tag
1014 else if(tagptr->type==TAGTYPE) { //one tag
1015 //struct ___TagDescriptor___ * tag=
1016 //(struct ___TagDescriptor___*) tagptr;
1017 for(i=0; i<parameter->numbertags; i++) {
1018 //slotid is parameter->tagarray[2*i];
1019 int tagid=parameter->tagarray[2*i+1];
1020 if (tagid!=tagptr->flag)
1021 goto nextloop; /*We don't have this tag */
1023 } else { //multiple tags
1024 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1025 for(i=0; i<parameter->numbertags; i++) {
1026 //slotid is parameter->tagarray[2*i];
1027 int tagid=parameter->tagarray[2*i+1];
1029 for(j=0; j<ao->___cachedCode___; j++) {
1030 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1041 for(i=0; i<parameter->numberofterms; i++) {
1042 int andmask=parameter->intarray[i*2];
1043 int checkmask=parameter->intarray[i*2+1];
1044 if ((ptr->flag&andmask)==checkmask) {
1045 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1056 void enqueueObject_I(void * vptr,
1057 struct parameterwrapper ** vqueues,
1059 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1062 //struct QueueItem *tmpptr;
1063 struct parameterwrapper * parameter=NULL;
1066 struct parameterwrapper * prevptr=NULL;
1067 struct ___Object___ *tagptr=NULL;
1068 struct parameterwrapper ** queues = vqueues;
1069 int length = vlength;
1070 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1073 if(queues == NULL) {
1074 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1075 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1077 tagptr=ptr->___tags___;
1079 /* Outer loop iterates through all parameter queues an object of
1080 this type could be in. */
1081 for(j = 0; j < length; ++j) {
1082 parameter = queues[j];
1084 if (parameter->numbertags>0) {
1086 goto nextloop; //that means the object has no tag
1087 //but that param needs tag
1088 else if(tagptr->type==TAGTYPE) { //one tag
1089 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1090 for(i=0; i<parameter->numbertags; i++) {
1091 //slotid is parameter->tagarray[2*i];
1092 int tagid=parameter->tagarray[2*i+1];
1093 if (tagid!=tagptr->flag)
1094 goto nextloop; /*We don't have this tag */
1096 } else { //multiple tags
1097 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1098 for(i=0; i<parameter->numbertags; i++) {
1099 //slotid is parameter->tagarray[2*i];
1100 int tagid=parameter->tagarray[2*i+1];
1102 for(j=0; j<ao->___cachedCode___; j++) {
1103 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1114 for(i=0; i<parameter->numberofterms; i++) {
1115 int andmask=parameter->intarray[i*2];
1116 int checkmask=parameter->intarray[i*2+1];
1117 if ((ptr->flag&andmask)==checkmask) {
1118 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1130 int * getAliasLock(void ** ptrs,
1132 struct RuntimeHash * tbl) {
1134 return (int*)(RUNMALLOC(sizeof(int)));
1139 bool redirect = false;
1140 int redirectlock = 0;
1141 for(; i < length; i++) {
1142 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1145 if(ptr->lock == NULL) {
1148 lock = (int)(ptr->lock);
1151 if(lock != redirectlock) {
1152 RuntimeHashadd(tbl, lock, redirectlock);
1155 if(RuntimeHashcontainskey(tbl, lock)) {
1156 // already redirected
1158 RuntimeHashget(tbl, lock, &redirectlock);
1159 for(; j < locklen; j++) {
1160 if(locks[j] != redirectlock) {
1161 RuntimeHashadd(tbl, locks[j], redirectlock);
1166 for(j = 0; j < locklen; j++) {
1167 if(locks[j] == lock) {
1170 } else if(locks[j] > lock) {
1177 locks[h] = locks[h-1];
1186 return (int *)redirectlock;
1188 return (int *)(locks[0]);
1193 void addAliasLock(void * ptr,
1195 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1196 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1197 // originally no alias lock associated or have a different alias lock
1198 // flush it as the new one
1199 obj->lock = (int *)lock;
1204 inline void setTaskExitIndex(int index) {
1205 taskInfoArray[taskInfoIndex]->exitIndex = index;
1208 inline void addNewObjInfo(void * nobj) {
1209 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1210 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1212 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1217 void * localmalloc_I(int coren,
1223 int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1224 int totest = tofindb;
1225 int bound = BAMBOO_SMEM_SIZE_L;
1229 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1230 int nsize = bamboo_smemtbl[totest];
1231 bool islocal = true;
1233 bool tocheck = true;
1234 // have some space in the block
1235 if(totest == tofindb) {
1236 // the first partition
1237 size = bound - nsize;
1238 } else if(nsize == 0) {
1239 // an empty partition, can be appended
1242 // not an empty partition, can not be appended
1243 // the last continuous block is not big enough, go to check the next
1247 } // if(totest == tofindb) else if(nsize == 0) else ...
1250 // have enough space in the block, malloc
1254 // no enough space yet, try to append next continuous block
1256 } // if(size > isize) else ...
1258 } // if(nsize < bound)
1260 // no space in the block, go to check the next block
1266 tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1269 } // if(islocal) else ...
1270 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1271 // no more local mem, do not find suitable block
1274 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1277 if(foundsmem == 1) {
1278 // find suitable block
1279 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC)?
1280 (BAMBOO_SMEM_SIZE_L*tofindb):(BAMBOO_LARGE_SMEM_BOUND+
1281 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1283 // set bamboo_smemtbl
1284 for(i = tofindb; i <= totest; i++) {
1285 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1287 } else if(foundsmem == 2) {
1288 // no suitable block
1293 } // void * localmalloc_I(int, int, int *)
1295 void * globalmalloc_I(int coren,
1299 int tofindb = bamboo_free_block; //0;
1300 int totest = tofindb;
1301 int bound = BAMBOO_SMEM_SIZE_L;
1304 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1309 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1310 int nsize = bamboo_smemtbl[totest];
1311 bool isnext = false;
1313 bool tocheck = true;
1314 // have some space in the block
1315 if(totest == tofindb) {
1316 // the first partition
1317 size = bound - nsize;
1318 } else if(nsize == 0) {
1319 // an empty partition, can be appended
1322 // not an empty partition, can not be appended
1323 // the last continuous block is not big enough, start another block
1326 } // if(totest == tofindb) else if(nsize == 0) else ...
1329 // have enough space in the block, malloc
1332 } // if(size > isize)
1336 }// if(nsize < bound) else ...
1338 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1339 // no more local mem, do not find suitable block
1342 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1344 // start another block
1349 if(foundsmem == 1) {
1350 // find suitable block
1351 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC)?
1352 (BAMBOO_SMEM_SIZE_L*tofindb):(BAMBOO_LARGE_SMEM_BOUND+
1353 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1355 // set bamboo_smemtbl
1356 for(int i = tofindb; i <= totest; i++) {
1357 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1359 if(tofindb == bamboo_free_block) {
1360 bamboo_free_block = totest+1;
1362 } else if(foundsmem == 2) {
1363 // no suitable block
1369 } // void * globalmalloc_I(int, int, int *)
1370 #endif // #ifdef MULTICORE_GC
1372 // malloc from the shared memory
1373 void * smemalloc_I(int coren,
1378 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1380 // go through the bamboo_smemtbl for suitable partitions
1381 switch(bamboo_smem_mode) {
1383 mem = localmalloc_I(coren, isize, allocsize);
1388 // TODO not supported yet
1389 BAMBOO_EXIT(0xe001);
1394 // TODO not supported yet
1395 BAMBOO_EXIT(0xe002);
1400 mem = globalmalloc_I(coren, isize, allocsize);
1410 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size):(BAMBOO_SMEM_SIZE);
1411 mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1412 *allocsize = toallocate;
1415 // no enough shared global memory
1421 BAMBOO_DEBUGPRINT(0xa001);
1422 BAMBOO_EXIT(0xa001);
1426 } // void * smemalloc_I(int, int, int)
1428 // receive object transferred from other cores
1429 // or the terminate message from other cores
1430 // Should be invoked in critical sections!!
1431 // NOTICE: following format is for threadsimulate version only
1432 // RAW version please see previous description
1433 // format: type + object
1434 // type: -1--stall msg
1436 // return value: 0--received an object
1437 // 1--received nothing
1438 // 2--received a Stall Msg
1439 // 3--received a lock Msg
1440 // RAW version: -1 -- received nothing
1441 // otherwise -- received msg type
1442 int receiveObject() {
1446 if(receiveMsg() == -1) {
1450 if(msgdataindex == msglength) {
1451 // received a whole msg
1456 // receive a object transfer msg
1457 struct transObjInfo * transObj =
1458 RUNMALLOC_I(sizeof(struct transObjInfo));
1462 BAMBOO_DEBUGPRINT(0xe880);
1465 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1467 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1469 BAMBOO_EXIT(0xa002);
1471 // store the object and its corresponding queue info, enqueue it later
1472 transObj->objptr = (void *)msgdata[2];
1473 transObj->length = (msglength - 3) / 2;
1474 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1475 for(k = 0; k < transObj->length; ++k) {
1476 transObj->queues[2*k] = msgdata[3+2*k];
1479 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1482 transObj->queues[2*k+1] = msgdata[3+2*k+1];
1485 BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1489 // check if there is an existing duplicate item
1491 struct QueueItem * qitem = getHead(&objqueue);
1492 struct QueueItem * prev = NULL;
1493 while(qitem != NULL) {
1494 struct transObjInfo * tmpinfo =
1495 (struct transObjInfo *)(qitem->objectptr);
1496 if(tmpinfo->objptr == transObj->objptr) {
1497 // the same object, remove outdate one
1498 RUNFREE(tmpinfo->queues);
1500 removeItem(&objqueue, qitem);
1506 qitem = getHead(&objqueue);
1508 qitem = getNextQueueItem(prev);
1511 addNewItem_I(&objqueue, (void *)transObj);
1513 ++(self_numreceiveobjs);
1518 // receive a stall msg
1519 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1520 // non startup core can not receive stall msg
1522 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1524 BAMBOO_EXIT(0xa003);
1526 if(msgdata[1] < NUMCORESACTIVE) {
1529 BAMBOO_DEBUGPRINT(0xe881);
1532 corestatus[msgdata[1]] = 0;
1533 numsendobjs[msgdata[1]] = msgdata[2];
1534 numreceiveobjs[msgdata[1]] = msgdata[3];
1539 // GC version have no lock msgs
1540 #ifndef MULTICORE_GC
1542 // receive lock request msg, handle it right now
1543 // check to see if there is a lock exist for the required obj
1544 // msgdata[1] -> lock type
1545 int data2 = msgdata[2]; // obj pointer
1546 int data3 = msgdata[3]; // lock
1547 int data4 = msgdata[4]; // request core
1548 // -1: redirected, 0: approved, 1: denied
1549 deny = processlockrequest(msgdata[1], data3, data2,
1550 data4, data4, true);
1552 // this lock request is redirected
1555 // send response msg
1556 // for 32 bit machine, the size is always 4 words
1557 int tmp = deny==1?LOCKDENY:LOCKGROUNT;
1559 cache_msg_4(data4, tmp, msgdata[1], data2, data3);
1561 send_msg_4(data4, tmp, msgdata[1], data2, data3, true);
1568 // receive lock grount msg
1569 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1571 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1573 BAMBOO_EXIT(0xa004);
1575 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1578 BAMBOO_DEBUGPRINT(0xe882);
1587 // conflicts on lockresults
1589 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1591 BAMBOO_EXIT(0xa005);
1597 // receive lock deny msg
1598 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1600 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1602 BAMBOO_EXIT(0xa006);
1604 if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
1607 BAMBOO_DEBUGPRINT(0xe883);
1616 // conflicts on lockresults
1618 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1620 BAMBOO_EXIT(0xa007);
1626 // receive lock release msg
1627 processlockrelease(msgdata[1], msgdata[2], 0, false);
1633 case PROFILEOUTPUT: {
1634 // receive an output profile data request msg
1635 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
1636 // startup core can not receive profile output finish msg
1637 BAMBOO_EXIT(0xa008);
1641 BAMBOO_DEBUGPRINT(0xe885);
1645 totalexetime = msgdata[1];
1646 outputProfileData();
1648 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
1650 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
1655 case PROFILEFINISH: {
1656 // receive a profile output finish msg
1657 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1658 // non startup core can not receive profile output finish msg
1660 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1662 BAMBOO_EXIT(0xa009);
1666 BAMBOO_DEBUGPRINT(0xe886);
1669 profilestatus[msgdata[1]] = 0;
1674 // GC version has no lock msgs
1675 #ifndef MULTICORE_GC
1676 case REDIRECTLOCK: {
1677 // receive a redirect lock request msg, handle it right now
1678 // check to see if there is a lock exist for the required obj
1679 int data1 = msgdata[1]; // lock type
1680 int data2 = msgdata[2]; // obj pointer
1681 int data3 = msgdata[3]; // redirect lock
1682 int data4 = msgdata[4]; // root request core
1683 int data5 = msgdata[5]; // request core
1684 deny = processlockrequest(msgdata[1], data3, data2, data5, data4, true);
1686 // this lock request is redirected
1689 // send response msg
1690 // for 32 bit machine, the size is always 4 words
1692 cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1693 data1, data2, data3);
1695 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
1696 data1, data2, data3, true);
1702 case REDIRECTGROUNT: {
1703 // receive a lock grant msg with redirect info
1704 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1706 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1708 BAMBOO_EXIT(0xa00a);
1710 if(lockobj == msgdata[2]) {
1713 BAMBOO_DEBUGPRINT(0xe891);
1718 RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
1723 // conflicts on lockresults
1725 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1727 BAMBOO_EXIT(0xa00b);
1732 case REDIRECTDENY: {
1733 // receive a lock deny msg with redirect info
1734 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1736 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1738 BAMBOO_EXIT(0xa00c);
1740 if(lockobj == msgdata[2]) {
1743 BAMBOO_DEBUGPRINT(0xe892);
1752 // conflicts on lockresults
1754 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1756 BAMBOO_EXIT(0xa00d);
1761 case REDIRECTRELEASE: {
1762 // receive a lock release msg with redirect info
1763 processlockrelease(msgdata[1], msgdata[2], msgdata[3], true);
1768 case STATUSCONFIRM: {
1769 // receive a status confirm info
1770 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1771 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1772 // wrong core to receive such msg
1773 BAMBOO_EXIT(0xa00e);
1775 // send response msg
1778 BAMBOO_DEBUGPRINT(0xe887);
1782 cache_msg_5(STARTUPCORE, STATUSREPORT,
1783 busystatus?1:0, BAMBOO_NUM_OF_CORE,
1784 self_numsendobjs, self_numreceiveobjs);
1786 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
1787 BAMBOO_NUM_OF_CORE, self_numsendobjs,
1788 self_numreceiveobjs, true);
1794 case STATUSREPORT: {
1795 // receive a status confirm info
1796 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1797 // wrong core to receive such msg
1799 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1801 BAMBOO_EXIT(0xa00f);
1805 BAMBOO_DEBUGPRINT(0xe888);
1811 corestatus[msgdata[2]] = msgdata[1];
1812 numsendobjs[msgdata[2]] = msgdata[3];
1813 numreceiveobjs[msgdata[2]] = msgdata[4];
1819 // receive a terminate msg
1822 BAMBOO_DEBUGPRINT(0xe889);
1831 // receive a shared memory request msg
1832 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1833 // wrong core to receive such msg
1835 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
1837 BAMBOO_EXIT(0xa010);
1841 BAMBOO_DEBUGPRINT(0xe88a);
1848 // is currently doing gc, dump this msg
1849 if(INITPHASE == gcphase) {
1850 // if still in the initphase of gc, send a startinit msg again
1852 cache_msg_1(msgdata[2], GCSTARTINIT);
1854 send_msg_1(msgdata[2], GCSTARTINIT, true);
1860 mem = smemalloc_I(msgdata[2], msgdata[1], &allocsize);
1862 // in this case, the gcflag of the startup core has been set
1863 // and the gc should be started later, then a GCSTARTINIT msg
1864 // will be sent to the requesting core to notice it to start gc
1865 // and try malloc again
1868 // send the start_va to request core
1870 cache_msg_3(msgdata[2], MEMRESPONSE, mem, allocsize);
1872 send_msg_3( msgdata[2], MEMRESPONSE, mem, allocsize, true);
1879 // receive a shared memory response msg
1882 BAMBOO_DEBUGPRINT(0xe88b);
1887 // is currently doing gc, dump this msg
1891 if(msgdata[2] == 0) {
1892 bamboo_smem_size = 0;
1896 // fill header to store the size of this mem block
1897 memset(msgdata[1], 0, BAMBOO_CACHE_LINE_SIZE);
1898 (*((int*)msgdata[1])) = msgdata[2];
1899 bamboo_smem_size = msgdata[2] - BAMBOO_CACHE_LINE_SIZE;
1900 bamboo_cur_msp = msgdata[1] + BAMBOO_CACHE_LINE_SIZE;
1902 bamboo_smem_size = msgdata[2];
1903 bamboo_cur_msp =(void*)(msgdata[1]);
1914 gcphase = INITPHASE;
1916 // is waiting for response of mem request
1917 // let it return NULL and start gc
1918 bamboo_smem_size = 0;
1919 bamboo_cur_msp = NULL;
1926 // receive a start GC msg
1929 BAMBOO_DEBUGPRINT(0xe88c);
1933 gcphase = MARKPHASE;
1937 case GCSTARTCOMPACT: {
1938 // a compact phase start msg
1939 gcblock2fill = msgdata[1];
1940 gcphase = COMPACTPHASE;
1944 case GCSTARTFLUSH: {
1945 // received a flush phase start msg
1946 gcphase = FLUSHPHASE;
1950 case GCFINISHINIT: {
1951 // received a init phase finish msg
1952 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1953 // non startup core can not receive this msg
1955 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1957 BAMBOO_EXIT(0xb001);
1960 BAMBOO_DEBUGPRINT(0xe88c);
1961 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1963 // All cores should do init GC
1964 if(msgdata[1] < NUMCORESACTIVE) {
1965 gccorestatus[msgdata[1]] = 0;
1969 case GCFINISHMARK: {
1970 // received a mark phase finish msg
1971 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1972 // non startup core can not receive this msg
1974 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1976 BAMBOO_EXIT(0xb002);
1978 // all cores should do mark
1979 if(msgdata[1] < NUMCORESACTIVE) {
1980 gccorestatus[msgdata[1]] = 0;
1981 gcnumsendobjs[msgdata[1]] = msgdata[2];
1982 gcnumreceiveobjs[msgdata[1]] = msgdata[3];
1987 case GCFINISHCOMPACT: {
1988 // received a compact phase finish msg
1989 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1990 // non startup core can not receive this msg
1993 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
1995 BAMBOO_EXIT(0xb003);
1997 int cnum = msgdata[1];
1998 int filledblocks = msgdata[2];
1999 int heaptop = msgdata[3];
2000 int data4 = msgdata[4];
2001 // only gc cores need to do compact
2002 if(cnum < NUMCORES4GC) {
2003 if(COMPACTPHASE == gcphase) {
2004 gcfilledblocks[cnum] = filledblocks;
2005 gcloads[cnum] = heaptop;
2012 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2014 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2016 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2020 gccorestatus[cnum] = 0;
2022 } // if(cnum < NUMCORES4GC)
2026 case GCFINISHFLUSH: {
2027 // received a flush phase finish msg
2028 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2029 // non startup core can not receive this msg
2032 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2034 BAMBOO_EXIT(0xb004);
2036 // all cores should do flush
2037 if(msgdata[1] < NUMCORESACTIVE) {
2038 gccorestatus[msgdata[1]] = 0;
2044 // received a GC finish msg
2045 gcphase = FINISHPHASE;
2049 case GCMARKCONFIRM: {
2050 // received a marked phase finish confirm request msg
2051 // all cores should do mark
2052 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2053 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2054 // wrong core to receive such msg
2055 BAMBOO_EXIT(0xb005);
2057 // send response msg
2059 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2060 gcbusystatus, gcself_numsendobjs,
2061 gcself_numreceiveobjs);
2063 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2064 gcbusystatus, gcself_numsendobjs,
2065 gcself_numreceiveobjs, true);
2071 case GCMARKREPORT: {
2072 // received a marked phase finish confirm response msg
2073 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2074 // wrong core to receive such msg
2076 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2078 BAMBOO_EXIT(0xb006);
2083 gccorestatus[msgdata[1]] = msgdata[2];
2084 gcnumsendobjs[msgdata[1]] = msgdata[3];
2085 gcnumreceiveobjs[msgdata[1]] = msgdata[4];
2091 // received a markedObj msg
2092 if(((int *)msgdata[1])[6] == INIT) {
2093 // this is the first time that this object is discovered,
2094 // set the flag as DISCOVERED
2095 ((int *)msgdata[1])[6] = DISCOVERED;
2096 gc_enqueue_I(msgdata[1]);
2098 gcself_numreceiveobjs++;
2099 gcbusystatus = true;
2104 // received a start moving objs msg
2106 gcdstcore = msgdata[1];
2107 gcmovestartaddr = msgdata[2];
2108 gcblock2fill = msgdata[3];
2112 case GCMAPREQUEST: {
2113 // received a mapping info request msg
2114 void * dstptr = NULL;
2115 //dstptr = mgchashSearch(msgdata[1]);
2116 RuntimeHashget(gcpointertbl, msgdata[1], &dstptr);
2117 //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2118 if(NULL == dstptr) {
2119 // no such pointer in this core, something is wrong
2121 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2122 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2124 BAMBOO_EXIT(0xb007);
2125 //assume that the object was not moved, use the original address
2126 /*if(isMsgSending) {
2127 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2129 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1], true);
2132 // send back the mapping info
2134 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
2136 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr, true);
2143 // received a mapping info response msg
2144 if(msgdata[1] != gcobj2map) {
2145 // obj not matched, something is wrong
2147 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2148 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2150 BAMBOO_EXIT(0xb008);
2152 gcmappedobj = msgdata[2];
2153 //mgchashInsert_I(gcobj2map, gcmappedobj);
2154 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2155 //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2161 case GCLOBJREQUEST: {
2162 // received a large objs info request msg
2163 transferMarkResults_I();
2168 // received a large objs info response msg
2171 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2173 BAMBOO_DEBUGPRINT_REG(msgdata[2]);
2175 BAMBOO_EXIT(0xb009);
2177 // store the mark result info
2178 int cnum = msgdata[2];
2179 gcloads[cnum] = msgdata[3];
2180 if(gcheaptop < msgdata[4]) {
2181 gcheaptop = msgdata[4];
2183 // large obj info here
2184 for(int k = 5; k < msgdata[1];) {
2185 int lobj = msgdata[k++];
2186 int length = msgdata[k++];
2187 gc_lobjenqueue_I(lobj, length, cnum);
2189 } // for(int k = 5; k < msgdata[1];)
2193 case GCLOBJMAPPING: {
2194 // received a large obj mapping info msg
2195 //mgchashInsert_I(msgdata[1], msgdata[2]);
2196 RuntimeHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2197 //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2206 memset(msgdata, '\0', sizeof(int) * msgdataindex);
2208 msglength = BAMBOO_MSG_BUF_LENGTH;
2211 BAMBOO_DEBUGPRINT(0xe88d);
2215 if(BAMBOO_MSG_AVAIL() != 0) {
2228 BAMBOO_DEBUGPRINT(0xe88e);
2232 /* if(isInterrupt) {
2240 int enqueuetasks(struct parameterwrapper *parameter,
2241 struct parameterwrapper *prevptr,
2242 struct ___Object___ *ptr,
2244 int numenterflags) {
2245 void * taskpointerarray[MAXTASKPARAMS];
2247 //int numparams=parameter->task->numParameters;
2248 int numiterators=parameter->task->numTotal-1;
2251 struct taskdescriptor * task=parameter->task;
2253 //this add the object to parameterwrapper
2254 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
2255 numenterflags, enterflags==NULL);
2257 /* Add enqueued object to parameter vector */
2258 taskpointerarray[parameter->slot]=ptr;
2260 /* Reset iterators */
2261 for(j=0; j<numiterators; j++) {
2262 toiReset(¶meter->iterators[j]);
2265 /* Find initial state */
2266 for(j=0; j<numiterators; j++) {
2268 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2269 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2271 /* Need to backtrack */
2272 toiReset(¶meter->iterators[j]);
2276 /* Nothing to enqueue */
2282 /* Enqueue current state */
2284 struct taskparamdescriptor *tpd=
2285 RUNMALLOC(sizeof(struct taskparamdescriptor));
2287 tpd->numParameters=numiterators+1;
2288 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
2290 for(j=0; j<=numiterators; j++) {
2291 //store the actual parameters
2292 tpd->parameterArray[j]=taskpointerarray[j];
2295 if ((/*!gencontains(failedtasks, tpd)&&*/
2296 !gencontains(activetasks,tpd))) {
2297 genputtable(activetasks, tpd, tpd);
2299 RUNFREE(tpd->parameterArray);
2303 /* This loop iterates to the next parameter combination */
2304 if (numiterators==0)
2307 for(j=numiterators-1; j<numiterators; j++) {
2309 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2310 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2312 /* Need to backtrack */
2313 toiReset(¶meter->iterators[j]);
2317 /* Nothing more to enqueue */
2325 int enqueuetasks_I(struct parameterwrapper *parameter,
2326 struct parameterwrapper *prevptr,
2327 struct ___Object___ *ptr,
2329 int numenterflags) {
2330 void * taskpointerarray[MAXTASKPARAMS];
2332 //int numparams=parameter->task->numParameters;
2333 int numiterators=parameter->task->numTotal-1;
2338 struct taskdescriptor * task=parameter->task;
2340 //this add the object to parameterwrapper
2341 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
2342 numenterflags, enterflags==NULL);
2344 /* Add enqueued object to parameter vector */
2345 taskpointerarray[parameter->slot]=ptr;
2347 /* Reset iterators */
2348 for(j=0; j<numiterators; j++) {
2349 toiReset(¶meter->iterators[j]);
2352 /* Find initial state */
2353 for(j=0; j<numiterators; j++) {
2355 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
2356 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2358 /* Need to backtrack */
2359 toiReset(¶meter->iterators[j]);
2363 /* Nothing to enqueue */
2369 /* Enqueue current state */
2371 struct taskparamdescriptor *tpd=
2372 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
2374 tpd->numParameters=numiterators+1;
2375 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
2377 for(j=0; j<=numiterators; j++) {
2378 //store the actual parameters
2379 tpd->parameterArray[j]=taskpointerarray[j];
2382 if ((/*!gencontains(failedtasks, tpd)&&*/
2383 !gencontains(activetasks,tpd))) {
2384 genputtable_I(activetasks, tpd, tpd);
2386 RUNFREE(tpd->parameterArray);
2390 /* This loop iterates to the next parameter combination */
2391 if (numiterators==0)
2394 for(j=numiterators-1; j<numiterators; j++) {
2396 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
2397 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
2399 /* Need to backtrack */
2400 toiReset(¶meter->iterators[j]);
2404 /* Nothing more to enqueue */
2418 int containstag(struct ___Object___ *ptr,
2419 struct ___TagDescriptor___ *tag);
2421 #ifndef MULTICORE_GC
2422 void releasewritelock_r(void * lock, void * redirectlock) {
2424 int reallock = (int)lock;
2425 targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
2428 BAMBOO_DEBUGPRINT(0xe671);
2429 BAMBOO_DEBUGPRINT_REG((int)lock);
2430 BAMBOO_DEBUGPRINT_REG(reallock);
2431 BAMBOO_DEBUGPRINT_REG(targetcore);
2434 if(targetcore == BAMBOO_NUM_OF_CORE) {
2435 BAMBOO_START_CRITICAL_SECTION_LOCK();
2437 BAMBOO_DEBUGPRINT(0xf001);
2439 // reside on this core
2440 if(!RuntimeHashcontainskey(locktbl, reallock)) {
2441 // no locks for this object, something is wrong
2442 BAMBOO_EXIT(0xa011);
2445 struct LockValue * lockvalue = NULL;
2447 BAMBOO_DEBUGPRINT(0xe672);
2449 RuntimeHashget(locktbl, reallock, &rwlock_obj);
2450 lockvalue = (struct LockValue *)rwlock_obj;
2452 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2455 lockvalue->redirectlock = (int)redirectlock;
2457 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
2460 BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
2462 BAMBOO_DEBUGPRINT(0xf000);
2466 // send lock release with redirect info msg
2467 // for 32 bit machine, the size is always 4 words
2468 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
2469 (int)redirectlock, false);
2474 void executetasks() {
2475 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
2478 struct ___Object___ * tmpparam = NULL;
2479 struct parameterdescriptor * pd=NULL;
2480 struct parameterwrapper *pw=NULL;
2490 while(hashsize(activetasks)>0) {
2495 BAMBOO_DEBUGPRINT(0xe990);
2498 /* See if there are any active tasks */
2499 //if (hashsize(activetasks)>0) {
2502 #ifdef ACCURATEPROFILE
2503 profileTaskStart("tpd checking");
2507 //clock1 = BAMBOO_GET_EXE_TIME();
2510 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
2511 genfreekey(activetasks, currtpd);
2513 numparams=currtpd->task->numParameters;
2514 numtotal=currtpd->task->numTotal;
2516 // clear the lockRedirectTbl
2517 // (TODO, this table should be empty after all locks are released)
2519 /*for(j = 0; j < MAXTASKPARAMS; j++) {
2520 runtime_locks[j].redirectlock = 0;
2521 runtime_locks[j].value = 0;
2523 // get all required locks
2524 runtime_locklen = 0;
2525 // check which locks are needed
2526 for(i = 0; i < numparams; i++) {
2527 void * param = currtpd->parameterArray[i];
2531 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
2533 taskpointerarray[i+OFFSET]=param;
2536 if(((struct ___Object___ *)param)->lock == NULL) {
2537 tmplock = (int)param;
2539 tmplock = (int)(((struct ___Object___ *)param)->lock);
2541 // insert into the locks array
2542 for(j = 0; j < runtime_locklen; j++) {
2543 if(runtime_locks[j].value == tmplock) {
2546 } else if(runtime_locks[j].value > tmplock) {
2551 int h = runtime_locklen;
2553 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
2554 runtime_locks[h].value = runtime_locks[h-1].value;
2556 runtime_locks[j].value = tmplock;
2557 runtime_locks[j].redirectlock = (int)param;
2560 } // line 2713: for(i = 0; i < numparams; i++)
2561 // grab these required locks
2563 BAMBOO_DEBUGPRINT(0xe991);
2566 //clock2 = BAMBOO_GET_EXE_TIME();
2568 for(i = 0; i < runtime_locklen; i++) {
2569 int * lock = (int *)(runtime_locks[i].redirectlock);
2571 // require locks for this parameter if it is not a startup object
2573 BAMBOO_DEBUGPRINT_REG((int)lock);
2574 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
2577 BAMBOO_START_CRITICAL_SECTION();
2579 BAMBOO_DEBUGPRINT(0xf001);
2582 //isInterrupt = false;
2585 BAMBOO_WAITING_FOR_LOCK();
2589 while(BAMBOO_WAITING_FOR_LOCK() != -1) {
2593 grount = lockresult;
2603 //isInterrupt = true;
2605 BAMBOO_CLOSE_CRITICAL_SECTION();
2607 BAMBOO_DEBUGPRINT(0xf000);
2612 BAMBOO_DEBUGPRINT(0xe992);
2613 BAMBOO_DEBUGPRINT_REG(lock);
2615 // check if has the lock already
2616 // can not get the lock, try later
2617 // release all grabbed locks for previous parameters
2618 for(j = 0; j < i; ++j) {
2619 lock = (int*)(runtime_locks[j].redirectlock);
2620 releasewritelock(lock);
2622 genputtable(activetasks, currtpd, currtpd);
2623 if(hashsize(activetasks) == 1) {
2624 // only one task right now, wait a little while before next try
2630 #ifdef ACCURATEPROFILE
2631 // fail, set the end of the checkTaskInfo
2638 } // line 2752: for(i = 0; i < runtime_locklen; i++)
2641 clock3 = BAMBOO_GET_EXE_TIME();
2642 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
2645 BAMBOO_DEBUGPRINT(0xe993);
2647 /* Make sure that the parameters are still in the queues */
2648 for(i=0; i<numparams; i++) {
2649 void * parameter=currtpd->parameterArray[i];
2653 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
2654 classsize[((struct ___Object___ *)parameter)->type]);
2656 tmpparam = (struct ___Object___ *)parameter;
2657 pd=currtpd->task->descriptorarray[i];
2658 pw=(struct parameterwrapper *) pd->queue;
2659 /* Check that object is still in queue */
2661 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
2663 BAMBOO_DEBUGPRINT(0xe994);
2664 BAMBOO_DEBUGPRINT_REG(parameter);
2666 // release grabbed locks
2667 for(j = 0; j < runtime_locklen; ++j) {
2668 int * lock = (int *)(runtime_locks[j].redirectlock);
2669 releasewritelock(lock);
2671 RUNFREE(currtpd->parameterArray);
2677 /* Check if the object's flags still meets requirements */
2681 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
2682 andmask=pw->intarray[tmpi*2];
2683 checkmask=pw->intarray[tmpi*2+1];
2684 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
2690 // flags are never suitable
2691 // remove this obj from the queue
2693 int UNUSED, UNUSED2;
2696 BAMBOO_DEBUGPRINT(0xe995);
2697 BAMBOO_DEBUGPRINT_REG(parameter);
2699 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
2700 (int *) &enterflags, &UNUSED, &UNUSED2);
2701 ObjectHashremove(pw->objectset, (int)parameter);
2702 if (enterflags!=NULL)
2703 RUNFREE(enterflags);
2704 // release grabbed locks
2705 for(j = 0; j < runtime_locklen; ++j) {
2706 int * lock = (int *)(runtime_locks[j].redirectlock);
2707 releasewritelock(lock);
2709 RUNFREE(currtpd->parameterArray);
2713 #ifdef ACCURATEPROFILE
2714 // fail, set the end of the checkTaskInfo
2719 } // line 2878: if (!ismet)
2723 /* Check that object still has necessary tags */
2724 for(j=0; j<pd->numbertags; j++) {
2725 int slotid=pd->tagarray[2*j]+numparams;
2726 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
2727 if (!containstag(parameter, tagd)) {
2729 BAMBOO_DEBUGPRINT(0xe996);
2732 // release grabbed locks
2734 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
2735 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
2736 releasewritelock(lock);
2739 RUNFREE(currtpd->parameterArray);
2743 } // line2911: if (!containstag(parameter, tagd))
2744 } // line 2808: for(j=0; j<pd->numbertags; j++)
2746 taskpointerarray[i+OFFSET]=parameter;
2747 } // line 2824: for(i=0; i<numparams; i++)
2749 for(; i<numtotal; i++) {
2750 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
2755 /* Actually call task */
2757 ((int *)taskpointerarray)[0]=currtpd->numParameters;
2758 taskpointerarray[1]=NULL;
2761 #ifdef ACCURATEPROFILE
2762 // check finish, set the end of the checkTaskInfo
2765 profileTaskStart(currtpd->task->name);
2769 //clock4 = BAMBOO_GET_EXE_TIME();
2770 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
2773 BAMBOO_DEBUGPRINT(0xe997);
2775 ((void(*) (void **))currtpd->task->taskptr)(taskpointerarray);
2778 //clock5 = BAMBOO_GET_EXE_TIME();
2779 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
2782 #ifdef ACCURATEPROFILE
2783 // task finish, set the end of the checkTaskInfo
2785 // new a PostTaskInfo for the post-task execution
2786 profileTaskStart("post task execution");
2790 BAMBOO_DEBUGPRINT(0xe998);
2791 BAMBOO_DEBUGPRINT_REG(islock);
2796 BAMBOO_DEBUGPRINT(0xe999);
2798 for(i = 0; i < runtime_locklen; ++i) {
2799 void * ptr = (void *)(runtime_locks[i].redirectlock);
2800 int * lock = (int *)(runtime_locks[i].value);
2802 BAMBOO_DEBUGPRINT_REG((int)ptr);
2803 BAMBOO_DEBUGPRINT_REG((int)lock);
2804 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
2806 #ifndef MULTICORE_GC
2807 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
2809 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
2810 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
2811 releasewritelock_r(lock, (int *)redirectlock);
2816 releasewritelock(ptr);
2819 } // line 3015: if(islock)
2822 //clock6 = BAMBOO_GET_EXE_TIME();
2823 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
2826 // post task execution finish, set the end of the postTaskInfo
2830 // Free up task parameter descriptor
2831 RUNFREE(currtpd->parameterArray);
2835 BAMBOO_DEBUGPRINT(0xe99a);
2838 //clock7 = BAMBOO_GET_EXE_TIME();
2839 //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));
2842 //} // if (hashsize(activetasks)>0)
2843 } // while(hashsize(activetasks)>0)
2845 BAMBOO_DEBUGPRINT(0xe99b);
2849 /* This function processes an objects tags */
2850 void processtags(struct parameterdescriptor *pd,
2852 struct parameterwrapper *parameter,
2853 int * iteratorcount,
2858 for(i=0; i<pd->numbertags; i++) {
2859 int slotid=pd->tagarray[2*i];
2860 int tagid=pd->tagarray[2*i+1];
2862 if (statusarray[slotid+numparams]==0) {
2863 parameter->iterators[*iteratorcount].istag=1;
2864 parameter->iterators[*iteratorcount].tagid=tagid;
2865 parameter->iterators[*iteratorcount].slot=slotid+numparams;
2866 parameter->iterators[*iteratorcount].tagobjectslot=index;
2867 statusarray[slotid+numparams]=1;
2874 void processobject(struct parameterwrapper *parameter,
2876 struct parameterdescriptor *pd,
2882 struct ObjectHash * objectset=
2883 ((struct parameterwrapper *)pd->queue)->objectset;
2885 parameter->iterators[*iteratorcount].istag=0;
2886 parameter->iterators[*iteratorcount].slot=index;
2887 parameter->iterators[*iteratorcount].objectset=objectset;
2888 statusarray[index]=1;
2890 for(i=0; i<pd->numbertags; i++) {
2891 int slotid=pd->tagarray[2*i];
2892 //int tagid=pd->tagarray[2*i+1];
2893 if (statusarray[slotid+numparams]!=0) {
2894 /* This tag has already been enqueued, use it to narrow search */
2895 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
2900 parameter->iterators[*iteratorcount].numtags=tagcount;
2905 /* This function builds the iterators for a task & parameter */
2907 void builditerators(struct taskdescriptor * task,
2909 struct parameterwrapper * parameter) {
2910 int statusarray[MAXTASKPARAMS];
2912 int numparams=task->numParameters;
2913 int iteratorcount=0;
2914 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
2916 statusarray[index]=1; /* Initial parameter */
2917 /* Process tags for initial iterator */
2919 processtags(task->descriptorarray[index], index, parameter,
2920 &iteratorcount, statusarray, numparams);
2924 /* Check for objects with existing tags */
2925 for(i=0; i<numparams; i++) {
2926 if (statusarray[i]==0) {
2927 struct parameterdescriptor *pd=task->descriptorarray[i];
2929 for(j=0; j<pd->numbertags; j++) {
2930 int slotid=pd->tagarray[2*j];
2931 if(statusarray[slotid+numparams]!=0) {
2932 processobject(parameter, i, pd, &iteratorcount, statusarray,
2934 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2941 /* Next do objects w/ unbound tags*/
2943 for(i=0; i<numparams; i++) {
2944 if (statusarray[i]==0) {
2945 struct parameterdescriptor *pd=task->descriptorarray[i];
2946 if (pd->numbertags>0) {
2947 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2948 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2954 /* Nothing with a tag enqueued */
2956 for(i=0; i<numparams; i++) {
2957 if (statusarray[i]==0) {
2958 struct parameterdescriptor *pd=task->descriptorarray[i];
2959 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
2960 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
2973 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2976 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
2977 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
2979 printf("%s\n", task->name);
2981 for(j=0; j<task->numParameters; j++) {
2982 struct parameterdescriptor *param=task->descriptorarray[j];
2983 struct parameterwrapper *parameter=param->queue;
2984 struct ObjectHash * set=parameter->objectset;
2985 struct ObjectIterator objit;
2987 printf(" Parameter %d\n", j);
2989 ObjectHashiterator(set, &objit);
2990 while(ObjhasNext(&objit)) {
2991 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
2992 struct ___Object___ * tagptr=obj->___tags___;
2993 int nonfailed=Objdata4(&objit);
2994 int numflags=Objdata3(&objit);
2995 int flags=Objdata2(&objit);
2998 printf(" Contains %lx\n", obj);
2999 printf(" flag=%d\n", obj->flag);
3002 } else if (tagptr->type==TAGTYPE) {
3004 printf(" tag=%lx\n",tagptr);
3010 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3011 for(; tagindex<ao->___cachedCode___; tagindex++) {
3013 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3026 /* This function processes the task information to create queues for
3027 each parameter type. */
3029 void processtasks() {
3031 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3034 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3035 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3038 /* Build objectsets */
3039 for(j=0; j<task->numParameters; j++) {
3040 struct parameterdescriptor *param=task->descriptorarray[j];
3041 struct parameterwrapper *parameter=param->queue;
3042 parameter->objectset=allocateObjectHash(10);
3043 parameter->task=task;
3046 /* Build iterators for parameters */
3047 for(j=0; j<task->numParameters; j++) {
3048 struct parameterdescriptor *param=task->descriptorarray[j];
3049 struct parameterwrapper *parameter=param->queue;
3050 builditerators(task, j, parameter);
3055 void toiReset(struct tagobjectiterator * it) {
3058 } else if (it->numtags>0) {
3061 ObjectHashiterator(it->objectset, &it->it);
3065 int toiHasNext(struct tagobjectiterator *it,
3066 void ** objectarray OPTARG(int * failed)) {
3069 /* Get object with tags */
3070 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3071 struct ___Object___ *tagptr=obj->___tags___;
3072 if (tagptr->type==TAGTYPE) {
3073 if ((it->tagobjindex==0)&& /* First object */
3074 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3079 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3080 int tagindex=it->tagobjindex;
3081 for(; tagindex<ao->___cachedCode___; tagindex++) {
3082 struct ___TagDescriptor___ *td=
3083 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3084 if (td->flag==it->tagid) {
3085 it->tagobjindex=tagindex; /* Found right type of tag */
3091 } else if (it->numtags>0) {
3092 /* Use tags to locate appropriate objects */
3093 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3094 struct ___Object___ *objptr=tag->flagptr;
3096 if (objptr->type!=OBJECTARRAYTYPE) {
3097 if (it->tagobjindex>0)
3099 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3101 for(i=1; i<it->numtags; i++) {
3102 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3103 if (!containstag(objptr,tag2))
3108 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3111 for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++) {
3112 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3113 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3115 for(i=1; i<it->numtags; i++) {
3116 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3117 if (!containstag(objptr,tag2))
3120 it->tagobjindex=tagindex;
3125 it->tagobjindex=tagindex;
3129 return ObjhasNext(&it->it);
3133 int containstag(struct ___Object___ *ptr,
3134 struct ___TagDescriptor___ *tag) {
3136 struct ___Object___ * objptr=tag->flagptr;
3137 if (objptr->type==OBJECTARRAYTYPE) {
3138 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3139 for(j=0; j<ao->___cachedCode___; j++) {
3140 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3150 void toiNext(struct tagobjectiterator *it,
3151 void ** objectarray OPTARG(int * failed)) {
3152 /* hasNext has all of the intelligence */
3155 /* Get object with tags */
3156 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3157 struct ___Object___ *tagptr=obj->___tags___;
3158 if (tagptr->type==TAGTYPE) {
3160 objectarray[it->slot]=tagptr;
3162 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3163 objectarray[it->slot]=
3164 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3166 } else if (it->numtags>0) {
3167 /* Use tags to locate appropriate objects */
3168 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3169 struct ___Object___ *objptr=tag->flagptr;
3170 if (objptr->type!=OBJECTARRAYTYPE) {
3172 objectarray[it->slot]=objptr;
3174 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3175 objectarray[it->slot]=
3176 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3179 /* Iterate object */
3180 objectarray[it->slot]=(void *)Objkey(&it->it);
3186 inline void profileTaskStart(char * taskname) {
3187 if(!taskInfoOverflow) {
3188 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
3189 taskInfoArray[taskInfoIndex] = taskInfo;
3190 taskInfo->taskName = taskname;
3191 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
3192 taskInfo->endTime = -1;
3193 taskInfo->exitIndex = -1;
3194 taskInfo->newObjs = NULL;
3198 inline void profileTaskEnd() {
3199 if(!taskInfoOverflow) {
3200 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
3202 if(taskInfoIndex == TASKINFOLENGTH) {
3203 taskInfoOverflow = true;
3204 //taskInfoIndex = 0;
3209 // output the profiling data
3210 void outputProfileData() {
3213 unsigned long long totaltasktime = 0;
3214 unsigned long long preprocessingtime = 0;
3215 unsigned long long objqueuecheckingtime = 0;
3216 unsigned long long postprocessingtime = 0;
3217 //int interruptiontime = 0;
3218 unsigned long long other = 0;
3219 unsigned long long averagetasktime = 0;
3222 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
3223 // output task related info
3224 for(i = 0; i < taskInfoIndex; i++) {
3225 TaskInfo* tmpTInfo = taskInfoArray[i];
3226 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
3227 printf("%s, %lld, %lld, %lld, %lld",
3228 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
3229 duration, tmpTInfo->exitIndex);
3230 // summarize new obj info
3231 if(tmpTInfo->newObjs != NULL) {
3232 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3233 struct RuntimeIterator * iter = NULL;
3234 while(0 == isEmpty(tmpTInfo->newObjs)) {
3235 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3236 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3238 RuntimeHashget(nobjtbl, (int)objtype, &num);
3239 RuntimeHashremovekey(nobjtbl, (int)objtype);
3241 RuntimeHashadd(nobjtbl, (int)objtype, num);
3243 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3245 //printf(stderr, "new obj!\n");
3248 // output all new obj info
3249 iter = RuntimeHashcreateiterator(nobjtbl);
3250 while(RunhasNext(iter)) {
3251 char * objtype = (char *)Runkey(iter);
3252 int num = Runnext(iter);
3253 printf(", %s, %d", objtype, num);
3257 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
3258 preprocessingtime += duration;
3259 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
3260 postprocessingtime += duration;
3261 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
3262 objqueuecheckingtime += duration;
3264 totaltasktime += duration;
3265 averagetasktime += duration;
3270 if(taskInfoOverflow) {
3271 printf("Caution: task info overflow!\n");
3274 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
3275 averagetasktime /= tasknum;
3277 printf("\nTotal time: %lld\n", totalexetime);
3278 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
3279 (int)(((double)totaltasktime/(double)totalexetime)*100));
3280 printf("Total objqueue checking time: %lld (%d%%)\n",
3281 objqueuecheckingtime,
3282 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
3283 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
3284 (int)(((double)preprocessingtime/(double)totalexetime)*100));
3285 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
3286 (int)(((double)postprocessingtime/(double)totalexetime)*100));
3287 printf("Other time: %lld (%d%%)\n", other,
3288 (int)(((double)other/(double)totalexetime)*100));
3290 printf("\nAverage task execution time: %lld\n", averagetasktime);
3295 BAMBOO_DEBUGPRINT(0xdddd);
3296 // output task related info
3297 for(i= 0; i < taskInfoIndex; i++) {
3298 TaskInfo* tmpTInfo = taskInfoArray[i];
3299 char* tmpName = tmpTInfo->taskName;
3300 int nameLen = strlen(tmpName);
3301 BAMBOO_DEBUGPRINT(0xddda);
3302 for(j = 0; j < nameLen; j++) {
3303 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
3305 BAMBOO_DEBUGPRINT(0xdddb);
3306 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
3307 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
3308 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
3309 if(tmpTInfo->newObjs != NULL) {
3310 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
3311 struct RuntimeIterator * iter = NULL;
3312 while(0 == isEmpty(tmpTInfo->newObjs)) {
3313 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
3314 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
3316 RuntimeHashget(nobjtbl, (int)objtype, &num);
3317 RuntimeHashremovekey(nobjtbl, (int)objtype);
3319 RuntimeHashadd(nobjtbl, (int)objtype, num);
3321 RuntimeHashadd(nobjtbl, (int)objtype, 1);
3325 // ouput all new obj info
3326 iter = RuntimeHashcreateiterator(nobjtbl);
3327 while(RunhasNext(iter)) {
3328 char * objtype = (char *)Runkey(iter);
3329 int num = Runnext(iter);
3330 int nameLen = strlen(objtype);
3331 BAMBOO_DEBUGPRINT(0xddda);
3332 for(j = 0; j < nameLen; j++) {
3333 BAMBOO_DEBUGPRINT_REG(objtype[j]);
3335 BAMBOO_DEBUGPRINT(0xdddb);
3336 BAMBOO_DEBUGPRINT_REG(num);
3339 BAMBOO_DEBUGPRINT(0xdddc);
3342 if(taskInfoOverflow) {
3343 BAMBOO_DEBUGPRINT(0xefee);
3346 // output interrupt related info
3347 /*for(i = 0; i < interruptInfoIndex; i++) {
3348 InterruptInfo* tmpIInfo = interruptInfoArray[i];
3349 BAMBOO_DEBUGPRINT(0xddde);
3350 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
3351 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
3352 BAMBOO_DEBUGPRINT(0xdddf);
3355 if(interruptInfoOverflow) {
3356 BAMBOO_DEBUGPRINT(0xefef);
3359 BAMBOO_DEBUGPRINT(0xeeee);
3362 #endif // #ifdef PROFILE