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,
30 int core2test[1][5] = {
34 int core2test[56][5] = {
35 { 0, -1, 7, -1, 1}, { 1, -1, 8, 0, 2}, { 2, -1, 9, 1, 3},
36 { 3, -1, 10, 2, 4}, { 4, -1, 11, 3, 5}, { 5, -1, 12, 4, 6},
37 { 6, -1, 13, 5, -1}, { 7, 0, 14, -1, 8}, { 8, 1, 15, 7, 9},
38 { 9, 2, 16, 8, 10}, {10, 3, 17, 9, 11}, {11, 4, 18, 10, 12},
39 {12, 5, 19, 11, 13}, {13, 6, 20, 12, -1}, {14, 7, 21, -1, 15},
40 {15, 8, 22, 14, 16}, {16, 9, 23, 15, 17}, {17, 10, 24, 16, 18},
41 {18, 11, 25, 17, 19}, {19, 12, 26, 18, 20}, {20, 13, 27, 19, -1},
42 {21, 14, 28, -1, 22}, {22, 15, 29, 21, 23}, {23, 16, 30, 22, 24},
43 {24, 17, 31, 23, 25}, {25, 18, 32, 24, 26}, {26, 19, 33, 25, 27},
44 {27, 20, 34, 26, -1}, {28, 21, 35, -1, 29}, {29, 22, 36, 28, 30},
45 {30, 23, 37, 29, 31}, {31, 24, 38, 30, 32}, {32, 25, 39, 31, 33},
46 {33, 26, 40, 32, 34}, {34, 27, 41, 33, -1}, {35, 28, 42, -1, 36},
47 {36, 29, 43, 35, 37}, {37, 30, 44, 36, 38}, {38, 31, 45, 37, 39},
48 {39, 32, 46, 38, 40}, {40, 33, 47, 39, 41}, {41, 34, 48, 40, -1},
49 {42, 35, 49, -1, 43}, {43, 36, 50, 42, 44}, {44, 37, 51, 43, 45},
50 {45, 38, 52, 44, 46}, {46, 39, 53, 45, 47}, {47, 40, 54, 46, 48},
51 {48, 41, 55, 47, -1}, {49, 42, -1, -1, 50}, {50, 43, -1, 49, 51},
52 {51, 44, -1, 50, 52}, {52, 45, -1, 51, 53}, {53, 46, -1, 52, 54},
53 {54, 47, -1, 53, 55}, {55, 48, -1, 54, -1}
56 int core2test[62][5] = {
57 { 0, -1, 6, -1, 1}, { 1, -1, 7, 0, 2}, { 2, -1, 8, 1, 3},
58 { 3, -1, 9, 2, 4}, { 4, -1, 10, 3, 5}, { 5, -1, 11, 4, -1},
59 { 6, 0, 14, -1, 7}, { 7, 1, 15, 6, 8}, { 8, 2, 16, 7, 9},
60 { 9, 3, 17, 8, 10}, {10, 4, 18, 9, 11}, {11, 5, 19, 10, 12},
61 {12, -1, 20, 11, 13}, {13, -1, 21, 12, -1}, {14, 6, 22, -1, 15},
62 {15, 7, 23, 14, 16}, {16, 8, 24, 15, 17}, {17, 9, 25, 16, 18},
63 {18, 10, 26, 17, 19}, {19, 11, 27, 18, 20}, {20, 12, 28, 19, 21},
64 {21, 13, 29, 28, -1}, {22, 14, 30, -1, 23}, {23, 15, 31, 22, 24},
65 {24, 16, 32, 23, 25}, {25, 17, 33, 24, 26}, {26, 18, 34, 25, 27},
66 {27, 19, 35, 26, 28}, {28, 20, 36, 27, 29}, {29, 21, 37, 28, -1},
67 {30, 22, 38, -1, 31}, {31, 23, 39, 30, 32}, {32, 24, 40, 31, 33},
68 {33, 25, 41, 32, 34}, {34, 26, 42, 33, 35}, {35, 27, 43, 34, 36},
69 {36, 28, 44, 35, 37}, {37, 29, 45, 36, -1}, {38, 30, 46, -1, 39},
70 {39, 31, 47, 38, 40}, {40, 32, 48, 39, 41}, {41, 33, 49, 40, 42},
71 {42, 34, 50, 41, 43}, {43, 35, 51, 42, 44}, {44, 36, 52, 43, 45},
72 {45, 37, 53, 44, -1}, {46, 38, 54, -1, 47}, {47, 39, 55, 46, 48},
73 {48, 40, 56, 47, 49}, {49, 41, 57, 48, 50}, {50, 42, 58, 49, 51},
74 {51, 43, 59, 50, 52}, {52, 44, 60, 51, 53}, {53, 45, 61, 52, -1},
75 {54, 46, -1, -1, 55}, {55, 47, -1, 54, 56}, {56, 48, -1, 55, 57},
76 {57, 49, -1, 56, 59}, {58, 50, -1, 57, 59}, {59, 51, -1, 58, 60},
77 {60, 52, -1, 59, 61}, {61, 53, -1, 60, -1}
83 inline __attribute__((always_inline))
84 void setupsmemmode(void) {
86 // Only allocate local mem chunks to each core.
87 // If a core has used up its local shared memory, start gc.
88 bamboo_smem_mode = SMEMLOCAL;
90 // Allocate the local shared memory to each core with the highest priority,
91 // if a core has used up its local shared memory, try to allocate the
92 // shared memory that belong to its neighbours, if also failed, start gc.
93 bamboo_smem_mode = SMEMFIXED;
95 // Allocate the local shared memory to each core with the highest priority,
96 // if a core has used up its local shared memory, try to allocate the
97 // shared memory that belong to its neighbours first, if failed, allocate
98 // the shared memory globally. If all the shared memory has been used up,
100 bamboo_smem_mode = SMEMMIXED;
102 // Allocate all the memory chunks globally, do not consider the host cores
103 // When all the shared memory are used up, start gc.
104 bamboo_smem_mode = SMEMGLOBAL;
106 // defaultly using local mode
107 //bamboo_smem_mode = SMEMLOCAL;
108 //bamboo_smem_mode = SMEMGLOBAL;
109 //bamboo_smem_mode = SMEMFIXED;
111 } // void setupsmemmode(void)
114 inline __attribute__((always_inline))
115 void initruntimedata() {
117 // initialize the arrays
118 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
119 // startup core to initialize corestatus[]
120 for(i = 0; i < NUMCORESACTIVE; ++i) {
123 numreceiveobjs[i] = 0;
125 // initialize the profile data arrays
126 profilestatus[i] = 1;
130 gcnumsendobjs[i] = 0;
131 gcnumreceiveobjs[i] = 0;
133 } // for(i = 0; i < NUMCORESACTIVE; ++i)
135 for(i = 0; i < NUMCORES4GC; ++i) {
137 gcrequiredmems[i] = 0;
139 gcfilledblocks[i] = 0;
140 } // for(i = 0; i < NUMCORES4GC; ++i)
143 gc_infoOverflow = false;
154 self_numsendobjs = 0;
155 self_numreceiveobjs = 0;
157 for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
162 msglength = BAMBOO_MSG_BUF_LENGTH;
164 for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
170 isMsgHanging = false;
171 //isMsgSending = false;
174 bamboo_cur_msp = NULL;
175 bamboo_smem_size = 0;
176 totransobjqueue = createQueue_I();
180 gcprocessing = false;
181 gcphase = FINISHPHASE;
183 gcself_numsendobjs = 0;
184 gcself_numreceiveobjs = 0;
185 gcmarkedptrbound = 0;
186 //mgchashCreate(2000, 0.75);
187 gcpointertbl = allocateRuntimeHash_I(20);
188 //gcpointertbl = allocateMGCHash(20);
189 gcforwardobjtbl = allocateMGCHash_I(20, 3);
192 //gcismapped = false;
201 gcsbstarttbl = BAMBOO_BASE_VA;
202 bamboo_smemtbl = (void *)gcsbstarttbl
203 + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
204 if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
205 int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
206 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
208 unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
209 while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
210 t_size = t_size << 1;
213 t_size = tmp_k >> kk;
214 gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);//allocateGCSharedHash_I(20);
218 BAMBOO_MEMSET_WH(gcrpointertbls,0,sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
219 //sizeof(struct RuntimeHash *)*NUMCORES4GC);
221 // create the lock table, lockresult table and obj queue
224 (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
225 /* Set allocation blocks*/
226 locktable.listhead=NULL;
227 locktable.listtail=NULL;
229 locktable.numelements = 0;
234 lockRedirectTbl = allocateRuntimeHash_I(20);
235 objRedirectLockTbl = allocateRuntimeHash_I(20);
240 objqueue.head = NULL;
241 objqueue.tail = NULL;
247 //isInterrupt = true;
251 taskInfoOverflow = false;
253 interruptInfoIndex = 0;
254 interruptInfoOverflow = false;
257 for(i = 0; i < MAXTASKPARAMS; i++) {
258 runtime_locks[i].redirectlock = 0;
259 runtime_locks[i].value = 0;
264 inline __attribute__((always_inline))
265 void disruntimedata() {
268 freeRuntimeHash(gcpointertbl);
269 //freeMGCHash(gcpointertbl);
270 freeMGCHash(gcforwardobjtbl);
271 // for mapping info structures
272 //freeRuntimeHash(gcrcoretbl);
274 freeRuntimeHash(lockRedirectTbl);
275 freeRuntimeHash(objRedirectLockTbl);
276 RUNFREE(locktable.bucket);
278 if(activetasks != NULL) {
279 genfreehashtable(activetasks);
281 if(currtpd != NULL) {
282 RUNFREE(currtpd->parameterArray);
286 BAMBOO_LOCAL_MEM_CLOSE();
287 BAMBOO_SHARE_MEM_CLOSE();
290 inline __attribute__((always_inline))
291 bool checkObjQueue() {
293 struct transObjInfo * objInfo = NULL;
297 #ifdef ACCURATEPROFILE
298 bool isChecking = false;
299 if(!isEmpty(&objqueue)) {
300 profileTaskStart("objqueue checking");
302 } // if(!isEmpty(&objqueue))
306 while(!isEmpty(&objqueue)) {
308 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
310 BAMBOO_DEBUGPRINT(0xf001);
313 //isInterrupt = false;
316 BAMBOO_DEBUGPRINT(0xeee1);
319 objInfo = (struct transObjInfo *)getItem(&objqueue);
320 obj = objInfo->objptr;
322 BAMBOO_DEBUGPRINT_REG((int)obj);
324 // grab lock and flush the obj
328 BAMBOO_WAITING_FOR_LOCK(0);
329 // check for outgoing sends
330 /*if (isMsgHanging) {
331 extern inline void send_hanging_msg(bool);
332 send_hanging_msg(true);
334 } // while(!lockflag)
337 BAMBOO_DEBUGPRINT_REG(grount);
352 BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
353 BAMBOO_CACHE_FLUSH_RANGE((int)obj,
354 classsize[((struct ___Object___ *)obj)->type]);
356 // enqueue the object
357 for(k = 0; k < objInfo->length; ++k) {
358 int taskindex = objInfo->queues[2 * k];
359 int paramindex = objInfo->queues[2 * k + 1];
360 struct parameterwrapper ** queues =
361 &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
363 BAMBOO_DEBUGPRINT_REG(taskindex);
364 BAMBOO_DEBUGPRINT_REG(paramindex);
365 struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
366 tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
367 BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
368 (long)obj, tmpptr->flag);
370 enqueueObject_I(obj, queues, 1);
372 BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
374 } // for(k = 0; k < objInfo->length; ++k)
375 releasewritelock_I(obj);
376 RUNFREE(objInfo->queues);
380 // put it at the end of the queue if no update version in the queue
381 struct QueueItem * qitem = getHead(&objqueue);
382 struct QueueItem * prev = NULL;
383 while(qitem != NULL) {
384 struct transObjInfo * tmpinfo =
385 (struct transObjInfo *)(qitem->objectptr);
386 if(tmpinfo->objptr == obj) {
387 // the same object in the queue, which should be enqueued
388 // recently. Current one is outdate, do not re-enqueue it
389 RUNFREE(objInfo->queues);
394 } // if(tmpinfo->objptr == obj)
395 qitem = getNextQueueItem(prev);
396 } // while(qitem != NULL)
397 // try to execute active tasks already enqueued first
398 addNewItem_I(&objqueue, objInfo);
400 //isInterrupt = true;
403 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
405 BAMBOO_DEBUGPRINT(0xf000);
409 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
411 BAMBOO_DEBUGPRINT(0xf000);
413 } // while(!isEmpty(&objqueue))
416 #ifdef ACCURATEPROFILE
424 BAMBOO_DEBUGPRINT(0xee02);
429 inline __attribute__((always_inline))
430 void checkCoreStatus() {
431 bool allStall = false;
435 (waitconfirm && (numconfirm == 0))) {
437 BAMBOO_DEBUGPRINT(0xee04);
438 BAMBOO_DEBUGPRINT_REG(waitconfirm);
440 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
442 BAMBOO_DEBUGPRINT(0xf001);
444 corestatus[BAMBOO_NUM_OF_CORE] = 0;
445 numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
446 numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
447 // check the status of all cores
450 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
452 for(i = 0; i < NUMCORESACTIVE; ++i) {
454 BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
456 if(corestatus[i] != 0) {
460 } // for(i = 0; i < NUMCORESACTIVE; ++i)
462 // check if the sum of send objs and receive obj are the same
463 // yes->check if the info is the latest; no->go on executing
465 for(i = 0; i < NUMCORESACTIVE; ++i) {
466 sumsendobj += numsendobjs[i];
468 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
470 } // for(i = 0; i < NUMCORESACTIVE; ++i)
471 for(i = 0; i < NUMCORESACTIVE; ++i) {
472 sumsendobj -= numreceiveobjs[i];
474 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
476 } // for(i = 0; i < NUMCORESACTIVE; ++i)
477 if(0 == sumsendobj) {
479 // the first time found all cores stall
480 // send out status confirm msg to all other cores
481 // reset the corestatus array too
483 BAMBOO_DEBUGPRINT(0xee05);
485 corestatus[BAMBOO_NUM_OF_CORE] = 1;
487 numconfirm = NUMCORESACTIVE - 1;
488 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
489 for(i = 1; i < NUMCORESACTIVE; ++i) {
491 // send status confirm msg to core i
492 send_msg_1(i, STATUSCONFIRM, false);
493 } // for(i = 1; i < NUMCORESACTIVE; ++i)
496 // all the core status info are the latest
497 // terminate; for profiling mode, send request to all
498 // other cores to pour out profiling data
500 BAMBOO_DEBUGPRINT(0xee06);
504 totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
507 //BAMBOO_DEBUGPRINT_REG(interrupttime);
510 BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
511 //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
512 BAMBOO_DEBUGPRINT(0xbbbbbbbb);
514 // profile mode, send msgs to other cores to request pouring
515 // out progiling data
517 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
519 BAMBOO_DEBUGPRINT(0xf000);
521 for(i = 1; i < NUMCORESACTIVE; ++i) {
522 // send profile request msg to core i
523 send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
524 } // for(i = 1; i < NUMCORESACTIVE; ++i)
525 // pour profiling data on startup core
528 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
530 BAMBOO_DEBUGPRINT(0xf001);
532 profilestatus[BAMBOO_NUM_OF_CORE] = 0;
533 // check the status of all cores
536 BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
538 for(i = 0; i < NUMCORESACTIVE; ++i) {
540 BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
542 if(profilestatus[i] != 0) {
546 } // for(i = 0; i < NUMCORESACTIVE; ++i)
549 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
551 BAMBOO_DEBUGPRINT(0xf000);
556 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
562 // gc_profile mode, ourput gc prfiling data
565 gc_outputProfileData();
566 #endif // #ifdef GC_PROFILE
567 #endif // #ifdef MULTICORE_GC
569 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
570 terminate(); // All done.
571 } // if(!waitconfirm)
573 // still some objects on the fly on the network
574 // reset the waitconfirm and numconfirm
576 BAMBOO_DEBUGPRINT(0xee07);
580 } // if(0 == sumsendobj)
582 // not all cores are stall, keep on waiting
584 BAMBOO_DEBUGPRINT(0xee08);
589 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
591 BAMBOO_DEBUGPRINT(0xf000);
593 } // if((!waitconfirm) ||
596 // main function for each core
597 inline void run(void * arg) {
601 bool sendStall = false;
603 bool tocontinue = false;
605 corenum = BAMBOO_GET_NUM_OF_CORE();
607 BAMBOO_DEBUGPRINT(0xeeee);
608 BAMBOO_DEBUGPRINT_REG(corenum);
609 BAMBOO_DEBUGPRINT(STARTUPCORE);
612 // initialize runtime data structures
615 // other architecture related initialization
619 initializeexithandler();
621 // main process of the execution module
622 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
623 // non-executing cores, only processing communications
626 BAMBOO_DEBUGPRINT(0xee01);
627 BAMBOO_DEBUGPRINT_REG(taskInfoIndex);
628 BAMBOO_DEBUGPRINT_REG(taskInfoOverflow);
629 profileTaskStart("msg handling");
633 //isInterrupt = false;
637 /* Create queue of active tasks */
639 genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
640 (int (*)(void *,void *)) &comparetpd);
642 /* Process task information */
645 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
646 /* Create startup object */
647 createstartupobject(argc, argv);
651 BAMBOO_DEBUGPRINT(0xee00);
656 // check if need to do GC
660 // check if there are new active tasks can be executed
667 while(receiveObject() != -1) {
672 BAMBOO_DEBUGPRINT(0xee01);
675 // check if there are some pending objects,
676 // if yes, enqueue them and executetasks again
677 tocontinue = checkObjQueue();
681 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
684 BAMBOO_DEBUGPRINT(0xee03);
692 BAMBOO_DEBUGPRINT(0xee09);
698 // wait for some time
701 BAMBOO_DEBUGPRINT(0xee0a);
707 // send StallMsg to startup core
709 BAMBOO_DEBUGPRINT(0xee0b);
712 send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
713 self_numsendobjs, self_numreceiveobjs, false);
725 BAMBOO_DEBUGPRINT(0xee0c);
728 } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
731 } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
735 struct ___createstartupobject____I_locals {
738 struct ___StartupObject___ * ___startupobject___;
739 struct ArrayObject * ___stringarray___;
740 }; // struct ___createstartupobject____I_locals
742 void createstartupobject(int argc,
746 /* Allocate startup object */
748 struct ___createstartupobject____I_locals ___locals___={2, NULL, NULL, NULL};
749 struct ___StartupObject___ *startupobject=
750 (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
751 ___locals___.___startupobject___ = startupobject;
752 struct ArrayObject * stringarray=
753 allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
754 ___locals___.___stringarray___ = stringarray;
756 struct ___StartupObject___ *startupobject=
757 (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
758 struct ArrayObject * stringarray=
759 allocate_newarray(STRINGARRAYTYPE, argc-1);
761 /* Build array of strings */
762 startupobject->___parameters___=stringarray;
763 for(i=1; i<argc; i++) {
764 int length=strlen(argv[i]);
766 struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
768 struct ___String___ *newstring=NewString(argv[i],length);
770 ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
774 startupobject->version = 0;
775 startupobject->lock = NULL;
777 /* Set initialized flag for startup object */
778 flagorandinit(startupobject,1,0xFFFFFFFF);
779 enqueueObject(startupobject, NULL, 0);
781 BAMBOO_CACHE_FLUSH_ALL();
785 int hashCodetpd(struct taskparamdescriptor *ftd) {
786 int hash=(int)ftd->task;
788 for(i=0; i<ftd->numParameters; i++) {
789 hash^=(int)ftd->parameterArray[i];
794 int comparetpd(struct taskparamdescriptor *ftd1,
795 struct taskparamdescriptor *ftd2) {
797 if (ftd1->task!=ftd2->task)
799 for(i=0; i<ftd1->numParameters; i++)
800 if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
805 /* This function sets a tag. */
807 void tagset(void *ptr,
808 struct ___Object___ * obj,
809 struct ___TagDescriptor___ * tagd) {
811 void tagset(struct ___Object___ * obj,
812 struct ___TagDescriptor___ * tagd) {
814 struct ArrayObject * ao=NULL;
815 struct ___Object___ * tagptr=obj->___tags___;
817 obj->___tags___=(struct ___Object___ *)tagd;
819 /* Have to check if it is already set */
820 if (tagptr->type==TAGTYPE) {
821 struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
826 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
827 struct ArrayObject * ao=
828 allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
829 obj=(struct ___Object___ *)ptrarray[2];
830 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
831 td=(struct ___TagDescriptor___ *) obj->___tags___;
833 ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
836 ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
837 ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
838 obj->___tags___=(struct ___Object___ *) ao;
839 ao->___cachedCode___=2;
843 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
844 for(i=0; i<ao->___cachedCode___; i++) {
845 struct ___TagDescriptor___ * td=
846 ARRAYGET(ao, struct ___TagDescriptor___*, i);
851 if (ao->___cachedCode___<ao->___length___) {
852 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, tagd);
853 ao->___cachedCode___++;
856 int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
857 struct ArrayObject * aonew=
858 allocate_newarray(&ptrarray,TAGARRAYTYPE,
859 TAGARRAYINTERVAL+ao->___length___);
860 obj=(struct ___Object___ *)ptrarray[2];
861 tagd=(struct ___TagDescriptor___ *) ptrarray[3];
862 ao=(struct ArrayObject *)obj->___tags___;
864 struct ArrayObject * aonew=
865 allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
868 aonew->___cachedCode___=ao->___length___+1;
869 for(i=0; i<ao->___length___; i++) {
870 ARRAYSET(aonew, struct ___TagDescriptor___*, i,
871 ARRAYGET(ao, struct ___TagDescriptor___*, i));
873 ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___, tagd);
879 struct ___Object___ * tagset=tagd->flagptr;
882 } else if (tagset->type!=OBJECTARRAYTYPE) {
884 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
885 struct ArrayObject * ao=
886 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
887 obj=(struct ___Object___ *)ptrarray[2];
888 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
890 struct ArrayObject * ao=
891 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
893 ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
894 ARRAYSET(ao, struct ___Object___ *, 1, obj);
895 ao->___cachedCode___=2;
896 tagd->flagptr=(struct ___Object___ *)ao;
898 struct ArrayObject *ao=(struct ArrayObject *) tagset;
899 if (ao->___cachedCode___<ao->___length___) {
900 ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
904 int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
905 struct ArrayObject * aonew=
906 allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
907 OBJECTARRAYINTERVAL+ao->___length___);
908 obj=(struct ___Object___ *)ptrarray[2];
909 tagd=(struct ___TagDescriptor___ *)ptrarray[3];
910 ao=(struct ArrayObject *)tagd->flagptr;
912 struct ArrayObject * aonew=
913 allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL+ao->___length___);
915 aonew->___cachedCode___=ao->___cachedCode___+1;
916 for(i=0; i<ao->___length___; i++) {
917 ARRAYSET(aonew, struct ___Object___*, i,
918 ARRAYGET(ao, struct ___Object___*, i));
920 ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
921 tagd->flagptr=(struct ___Object___ *) aonew;
927 /* This function clears a tag. */
929 void tagclear(void *ptr,
930 struct ___Object___ * obj,
931 struct ___TagDescriptor___ * tagd) {
933 void tagclear(struct ___Object___ * obj,
934 struct ___TagDescriptor___ * tagd) {
936 /* We'll assume that tag is alway there.
937 Need to statically check for this of course. */
938 struct ___Object___ * tagptr=obj->___tags___;
940 if (tagptr->type==TAGTYPE) {
941 if ((struct ___TagDescriptor___ *)tagptr==tagd)
942 obj->___tags___=NULL;
944 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
946 for(i=0; i<ao->___cachedCode___; i++) {
947 struct ___TagDescriptor___ * td=
948 ARRAYGET(ao, struct ___TagDescriptor___ *, i);
950 ao->___cachedCode___--;
951 if (i<ao->___cachedCode___)
952 ARRAYSET(ao, struct ___TagDescriptor___ *, i,
953 ARRAYGET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___));
954 ARRAYSET(ao, struct ___TagDescriptor___ *, ao->___cachedCode___, NULL);
955 if (ao->___cachedCode___==0)
956 obj->___tags___=NULL;
963 struct ___Object___ *tagset=tagd->flagptr;
964 if (tagset->type!=OBJECTARRAYTYPE) {
968 struct ArrayObject *ao=(struct ArrayObject *) tagset;
970 for(i=0; i<ao->___cachedCode___; i++) {
971 struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
973 ao->___cachedCode___--;
974 if (i<ao->___cachedCode___)
975 ARRAYSET(ao, struct ___Object___ *, i,
976 ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
977 ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
978 if (ao->___cachedCode___==0)
989 /* This function allocates a new tag. */
991 struct ___TagDescriptor___ * allocate_tag(void *ptr,
993 struct ___TagDescriptor___ * v=
994 (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
997 struct ___TagDescriptor___ * allocate_tag(int index) {
998 struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
1007 /* This function updates the flag for object ptr. It or's the flag
1008 with the or mask and and's it with the andmask. */
1010 void flagbody(struct ___Object___ *ptr,
1012 struct parameterwrapper ** queues,
1016 int flagcomp(const int *val1, const int *val2) {
1017 return (*val1)-(*val2);
1020 void flagorand(void * ptr,
1023 struct parameterwrapper ** queues,
1026 int oldflag=((int *)ptr)[1];
1027 int flag=ormask|oldflag;
1029 flagbody(ptr, flag, queues, length, false);
1033 bool intflagorand(void * ptr,
1037 int oldflag=((int *)ptr)[1];
1038 int flag=ormask|oldflag;
1040 if (flag==oldflag) /* Don't do anything */
1043 flagbody(ptr, flag, NULL, 0, false);
1049 void flagorandinit(void * ptr,
1052 int oldflag=((int *)ptr)[1];
1053 int flag=ormask|oldflag;
1055 flagbody(ptr,flag,NULL,0,true);
1058 void flagbody(struct ___Object___ *ptr,
1060 struct parameterwrapper ** vqueues,
1063 struct parameterwrapper * flagptr = NULL;
1065 struct parameterwrapper ** queues = vqueues;
1066 int length = vlength;
1068 int UNUSED, UNUSED2;
1069 int * enterflags = NULL;
1070 if((!isnew) && (queues == NULL)) {
1071 if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
1072 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1073 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1080 /*Remove object from all queues */
1081 for(i = 0; i < length; ++i) {
1082 flagptr = queues[i];
1083 ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
1084 (int *) &enterflags, &UNUSED, &UNUSED2);
1085 ObjectHashremove(flagptr->objectset, (int)ptr);
1086 if (enterflags!=NULL)
1087 RUNFREE(enterflags);
1091 void enqueueObject(void * vptr,
1092 struct parameterwrapper ** vqueues,
1094 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1097 //struct QueueItem *tmpptr;
1098 struct parameterwrapper * parameter=NULL;
1101 struct parameterwrapper * prevptr=NULL;
1102 struct ___Object___ *tagptr=NULL;
1103 struct parameterwrapper ** queues = vqueues;
1104 int length = vlength;
1105 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1108 if(queues == NULL) {
1109 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1110 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1112 tagptr=ptr->___tags___;
1114 /* Outer loop iterates through all parameter queues an object of
1115 this type could be in. */
1116 for(j = 0; j < length; ++j) {
1117 parameter = queues[j];
1119 if (parameter->numbertags>0) {
1121 goto nextloop; //that means the object has no tag
1122 //but that param needs tag
1123 else if(tagptr->type==TAGTYPE) { //one tag
1124 //struct ___TagDescriptor___ * tag=
1125 //(struct ___TagDescriptor___*) tagptr;
1126 for(i=0; i<parameter->numbertags; i++) {
1127 //slotid is parameter->tagarray[2*i];
1128 int tagid=parameter->tagarray[2*i+1];
1129 if (tagid!=tagptr->flag)
1130 goto nextloop; /*We don't have this tag */
1132 } else { //multiple tags
1133 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1134 for(i=0; i<parameter->numbertags; i++) {
1135 //slotid is parameter->tagarray[2*i];
1136 int tagid=parameter->tagarray[2*i+1];
1138 for(j=0; j<ao->___cachedCode___; j++) {
1139 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1150 for(i=0; i<parameter->numberofterms; i++) {
1151 int andmask=parameter->intarray[i*2];
1152 int checkmask=parameter->intarray[i*2+1];
1153 if ((ptr->flag&andmask)==checkmask) {
1154 enqueuetasks(parameter, prevptr, ptr, NULL, 0);
1165 void enqueueObject_I(void * vptr,
1166 struct parameterwrapper ** vqueues,
1168 struct ___Object___ *ptr = (struct ___Object___ *)vptr;
1171 //struct QueueItem *tmpptr;
1172 struct parameterwrapper * parameter=NULL;
1175 struct parameterwrapper * prevptr=NULL;
1176 struct ___Object___ *tagptr=NULL;
1177 struct parameterwrapper ** queues = vqueues;
1178 int length = vlength;
1179 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1182 if(queues == NULL) {
1183 queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1184 length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
1186 tagptr=ptr->___tags___;
1188 /* Outer loop iterates through all parameter queues an object of
1189 this type could be in. */
1190 for(j = 0; j < length; ++j) {
1191 parameter = queues[j];
1193 if (parameter->numbertags>0) {
1195 goto nextloop; //that means the object has no tag
1196 //but that param needs tag
1197 else if(tagptr->type==TAGTYPE) { //one tag
1198 //struct ___TagDescriptor___ * tag=(struct ___TagDescriptor___*) tagptr;
1199 for(i=0; i<parameter->numbertags; i++) {
1200 //slotid is parameter->tagarray[2*i];
1201 int tagid=parameter->tagarray[2*i+1];
1202 if (tagid!=tagptr->flag)
1203 goto nextloop; /*We don't have this tag */
1205 } else { //multiple tags
1206 struct ArrayObject * ao=(struct ArrayObject *) tagptr;
1207 for(i=0; i<parameter->numbertags; i++) {
1208 //slotid is parameter->tagarray[2*i];
1209 int tagid=parameter->tagarray[2*i+1];
1211 for(j=0; j<ao->___cachedCode___; j++) {
1212 if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
1223 for(i=0; i<parameter->numberofterms; i++) {
1224 int andmask=parameter->intarray[i*2];
1225 int checkmask=parameter->intarray[i*2+1];
1226 if ((ptr->flag&andmask)==checkmask) {
1227 enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
1239 int * getAliasLock(void ** ptrs,
1241 struct RuntimeHash * tbl) {
1243 return (int*)(RUNMALLOC(sizeof(int)));
1248 bool redirect = false;
1249 int redirectlock = 0;
1250 for(; i < length; i++) {
1251 struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
1254 if(ptr->lock == NULL) {
1257 lock = (int)(ptr->lock);
1260 if(lock != redirectlock) {
1261 RuntimeHashadd(tbl, lock, redirectlock);
1264 if(RuntimeHashcontainskey(tbl, lock)) {
1265 // already redirected
1267 RuntimeHashget(tbl, lock, &redirectlock);
1268 for(; j < locklen; j++) {
1269 if(locks[j] != redirectlock) {
1270 RuntimeHashadd(tbl, locks[j], redirectlock);
1275 for(j = 0; j < locklen; j++) {
1276 if(locks[j] == lock) {
1279 } else if(locks[j] > lock) {
1286 locks[h] = locks[h-1];
1295 return (int *)redirectlock;
1297 return (int *)(locks[0]);
1302 void addAliasLock(void * ptr,
1304 struct ___Object___ * obj = (struct ___Object___ *)ptr;
1305 if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
1306 // originally no alias lock associated or have a different alias lock
1307 // flush it as the new one
1308 obj->lock = (int *)lock;
1313 inline void setTaskExitIndex(int index) {
1314 taskInfoArray[taskInfoIndex]->exitIndex = index;
1317 inline void addNewObjInfo(void * nobj) {
1318 if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
1319 taskInfoArray[taskInfoIndex]->newObjs = createQueue();
1321 addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
1326 // Only allocate local mem chunks to each core.
1327 // If a core has used up its local shared memory, start gc.
1328 void * localmalloc_I(int coren,
1334 int tofindb = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1335 int totest = tofindb;
1336 int bound = BAMBOO_SMEM_SIZE_L;
1340 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1341 int nsize = bamboo_smemtbl[totest];
1342 bool islocal = true;
1344 bool tocheck = true;
1345 // have some space in the block
1346 if(totest == tofindb) {
1347 // the first partition
1348 size = bound - nsize;
1349 } else if(nsize == 0) {
1350 // an empty partition, can be appended
1353 // not an empty partition, can not be appended
1354 // the last continuous block is not big enough, go to check the next
1358 } // if(totest == tofindb) else if(nsize == 0) else ...
1361 // have enough space in the block, malloc
1365 // no enough space yet, try to append next continuous block
1367 } // if(size > isize) else ...
1369 } // if(nsize < bound)
1371 // no space in the block, go to check the next block
1377 tofindb = totest = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
1380 } // if(islocal) else ...
1381 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1382 // no more local mem, do not find suitable block
1385 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1388 if(foundsmem == 1) {
1389 // find suitable block
1390 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1391 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1392 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1394 // set bamboo_smemtbl
1395 for(i = tofindb; i <= totest; i++) {
1396 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1398 } else if(foundsmem == 2) {
1399 // no suitable block
1404 } // void * localmalloc_I(int, int, int *)
1406 // Allocate the local shared memory to each core with the highest priority,
1407 // if a core has used up its local shared memory, try to allocate the
1408 // shared memory that belong to its neighbours, if also failed, start gc.
1409 void * fixedmalloc_I(int coren,
1416 //int core2test[5]={coren,-1,-1,-1,-1};//(x,y),(x-1,y),(x+1,y),(x,y-1),(x,y+1)
1417 int coords_x = bamboo_cpu2coords[coren*2];
1418 int coords_y = bamboo_cpu2coords[coren*2+1];
1420 /*if(coords_x != 0) {
1421 core2test[ii++] = bamboo_coords2cpu[coords_x-1][coords_y];
1424 core2test[ii++] = bamboo_coords2cpu[coords_x+1][coords_y];
1427 core2test[ii++] = bamboo_coords2cpu[coords_x][coords_y-1];
1430 core2test[ii++] = bamboo_coords2cpu[coords_x][coords_y+1];
1432 int tofindb = gc_core2block[2*core2test[coren][k]+i]+(NUMCORES4GC*2)*j;
1433 int totest = tofindb;
1434 int bound = BAMBOO_SMEM_SIZE_L;
1438 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1439 int nsize = bamboo_smemtbl[totest];
1440 bool islocal = true;
1442 bool tocheck = true;
1443 // have some space in the block
1444 if(totest == tofindb) {
1445 // the first partition
1446 size = bound - nsize;
1447 } else if(nsize == 0) {
1448 // an empty partition, can be appended
1451 // not an empty partition, can not be appended
1452 // the last continuous block is not big enough, go to check the next
1456 } // if(totest == tofindb) else if(nsize == 0) else ...
1459 // have enough space in the block, malloc
1463 // no enough space yet, try to append next continuous block
1464 // TODO may consider to go to next local block?
1466 } // if(size > isize) else ...
1468 } // if(nsize < bound)
1470 // no space in the block, go to check the next block
1476 tofindb=totest=gc_core2block[2*core2test[coren][k]+i]+(NUMCORES4GC*2)*j;
1479 } // if(islocal) else ...
1480 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1481 // no more local mem, do not find suitable block on local mem
1482 // try to malloc shared memory assigned to the neighbour cores
1486 // no more memory available on either coren or its neighbour cores
1488 goto memsearchresult;
1490 } while(core2test[coren][k] == -1);
1493 tofindb=totest=gc_core2block[2*core2test[coren][k]+i]+(NUMCORES4GC*2)*j;
1494 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1498 if(foundsmem == 1) {
1499 // find suitable block
1500 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1501 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1502 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1504 // set bamboo_smemtbl
1505 for(i = tofindb; i <= totest; i++) {
1506 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1508 } else if(foundsmem == 2) {
1509 // no suitable block
1514 } // void * fixedmalloc_I(int, int, int *)
1516 // Allocate all the memory chunks globally, do not consider the host cores
1517 // When all the shared memory are used up, start gc.
1518 void * globalmalloc_I(int coren,
1522 int tofindb = bamboo_free_block; //0;
1523 int totest = tofindb;
1524 int bound = BAMBOO_SMEM_SIZE_L;
1527 if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
1528 // Out of shared memory
1533 bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
1534 int nsize = bamboo_smemtbl[totest];
1535 bool isnext = false;
1537 bool tocheck = true;
1538 // have some space in the block
1539 if(totest == tofindb) {
1540 // the first partition
1541 size = bound - nsize;
1542 } else if(nsize == 0) {
1543 // an empty partition, can be appended
1546 // not an empty partition, can not be appended
1547 // the last continuous block is not big enough, start another block
1550 } // if(totest == tofindb) else if(nsize == 0) else ...
1553 // have enough space in the block, malloc
1556 } // if(size > isize)
1560 } // if(nsize < bound) else ...
1562 if(totest > gcnumblock-1-bamboo_reserved_smem) {
1563 // no more local mem, do not find suitable block
1566 } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
1568 // start another block
1573 if(foundsmem == 1) {
1574 // find suitable block
1575 mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
1576 (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
1577 (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
1579 // set bamboo_smemtbl
1580 for(int i = tofindb; i <= totest; i++) {
1581 bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
1583 if(tofindb == bamboo_free_block) {
1584 bamboo_free_block = totest+1;
1586 } else if(foundsmem == 2) {
1587 // no suitable block
1593 } // void * globalmalloc_I(int, int, int *)
1594 #endif // #ifdef MULTICORE_GC
1596 // malloc from the shared memory
1597 void * smemalloc_I(int coren,
1602 int isize = size+(BAMBOO_CACHE_LINE_SIZE);
1604 // go through the bamboo_smemtbl for suitable partitions
1605 switch(bamboo_smem_mode) {
1607 mem = localmalloc_I(coren, isize, allocsize);
1612 // TODO not supported yet
1613 //BAMBOO_EXIT(0xe001);
1614 mem = fixedmalloc_I(coren, isize, allocsize);
1619 // TODO not supported yet
1620 BAMBOO_EXIT(0xe002);
1625 mem = globalmalloc_I(coren, isize, allocsize);
1637 /*if(!interruptInfoOverflow) {
1638 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1639 interruptInfoArray[interruptInfoIndex] = intInfo;
1640 intInfo->startTime = BAMBOO_GET_EXE_TIME();
1641 intInfo->endTime = -1;
1644 int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
1645 //mem = mspace_calloc(bamboo_free_msp, 1, toallocate);
1646 if(toallocate > bamboo_free_smem_size) {
1650 mem = (void *)bamboo_free_smemp;
1651 bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
1652 bamboo_free_smem_size -= toallocate;
1653 //BAMBOO_MEMSET_WH(mem, '\0', toallocate);
1655 *allocsize = toallocate;
1657 /*if(!interruptInfoOverflow) {
1658 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1659 interruptInfoIndex++;
1660 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1661 interruptInfoOverflow = true;
1666 #endif // MULTICORE_GC
1667 // no enough shared global memory
1673 BAMBOO_DEBUGPRINT(0xa001);
1674 BAMBOO_EXIT(0xa001);
1678 } // void * smemalloc_I(int, int, int)
1680 INLINE int checkMsgLength_I(int size) {
1683 BAMBOO_DEBUGPRINT(0xcccc);
1686 int type = msgdata[msgdataindex];
1693 case GCSTARTMAPINFO:
1707 case GCSTARTCOMPACT:
1710 case GCFINISHMAPINFO:
1735 case REDIRECTGROUNT:
1737 case REDIRECTRELEASE:
1750 case GCFINISHCOMPACT:
1764 case TRANSOBJ: // nonfixed size
1770 msglength = msgdata[msgdataindex+1];
1779 BAMBOO_DEBUGPRINT_REG(type);
1780 BAMBOO_DEBUGPRINT_REG(size);
1781 BAMBOO_DEBUGPRINT_REG(msgdataindex);
1782 BAMBOO_DEBUGPRINT_REG(msgdatalast);
1783 BAMBOO_DEBUGPRINT_REG(msgdatafull);
1786 BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
1788 BAMBOO_EXIT(0xd005);
1794 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
1799 BAMBOO_DEBUGPRINT(0xffff);
1805 INLINE void processmsg_transobj_I() {
1807 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
1811 BAMBOO_DEBUGPRINT(0xe880);
1814 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1816 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
1818 BAMBOO_EXIT(0xa002);
1820 // store the object and its corresponding queue info, enqueue it later
1821 transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
1823 transObj->length = (msglength - 3) / 2;
1824 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
1825 for(k = 0; k < transObj->length; ++k) {
1826 transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
1830 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
1833 transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
1837 //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
1841 // check if there is an existing duplicate item
1843 struct QueueItem * qitem = getHead(&objqueue);
1844 struct QueueItem * prev = NULL;
1845 while(qitem != NULL) {
1846 struct transObjInfo * tmpinfo =
1847 (struct transObjInfo *)(qitem->objectptr);
1848 if(tmpinfo->objptr == transObj->objptr) {
1849 // the same object, remove outdate one
1850 RUNFREE(tmpinfo->queues);
1852 removeItem(&objqueue, qitem);
1858 qitem = getHead(&objqueue);
1860 qitem = getNextQueueItem(prev);
1863 addNewItem_I(&objqueue, (void *)transObj);
1865 ++(self_numreceiveobjs);
1868 INLINE void processmsg_transtall_I() {
1869 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1870 // non startup core can not receive stall msg
1872 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
1874 BAMBOO_EXIT(0xa003);
1876 int num_core = msgdata[msgdataindex]; //[1]
1878 if(num_core < NUMCORESACTIVE) {
1881 BAMBOO_DEBUGPRINT(0xe881);
1884 corestatus[num_core] = 0;
1885 numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
1887 numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
1892 #ifndef MULTICORE_GC
1893 INLINE void processmsg_lockrequest_I() {
1894 // check to see if there is a lock exist for the required obj
1895 // msgdata[1] -> lock type
1896 int locktype = msgdata[msgdataindex]; //[1];
1898 int data2 = msgdata[msgdataindex]; // obj pointer
1900 int data3 = msgdata[msgdataindex]; // lock
1902 int data4 = msgdata[msgdataindex]; // request core
1904 // -1: redirected, 0: approved, 1: denied
1905 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
1907 // this lock request is redirected
1910 // send response msg
1911 // for 32 bit machine, the size is always 4 words, cache the msg first
1912 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
1913 if(BAMBOO_CHECK_SEND_MODE()) {
1914 cache_msg_4(data4, tmp, locktype, data2, data3);
1916 send_msg_4(data4, tmp, locktype, data2, data3, true);
1921 INLINE void processmsg_lockgrount_I() {
1923 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1925 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
1927 BAMBOO_EXIT(0xa004);
1929 int data2 = msgdata[msgdataindex];
1931 int data3 = msgdata[msgdataindex];
1933 if((lockobj == data2) && (lock2require == data3)) {
1936 BAMBOO_DEBUGPRINT(0xe882);
1945 // conflicts on lockresults
1947 BAMBOO_DEBUGPRINT_REG(data2);
1949 BAMBOO_EXIT(0xa005);
1953 INLINE void processmsg_lockdeny_I() {
1955 int data2 = msgdata[msgdataindex];
1957 int data3 = msgdata[msgdataindex];
1959 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
1961 BAMBOO_DEBUGPRINT_REG(data2);
1963 BAMBOO_EXIT(0xa006);
1965 if((lockobj == data2) && (lock2require == data3)) {
1968 BAMBOO_DEBUGPRINT(0xe883);
1977 // conflicts on lockresults
1979 BAMBOO_DEBUGPRINT_REG(data2);
1981 BAMBOO_EXIT(0xa007);
1985 INLINE void processmsg_lockrelease_I() {
1986 int data1 = msgdata[msgdataindex];
1988 int data2 = msgdata[msgdataindex];
1990 // receive lock release msg
1991 processlockrelease(data1, data2, 0, false);
1994 INLINE void processmsg_redirectlock_I() {
1995 // check to see if there is a lock exist for the required obj
1996 int data1 = msgdata[msgdataindex];
1997 MSG_INDEXINC_I(); //msgdata[1]; // lock type
1998 int data2 = msgdata[msgdataindex];
1999 MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
2000 int data3 = msgdata[msgdataindex];
2001 MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
2002 int data4 = msgdata[msgdataindex];
2003 MSG_INDEXINC_I(); //msgdata[4]; // root request core
2004 int data5 = msgdata[msgdataindex];
2005 MSG_INDEXINC_I(); //msgdata[5]; // request core
2006 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
2008 // this lock request is redirected
2011 // send response msg
2012 // for 32 bit machine, the size is always 4 words, cache the msg first
2013 if(BAMBOO_CHECK_SEND_MODE()) {
2014 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
2015 data1, data2, data3);
2017 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
2018 data1, data2, data3, true);
2023 INLINE void processmsg_redirectgrount_I() {
2025 int data2 = msgdata[msgdataindex];
2027 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2029 BAMBOO_DEBUGPRINT_REG(data2);
2031 BAMBOO_EXIT(0xa00a);
2033 if(lockobj == data2) {
2036 BAMBOO_DEBUGPRINT(0xe891);
2039 int data3 = msgdata[msgdataindex];
2043 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
2048 // conflicts on lockresults
2050 BAMBOO_DEBUGPRINT_REG(data2);
2052 BAMBOO_EXIT(0xa00b);
2056 INLINE void processmsg_redirectdeny_I() {
2058 int data2 = msgdata[msgdataindex];
2060 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
2062 BAMBOO_DEBUGPRINT_REG(data2);
2064 BAMBOO_EXIT(0xa00c);
2066 if(lockobj == data2) {
2069 BAMBOO_DEBUGPRINT(0xe892);
2078 // conflicts on lockresults
2080 BAMBOO_DEBUGPRINT_REG(data2);
2082 BAMBOO_EXIT(0xa00d);
2086 INLINE void processmsg_redirectrelease_I() {
2087 int data1 = msgdata[msgdataindex];
2089 int data2 = msgdata[msgdataindex];
2091 int data3 = msgdata[msgdataindex];
2093 processlockrelease(data1, data2, data3, true);
2095 #endif // #ifndef MULTICORE_GC
2098 INLINE void processmsg_profileoutput_I() {
2099 if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
2100 // startup core can not receive profile output finish msg
2101 BAMBOO_EXIT(0xa008);
2105 BAMBOO_DEBUGPRINT(0xe885);
2109 totalexetime = msgdata[msgdataindex]; //[1]
2111 outputProfileData();
2112 // cache the msg first
2113 if(BAMBOO_CHECK_SEND_MODE()) {
2114 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
2116 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
2120 INLINE void processmsg_profilefinish_I() {
2121 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2122 // non startup core can not receive profile output finish msg
2124 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
2126 BAMBOO_EXIT(0xa009);
2130 BAMBOO_DEBUGPRINT(0xe886);
2133 int data1 = msgdata[msgdataindex];
2135 profilestatus[data1] = 0;
2137 #endif // #ifdef PROFILE
2139 INLINE void processmsg_statusconfirm_I() {
2140 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2141 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2142 // wrong core to receive such msg
2143 BAMBOO_EXIT(0xa00e);
2145 // send response msg
2148 BAMBOO_DEBUGPRINT(0xe887);
2151 // cache the msg first
2152 if(BAMBOO_CHECK_SEND_MODE()) {
2153 cache_msg_5(STARTUPCORE, STATUSREPORT,
2154 busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
2155 self_numsendobjs, self_numreceiveobjs);
2157 send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
2158 BAMBOO_NUM_OF_CORE, self_numsendobjs,
2159 self_numreceiveobjs, true);
2164 INLINE void processmsg_statusreport_I() {
2165 int data1 = msgdata[msgdataindex];
2167 int data2 = msgdata[msgdataindex];
2169 int data3 = msgdata[msgdataindex];
2171 int data4 = msgdata[msgdataindex];
2173 // receive a status confirm info
2174 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2175 // wrong core to receive such msg
2177 BAMBOO_DEBUGPRINT_REG(data2);
2179 BAMBOO_EXIT(0xa00f);
2183 BAMBOO_DEBUGPRINT(0xe888);
2189 corestatus[data2] = data1;
2190 numsendobjs[data2] = data3;
2191 numreceiveobjs[data2] = data4;
2195 INLINE void processmsg_terminate_I() {
2198 BAMBOO_DEBUGPRINT(0xe889);
2205 INLINE void processmsg_memrequest_I() {
2207 if(!interruptInfoOverflow) {
2208 InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
2209 interruptInfoArray[interruptInfoIndex] = intInfo;
2210 intInfo->startTime = BAMBOO_GET_EXE_TIME();
2211 intInfo->endTime = -1;
2214 int data1 = msgdata[msgdataindex];
2216 int data2 = msgdata[msgdataindex];
2218 // receive a shared memory request msg
2219 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2220 // wrong core to receive such msg
2222 BAMBOO_DEBUGPRINT_REG(data2);
2224 BAMBOO_EXIT(0xa010);
2228 BAMBOO_DEBUGPRINT(0xe88a);
2235 // is currently doing gc, dump this msg
2236 if(INITPHASE == gcphase) {
2237 // if still in the initphase of gc, send a startinit msg again,
2238 // cache the msg first
2239 if(BAMBOO_CHECK_SEND_MODE()) {
2240 cache_msg_1(data2, GCSTARTINIT);
2242 send_msg_1(data2, GCSTARTINIT, true);
2247 mem = smemalloc_I(data2, data1, &allocsize);
2249 // send the start_va to request core, cache the msg first
2250 if(BAMBOO_CHECK_SEND_MODE()) {
2251 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
2253 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
2255 } // if mem == NULL, the gcflag of the startup core has been set
2256 // and the gc should be started later, then a GCSTARTINIT msg
2257 // will be sent to the requesting core to notice it to start gc
2258 // and try malloc again
2264 if(!interruptInfoOverflow) {
2265 interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
2266 interruptInfoIndex++;
2267 if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
2268 interruptInfoOverflow = true;
2274 INLINE void processmsg_memresponse_I() {
2275 int data1 = msgdata[msgdataindex];
2277 int data2 = msgdata[msgdataindex];
2279 // receive a shared memory response msg
2282 BAMBOO_DEBUGPRINT(0xe88b);
2286 // if is currently doing gc, dump this msg
2290 bamboo_smem_size = 0;
2294 // fill header to store the size of this mem block
2295 BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
2296 //memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
2297 (*((int*)data1)) = data2;
2298 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
2299 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
2301 bamboo_smem_size = data2;
2302 bamboo_cur_msp =(void*)(data1);
2312 INLINE void processmsg_gcstartinit_I() {
2314 gcphase = INITPHASE;
2316 // is waiting for response of mem request
2317 // let it return NULL and start gc
2318 bamboo_smem_size = 0;
2319 bamboo_cur_msp = NULL;
2324 INLINE void processmsg_gcstart_I() {
2327 BAMBOO_DEBUGPRINT(0xe88c);
2331 gcphase = MARKPHASE;
2334 INLINE void processmsg_gcstartcompact_I() {
2335 gcblock2fill = msgdata[msgdataindex];
2336 MSG_INDEXINC_I(); //msgdata[1];
2337 gcphase = COMPACTPHASE;
2340 INLINE void processmsg_gcstartmapinfo_I() {
2344 INLINE void processmsg_gcstartflush_I() {
2345 gcphase = FLUSHPHASE;
2348 INLINE void processmsg_gcfinishinit_I() {
2349 int data1 = msgdata[msgdataindex];
2351 // received a init phase finish msg
2352 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2353 // non startup core can not receive this msg
2355 BAMBOO_DEBUGPRINT_REG(data1);
2357 BAMBOO_EXIT(0xb001);
2360 BAMBOO_DEBUGPRINT(0xe88c);
2361 BAMBOO_DEBUGPRINT_REG(data1);
2363 // All cores should do init GC
2364 if(data1 < NUMCORESACTIVE) {
2365 gccorestatus[data1] = 0;
2369 INLINE void processmsg_gcfinishmark_I() {
2370 int data1 = msgdata[msgdataindex];
2372 int data2 = msgdata[msgdataindex];
2374 int data3 = msgdata[msgdataindex];
2376 // received a mark phase finish msg
2377 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2378 // non startup core can not receive this msg
2380 BAMBOO_DEBUGPRINT_REG(data1);
2382 BAMBOO_EXIT(0xb002);
2384 // all cores should do mark
2385 if(data1 < NUMCORESACTIVE) {
2386 gccorestatus[data1] = 0;
2387 gcnumsendobjs[data1] = data2;
2388 gcnumreceiveobjs[data1] = data3;
2392 INLINE void processmsg_gcfinishcompact_I() {
2393 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2394 // non startup core can not receive this msg
2397 BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
2399 BAMBOO_EXIT(0xb003);
2401 int cnum = msgdata[msgdataindex];
2402 MSG_INDEXINC_I(); //msgdata[1];
2403 int filledblocks = msgdata[msgdataindex];
2404 MSG_INDEXINC_I(); //msgdata[2];
2405 int heaptop = msgdata[msgdataindex];
2406 MSG_INDEXINC_I(); //msgdata[3];
2407 int data4 = msgdata[msgdataindex];
2408 MSG_INDEXINC_I(); //msgdata[4];
2409 // only gc cores need to do compact
2410 if(cnum < NUMCORES4GC) {
2411 if(COMPACTPHASE == gcphase) {
2412 gcfilledblocks[cnum] = filledblocks;
2413 gcloads[cnum] = heaptop;
2420 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
2421 // cache the msg first
2422 if(BAMBOO_CHECK_SEND_MODE()) {
2423 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
2425 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
2429 gccorestatus[cnum] = 0;
2431 } // if(cnum < NUMCORES4GC)
2434 INLINE void processmsg_gcfinishmapinfo_I() {
2435 int data1 = msgdata[msgdataindex];
2437 // received a map phase finish msg
2438 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2439 // non startup core can not receive this msg
2442 BAMBOO_DEBUGPRINT_REG(data1);
2444 BAMBOO_EXIT(0xb004);
2446 // all cores should do flush
2447 if(data1 < NUMCORES4GC) {
2448 gccorestatus[data1] = 0;
2453 INLINE void processmsg_gcfinishflush_I() {
2454 int data1 = msgdata[msgdataindex];
2456 // received a flush phase finish msg
2457 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2458 // non startup core can not receive this msg
2461 BAMBOO_DEBUGPRINT_REG(data1);
2463 BAMBOO_EXIT(0xb005);
2465 // all cores should do flush
2466 if(data1 < NUMCORESACTIVE) {
2467 gccorestatus[data1] = 0;
2471 INLINE void processmsg_gcmarkconfirm_I() {
2472 if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
2473 || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
2474 // wrong core to receive such msg
2475 BAMBOO_EXIT(0xb006);
2477 // send response msg, cahce the msg first
2478 if(BAMBOO_CHECK_SEND_MODE()) {
2479 cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2480 gcbusystatus, gcself_numsendobjs,
2481 gcself_numreceiveobjs);
2483 send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
2484 gcbusystatus, gcself_numsendobjs,
2485 gcself_numreceiveobjs, true);
2490 INLINE void processmsg_gcmarkreport_I() {
2491 int data1 = msgdata[msgdataindex];
2493 int data2 = msgdata[msgdataindex];
2495 int data3 = msgdata[msgdataindex];
2497 int data4 = msgdata[msgdataindex];
2499 // received a marked phase finish confirm response msg
2500 if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
2501 // wrong core to receive such msg
2503 BAMBOO_DEBUGPRINT_REG(data2);
2505 BAMBOO_EXIT(0xb007);
2510 gccorestatus[data1] = data2;
2511 gcnumsendobjs[data1] = data3;
2512 gcnumreceiveobjs[data1] = data4;
2516 INLINE void processmsg_gcmarkedobj_I() {
2517 int data1 = msgdata[msgdataindex];
2519 // received a markedObj msg
2520 if(((int *)data1)[6] == INIT) {
2521 // this is the first time that this object is discovered,
2522 // set the flag as DISCOVERED
2523 ((int *)data1)[6] = DISCOVERED;
2524 gc_enqueue_I(data1);
2526 // set the remote flag
2527 ((int *)data1)[6] |= REMOTEM;
2528 gcself_numreceiveobjs++;
2529 gcbusystatus = true;
2532 INLINE void processmsg_gcmovestart_I() {
2534 gcdstcore = msgdata[msgdataindex];
2535 MSG_INDEXINC_I(); //msgdata[1];
2536 gcmovestartaddr = msgdata[msgdataindex];
2537 MSG_INDEXINC_I(); //msgdata[2];
2538 gcblock2fill = msgdata[msgdataindex];
2539 MSG_INDEXINC_I(); //msgdata[3];
2542 INLINE void processmsg_gcmaprequest_I() {
2544 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2546 void * dstptr = NULL;
2547 int data1 = msgdata[msgdataindex];
2549 //dstptr = mgchashSearch(msgdata[1]);
2551 // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2553 RuntimeHashget(gcpointertbl, data1, &dstptr);
2555 // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2557 int data2 = msgdata[msgdataindex];
2559 //MGCHashget(gcpointertbl, msgdata[1], &dstptr);
2561 // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
2563 if(NULL == dstptr) {
2564 // no such pointer in this core, something is wrong
2566 BAMBOO_DEBUGPRINT_REG(data1);
2567 BAMBOO_DEBUGPRINT_REG(data2);
2569 BAMBOO_EXIT(0xb009);
2570 //assume that the object was not moved, use the original address
2571 /*if(isMsgSending) {
2572 cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2574 send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
2577 // send back the mapping info, cache the msg first
2578 if(BAMBOO_CHECK_SEND_MODE()) {
2579 cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
2581 send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
2585 // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
2586 //num_mapinforequest_i++;
2590 INLINE void processmsg_gcmapinfo_I() {
2592 //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
2594 int data1 = msgdata[msgdataindex];
2597 if(data1 != gcobj2map) {
2598 // obj not matched, something is wrong
2600 BAMBOO_DEBUGPRINT_REG(gcobj2map);
2601 BAMBOO_DEBUGPRINT_REG(msgdata[1]);
2603 BAMBOO_EXIT(0xb00a);
2606 gcmappedobj = msgdata[msgdataindex]; // [2]
2608 //mgchashReplace_I(msgdata[1], msgdata[2]);
2609 //mgchashInsert_I(gcobj2map, gcmappedobj);
2610 RuntimeHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2611 /*struct nodemappinginfo * nodeinfo =
2612 (struct nodemappinginfo *)RUNMALLOC_I(sizeof(struct nodemappinginfo));
2613 nodeinfo->ptr = (void *)gcmappedobj;
2614 nodeinfo->cores = NULL;
2615 RuntimeHashadd_I(gcpointertbl, data1, (int)nodeinfo);*/
2616 //MGCHashadd_I(gcpointertbl, gcobj2map, gcmappedobj);
2618 if(data1 == gcobj2map) {
2622 //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
2626 INLINE void processmsg_gcmaptbl_I() {
2627 int data1 = msgdata[msgdataindex];
2629 int data2 = msgdata[msgdataindex];
2631 gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
2634 INLINE void processmsg_gclobjinfo_I() {
2637 int data1 = msgdata[msgdataindex];
2639 int data2 = msgdata[msgdataindex];
2641 if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
2643 BAMBOO_DEBUGPRINT_REG(data2);
2645 BAMBOO_EXIT(0xb00b);
2647 // store the mark result info
2649 gcloads[cnum] = msgdata[msgdataindex];
2650 MSG_INDEXINC_I(); // msgdata[3];
2651 int data4 = msgdata[msgdataindex];
2653 if(gcheaptop < data4) {
2656 // large obj info here
2657 for(int k = 5; k < data1; ) {
2658 int lobj = msgdata[msgdataindex];
2659 MSG_INDEXINC_I(); //msgdata[k++];
2660 int length = msgdata[msgdataindex];
2661 MSG_INDEXINC_I(); //msgdata[k++];
2662 gc_lobjenqueue_I(lobj, length, cnum);
2664 } // for(int k = 5; k < msgdata[1];)
2667 INLINE void processmsg_gclobjmapping_I() {
2668 int data1 = msgdata[msgdataindex];
2670 int data2 = msgdata[msgdataindex];
2672 //mgchashInsert_I(msgdata[1], msgdata[2]);
2673 RuntimeHashadd_I(gcpointertbl, data1, data2);
2674 mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
2675 //GCSharedHashadd_I(gcsharedptbl, data1, data2);
2676 //MGCHashadd_I(gcpointertbl, msgdata[1], msgdata[2]);
2678 #endif // #ifdef MULTICORE_GC
2680 // receive object transferred from other cores
2681 // or the terminate message from other cores
2682 // Should be invoked in critical sections!!
2683 // NOTICE: following format is for threadsimulate version only
2684 // RAW version please see previous description
2685 // format: type + object
2686 // type: -1--stall msg
2688 // return value: 0--received an object
2689 // 1--received nothing
2690 // 2--received a Stall Msg
2691 // 3--received a lock Msg
2692 // RAW version: -1 -- received nothing
2693 // otherwise -- received msg type
2694 int receiveObject(int send_port_pending) {
2696 // get the incoming msgs
2697 if(receiveMsg(send_port_pending) == -1) {
2701 // processing received msgs
2703 MSG_REMAINSIZE_I(&size);
2704 if((size == 0) || (checkMsgLength_I(size) == -1)) {
2706 // have new coming msg
2707 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
2714 if(msglength <= size) {
2715 // have some whole msg
2716 //if(msgdataindex == msglength) {
2717 // received a whole msg
2719 type = msgdata[msgdataindex]; //[0]
2721 msgdatafull = false;
2723 //tprintf("msg type: %x\n", type);
2726 // receive a object transfer msg
2727 processmsg_transobj_I();
2732 // receive a stall msg
2733 processmsg_transtall_I();
2737 // GC version have no lock msgs
2738 #ifndef MULTICORE_GC
2740 // receive lock request msg, handle it right now
2741 processmsg_lockrequest_I();
2743 } // case LOCKREQUEST
2746 // receive lock grount msg
2747 processmsg_lockgrount_I();
2749 } // case LOCKGROUNT
2752 // receive lock deny msg
2753 processmsg_lockdeny_I();
2758 processmsg_lockrelease_I();
2760 } // case LOCKRELEASE
2761 #endif // #ifndef MULTICORE_GC
2764 case PROFILEOUTPUT: {
2765 // receive an output profile data request msg
2766 processmsg_profileoutput_I();
2768 } // case PROFILEOUTPUT
2770 case PROFILEFINISH: {
2771 // receive a profile output finish msg
2772 processmsg_profilefinish_I();
2774 } // case PROFILEFINISH
2775 #endif // #ifdef PROFILE
2777 // GC version has no lock msgs
2778 #ifndef MULTICORE_GC
2779 case REDIRECTLOCK: {
2780 // receive a redirect lock request msg, handle it right now
2781 processmsg_redirectlock_I();
2783 } // case REDIRECTLOCK
2785 case REDIRECTGROUNT: {
2786 // receive a lock grant msg with redirect info
2787 processmsg_redirectgrount_I();
2789 } // case REDIRECTGROUNT
2791 case REDIRECTDENY: {
2792 // receive a lock deny msg with redirect info
2793 processmsg_redirectdeny_I();
2795 } // case REDIRECTDENY
2797 case REDIRECTRELEASE: {
2798 // receive a lock release msg with redirect info
2799 processmsg_redirectrelease_I();
2801 } // case REDIRECTRELEASE
2802 #endif // #ifndef MULTICORE_GC
2804 case STATUSCONFIRM: {
2805 // receive a status confirm info
2806 processmsg_statusconfirm_I();
2808 } // case STATUSCONFIRM
2810 case STATUSREPORT: {
2811 processmsg_statusreport_I();
2813 } // case STATUSREPORT
2816 // receive a terminate msg
2817 processmsg_terminate_I();
2822 processmsg_memrequest_I();
2824 } // case MEMREQUEST
2827 processmsg_memresponse_I();
2829 } // case MEMRESPONSE
2834 processmsg_gcstartinit_I();
2836 } // case GCSTARTINIT
2839 // receive a start GC msg
2840 processmsg_gcstart_I();
2844 case GCSTARTCOMPACT: {
2845 // a compact phase start msg
2846 processmsg_gcstartcompact_I();
2848 } // case GCSTARTCOMPACT
2850 case GCSTARTMAPINFO: {
2851 // received a flush phase start msg
2852 processmsg_gcstartmapinfo_I();
2854 } // case GCSTARTFLUSH
2856 case GCSTARTFLUSH: {
2857 // received a flush phase start msg
2858 processmsg_gcstartflush_I();
2860 } // case GCSTARTFLUSH
2862 case GCFINISHINIT: {
2863 processmsg_gcfinishinit_I();
2865 } // case GCFINISHINIT
2867 case GCFINISHMARK: {
2868 processmsg_gcfinishmark_I();
2870 } // case GCFINISHMARK
2872 case GCFINISHCOMPACT: {
2873 // received a compact phase finish msg
2874 processmsg_gcfinishcompact_I();
2876 } // case GCFINISHCOMPACT
2878 case GCFINISHMAPINFO: {
2879 processmsg_gcfinishmapinfo_I();
2881 } // case GCFINISHMAPINFO
2883 case GCFINISHFLUSH: {
2884 processmsg_gcfinishflush_I();
2886 } // case GCFINISHFLUSH
2889 // received a GC finish msg
2890 gcphase = FINISHPHASE;
2894 case GCMARKCONFIRM: {
2895 // received a marked phase finish confirm request msg
2896 // all cores should do mark
2897 processmsg_gcmarkconfirm_I();
2899 } // case GCMARKCONFIRM
2901 case GCMARKREPORT: {
2902 processmsg_gcmarkreport_I();
2904 } // case GCMARKREPORT
2907 processmsg_gcmarkedobj_I();
2909 } // case GCMARKEDOBJ
2912 // received a start moving objs msg
2913 processmsg_gcmovestart_I();
2915 } // case GCMOVESTART
2917 case GCMAPREQUEST: {
2918 // received a mapping info request msg
2919 processmsg_gcmaprequest_I();
2921 } // case GCMAPREQUEST
2924 // received a mapping info response msg
2925 processmsg_gcmapinfo_I();
2930 // received a mapping tbl response msg
2931 processmsg_gcmaptbl_I();
2935 case GCLOBJREQUEST: {
2936 // received a large objs info request msg
2937 transferMarkResults_I();
2939 } // case GCLOBJREQUEST
2942 // received a large objs info response msg
2943 processmsg_gclobjinfo_I();
2945 } // case GCLOBJINFO
2947 case GCLOBJMAPPING: {
2948 // received a large obj mapping info msg
2949 processmsg_gclobjmapping_I();
2951 } // case GCLOBJMAPPING
2953 #endif // #ifdef MULTICORE_GC
2958 //memset(msgdata, '\0', sizeof(int) * msgdataindex);
2960 msglength = BAMBOO_MSG_BUF_LENGTH;
2962 //printf("++ msg: %x \n", type);
2964 if(msgdataindex != msgdatalast) {
2965 // still have available msg
2970 BAMBOO_DEBUGPRINT(0xe88d);
2974 // have new coming msg
2975 if(BAMBOO_MSG_AVAIL() != 0) {
2989 BAMBOO_DEBUGPRINT(0xe88e);
2993 /* if(isInterrupt) {
3001 int enqueuetasks(struct parameterwrapper *parameter,
3002 struct parameterwrapper *prevptr,
3003 struct ___Object___ *ptr,
3005 int numenterflags) {
3006 void * taskpointerarray[MAXTASKPARAMS];
3008 //int numparams=parameter->task->numParameters;
3009 int numiterators=parameter->task->numTotal-1;
3012 struct taskdescriptor * task=parameter->task;
3014 //this add the object to parameterwrapper
3015 ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
3016 numenterflags, enterflags==NULL);
3018 /* Add enqueued object to parameter vector */
3019 taskpointerarray[parameter->slot]=ptr;
3021 /* Reset iterators */
3022 for(j=0; j<numiterators; j++) {
3023 toiReset(¶meter->iterators[j]);
3026 /* Find initial state */
3027 for(j=0; j<numiterators; j++) {
3029 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3030 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3032 /* Need to backtrack */
3033 toiReset(¶meter->iterators[j]);
3037 /* Nothing to enqueue */
3043 /* Enqueue current state */
3045 struct taskparamdescriptor *tpd=
3046 RUNMALLOC(sizeof(struct taskparamdescriptor));
3048 tpd->numParameters=numiterators+1;
3049 tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
3051 for(j=0; j<=numiterators; j++) {
3052 //store the actual parameters
3053 tpd->parameterArray[j]=taskpointerarray[j];
3056 if (( /*!gencontains(failedtasks, tpd)&&*/
3057 !gencontains(activetasks,tpd))) {
3058 genputtable(activetasks, tpd, tpd);
3060 RUNFREE(tpd->parameterArray);
3064 /* This loop iterates to the next parameter combination */
3065 if (numiterators==0)
3068 for(j=numiterators-1; j<numiterators; j++) {
3070 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3071 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3073 /* Need to backtrack */
3074 toiReset(¶meter->iterators[j]);
3078 /* Nothing more to enqueue */
3086 int enqueuetasks_I(struct parameterwrapper *parameter,
3087 struct parameterwrapper *prevptr,
3088 struct ___Object___ *ptr,
3090 int numenterflags) {
3091 void * taskpointerarray[MAXTASKPARAMS];
3093 //int numparams=parameter->task->numParameters;
3094 int numiterators=parameter->task->numTotal-1;
3099 struct taskdescriptor * task=parameter->task;
3101 //this add the object to parameterwrapper
3102 ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
3103 numenterflags, enterflags==NULL);
3105 /* Add enqueued object to parameter vector */
3106 taskpointerarray[parameter->slot]=ptr;
3108 /* Reset iterators */
3109 for(j=0; j<numiterators; j++) {
3110 toiReset(¶meter->iterators[j]);
3113 /* Find initial state */
3114 for(j=0; j<numiterators; j++) {
3116 if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
3117 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3119 /* Need to backtrack */
3120 toiReset(¶meter->iterators[j]);
3124 /* Nothing to enqueue */
3130 /* Enqueue current state */
3132 struct taskparamdescriptor *tpd=
3133 RUNMALLOC_I(sizeof(struct taskparamdescriptor));
3135 tpd->numParameters=numiterators+1;
3136 tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
3138 for(j=0; j<=numiterators; j++) {
3139 //store the actual parameters
3140 tpd->parameterArray[j]=taskpointerarray[j];
3143 if (( /*!gencontains(failedtasks, tpd)&&*/
3144 !gencontains(activetasks,tpd))) {
3145 genputtable_I(activetasks, tpd, tpd);
3147 RUNFREE(tpd->parameterArray);
3151 /* This loop iterates to the next parameter combination */
3152 if (numiterators==0)
3155 for(j=numiterators-1; j<numiterators; j++) {
3157 if(toiHasNext(¶meter->iterators[j], taskpointerarray OPTARG(failed)))
3158 toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
3160 /* Need to backtrack */
3161 toiReset(¶meter->iterators[j]);
3165 /* Nothing more to enqueue */
3179 int containstag(struct ___Object___ *ptr,
3180 struct ___TagDescriptor___ *tag);
3182 #ifndef MULTICORE_GC
3183 void releasewritelock_r(void * lock, void * redirectlock) {
3185 int reallock = (int)lock;
3186 targetcore = (reallock >> 5) % NUMCORES;
3189 BAMBOO_DEBUGPRINT(0xe671);
3190 BAMBOO_DEBUGPRINT_REG((int)lock);
3191 BAMBOO_DEBUGPRINT_REG(reallock);
3192 BAMBOO_DEBUGPRINT_REG(targetcore);
3195 if(targetcore == BAMBOO_NUM_OF_CORE) {
3196 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3198 BAMBOO_DEBUGPRINT(0xf001);
3200 // reside on this core
3201 if(!RuntimeHashcontainskey(locktbl, reallock)) {
3202 // no locks for this object, something is wrong
3203 BAMBOO_EXIT(0xa00b);
3206 struct LockValue * lockvalue = NULL;
3208 BAMBOO_DEBUGPRINT(0xe672);
3210 RuntimeHashget(locktbl, reallock, &rwlock_obj);
3211 lockvalue = (struct LockValue *)rwlock_obj;
3213 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3216 lockvalue->redirectlock = (int)redirectlock;
3218 BAMBOO_DEBUGPRINT_REG(lockvalue->value);
3221 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3223 BAMBOO_DEBUGPRINT(0xf000);
3227 // send lock release with redirect info msg
3228 // for 32 bit machine, the size is always 4 words
3229 send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
3230 (int)redirectlock, false);
3235 void executetasks() {
3236 void * taskpointerarray[MAXTASKPARAMS+OFFSET];
3239 struct ___Object___ * tmpparam = NULL;
3240 struct parameterdescriptor * pd=NULL;
3241 struct parameterwrapper *pw=NULL;
3251 while(hashsize(activetasks)>0) {
3256 BAMBOO_DEBUGPRINT(0xe990);
3259 /* See if there are any active tasks */
3260 //if (hashsize(activetasks)>0) {
3263 #ifdef ACCURATEPROFILE
3264 profileTaskStart("tpd checking");
3268 //clock1 = BAMBOO_GET_EXE_TIME();
3271 currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
3272 genfreekey(activetasks, currtpd);
3274 numparams=currtpd->task->numParameters;
3275 numtotal=currtpd->task->numTotal;
3277 // clear the lockRedirectTbl
3278 // (TODO, this table should be empty after all locks are released)
3280 /*for(j = 0; j < MAXTASKPARAMS; j++) {
3281 runtime_locks[j].redirectlock = 0;
3282 runtime_locks[j].value = 0;
3284 // get all required locks
3285 runtime_locklen = 0;
3286 // check which locks are needed
3287 for(i = 0; i < numparams; i++) {
3288 void * param = currtpd->parameterArray[i];
3292 if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
3294 taskpointerarray[i+OFFSET]=param;
3297 if(((struct ___Object___ *)param)->lock == NULL) {
3298 tmplock = (int)param;
3300 tmplock = (int)(((struct ___Object___ *)param)->lock);
3302 // insert into the locks array
3303 for(j = 0; j < runtime_locklen; j++) {
3304 if(runtime_locks[j].value == tmplock) {
3307 } else if(runtime_locks[j].value > tmplock) {
3312 int h = runtime_locklen;
3314 runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
3315 runtime_locks[h].value = runtime_locks[h-1].value;
3317 runtime_locks[j].value = tmplock;
3318 runtime_locks[j].redirectlock = (int)param;
3321 } // line 2713: for(i = 0; i < numparams; i++)
3322 // grab these required locks
3324 BAMBOO_DEBUGPRINT(0xe991);
3327 //clock2 = BAMBOO_GET_EXE_TIME();
3329 for(i = 0; i < runtime_locklen; i++) {
3330 int * lock = (int *)(runtime_locks[i].redirectlock);
3332 // require locks for this parameter if it is not a startup object
3334 BAMBOO_DEBUGPRINT_REG((int)lock);
3335 BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
3338 BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
3340 BAMBOO_DEBUGPRINT(0xf001);
3343 //isInterrupt = false;
3346 BAMBOO_WAITING_FOR_LOCK(0);
3347 // check for outgoing sends
3348 /*if (isMsgHanging) {
3349 extern inline void send_hanging_msg(bool);
3350 send_hanging_msg(true);
3355 while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
3356 // check for outgoing sends
3357 /*if (isMsgHanging) {
3358 extern inline void send_hanging_msg(bool);
3359 send_hanging_msg(true);
3364 grount = lockresult;
3374 //isInterrupt = true;
3376 BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
3378 BAMBOO_DEBUGPRINT(0xf000);
3383 BAMBOO_DEBUGPRINT(0xe992);
3384 BAMBOO_DEBUGPRINT_REG(lock);
3386 // check if has the lock already
3387 // can not get the lock, try later
3388 // release all grabbed locks for previous parameters
3389 for(j = 0; j < i; ++j) {
3390 lock = (int*)(runtime_locks[j].redirectlock);
3391 releasewritelock(lock);
3393 genputtable(activetasks, currtpd, currtpd);
3394 if(hashsize(activetasks) == 1) {
3395 // only one task right now, wait a little while before next try
3401 #ifdef ACCURATEPROFILE
3402 // fail, set the end of the checkTaskInfo
3409 } // line 2752: for(i = 0; i < runtime_locklen; i++)
3412 clock3 = BAMBOO_GET_EXE_TIME();
3413 //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
3416 BAMBOO_DEBUGPRINT(0xe993);
3418 /* Make sure that the parameters are still in the queues */
3419 for(i=0; i<numparams; i++) {
3420 void * parameter=currtpd->parameterArray[i];
3424 BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
3425 classsize[((struct ___Object___ *)parameter)->type]);
3427 tmpparam = (struct ___Object___ *)parameter;
3428 pd=currtpd->task->descriptorarray[i];
3429 pw=(struct parameterwrapper *) pd->queue;
3430 /* Check that object is still in queue */
3432 if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
3434 BAMBOO_DEBUGPRINT(0xe994);
3435 BAMBOO_DEBUGPRINT_REG(parameter);
3437 // release grabbed locks
3438 for(j = 0; j < runtime_locklen; ++j) {
3439 int * lock = (int *)(runtime_locks[j].redirectlock);
3440 releasewritelock(lock);
3442 RUNFREE(currtpd->parameterArray);
3448 /* Check if the object's flags still meets requirements */
3452 for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
3453 andmask=pw->intarray[tmpi*2];
3454 checkmask=pw->intarray[tmpi*2+1];
3455 if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
3461 // flags are never suitable
3462 // remove this obj from the queue
3464 int UNUSED, UNUSED2;
3467 BAMBOO_DEBUGPRINT(0xe995);
3468 BAMBOO_DEBUGPRINT_REG(parameter);
3470 ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
3471 (int *) &enterflags, &UNUSED, &UNUSED2);
3472 ObjectHashremove(pw->objectset, (int)parameter);
3473 if (enterflags!=NULL)
3474 RUNFREE(enterflags);
3475 // release grabbed locks
3476 for(j = 0; j < runtime_locklen; ++j) {
3477 int * lock = (int *)(runtime_locks[j].redirectlock);
3478 releasewritelock(lock);
3480 RUNFREE(currtpd->parameterArray);
3484 #ifdef ACCURATEPROFILE
3485 // fail, set the end of the checkTaskInfo
3490 } // line 2878: if (!ismet)
3494 /* Check that object still has necessary tags */
3495 for(j=0; j<pd->numbertags; j++) {
3496 int slotid=pd->tagarray[2*j]+numparams;
3497 struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
3498 if (!containstag(parameter, tagd)) {
3500 BAMBOO_DEBUGPRINT(0xe996);
3503 // release grabbed locks
3505 for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
3506 int * lock = (int *)(runtime_locks[tmpj].redirectlock);
3507 releasewritelock(lock);
3510 RUNFREE(currtpd->parameterArray);
3514 } // line2911: if (!containstag(parameter, tagd))
3515 } // line 2808: for(j=0; j<pd->numbertags; j++)
3517 taskpointerarray[i+OFFSET]=parameter;
3518 } // line 2824: for(i=0; i<numparams; i++)
3520 for(; i<numtotal; i++) {
3521 taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
3526 /* Actually call task */
3528 ((int *)taskpointerarray)[0]=currtpd->numParameters;
3529 taskpointerarray[1]=NULL;
3532 #ifdef ACCURATEPROFILE
3533 // check finish, set the end of the checkTaskInfo
3536 profileTaskStart(currtpd->task->name);
3540 //clock4 = BAMBOO_GET_EXE_TIME();
3541 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3544 BAMBOO_DEBUGPRINT(0xe997);
3546 ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
3549 //clock5 = BAMBOO_GET_EXE_TIME();
3550 // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3553 #ifdef ACCURATEPROFILE
3554 // task finish, set the end of the checkTaskInfo
3556 // new a PostTaskInfo for the post-task execution
3557 profileTaskStart("post task execution");
3561 BAMBOO_DEBUGPRINT(0xe998);
3562 BAMBOO_DEBUGPRINT_REG(islock);
3567 BAMBOO_DEBUGPRINT(0xe999);
3569 for(i = 0; i < runtime_locklen; ++i) {
3570 void * ptr = (void *)(runtime_locks[i].redirectlock);
3571 int * lock = (int *)(runtime_locks[i].value);
3573 BAMBOO_DEBUGPRINT_REG((int)ptr);
3574 BAMBOO_DEBUGPRINT_REG((int)lock);
3575 BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
3577 #ifndef MULTICORE_GC
3578 if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
3580 RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
3581 RuntimeHashremovekey(lockRedirectTbl, (int)lock);
3582 releasewritelock_r(lock, (int *)redirectlock);
3587 releasewritelock(ptr);
3590 } // line 3015: if(islock)
3593 //clock6 = BAMBOO_GET_EXE_TIME();
3594 //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
3597 // post task execution finish, set the end of the postTaskInfo
3601 // Free up task parameter descriptor
3602 RUNFREE(currtpd->parameterArray);
3606 BAMBOO_DEBUGPRINT(0xe99a);
3609 //clock7 = BAMBOO_GET_EXE_TIME();
3610 //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));
3613 //} // if (hashsize(activetasks)>0)
3614 } // while(hashsize(activetasks)>0)
3616 BAMBOO_DEBUGPRINT(0xe99b);
3620 /* This function processes an objects tags */
3621 void processtags(struct parameterdescriptor *pd,
3623 struct parameterwrapper *parameter,
3624 int * iteratorcount,
3629 for(i=0; i<pd->numbertags; i++) {
3630 int slotid=pd->tagarray[2*i];
3631 int tagid=pd->tagarray[2*i+1];
3633 if (statusarray[slotid+numparams]==0) {
3634 parameter->iterators[*iteratorcount].istag=1;
3635 parameter->iterators[*iteratorcount].tagid=tagid;
3636 parameter->iterators[*iteratorcount].slot=slotid+numparams;
3637 parameter->iterators[*iteratorcount].tagobjectslot=index;
3638 statusarray[slotid+numparams]=1;
3645 void processobject(struct parameterwrapper *parameter,
3647 struct parameterdescriptor *pd,
3653 struct ObjectHash * objectset=
3654 ((struct parameterwrapper *)pd->queue)->objectset;
3656 parameter->iterators[*iteratorcount].istag=0;
3657 parameter->iterators[*iteratorcount].slot=index;
3658 parameter->iterators[*iteratorcount].objectset=objectset;
3659 statusarray[index]=1;
3661 for(i=0; i<pd->numbertags; i++) {
3662 int slotid=pd->tagarray[2*i];
3663 //int tagid=pd->tagarray[2*i+1];
3664 if (statusarray[slotid+numparams]!=0) {
3665 /* This tag has already been enqueued, use it to narrow search */
3666 parameter->iterators[*iteratorcount].tagbindings[tagcount]=
3671 parameter->iterators[*iteratorcount].numtags=tagcount;
3676 /* This function builds the iterators for a task & parameter */
3678 void builditerators(struct taskdescriptor * task,
3680 struct parameterwrapper * parameter) {
3681 int statusarray[MAXTASKPARAMS];
3683 int numparams=task->numParameters;
3684 int iteratorcount=0;
3685 for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
3687 statusarray[index]=1; /* Initial parameter */
3688 /* Process tags for initial iterator */
3690 processtags(task->descriptorarray[index], index, parameter,
3691 &iteratorcount, statusarray, numparams);
3695 /* Check for objects with existing tags */
3696 for(i=0; i<numparams; i++) {
3697 if (statusarray[i]==0) {
3698 struct parameterdescriptor *pd=task->descriptorarray[i];
3700 for(j=0; j<pd->numbertags; j++) {
3701 int slotid=pd->tagarray[2*j];
3702 if(statusarray[slotid+numparams]!=0) {
3703 processobject(parameter, i, pd, &iteratorcount, statusarray,
3705 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3712 /* Next do objects w/ unbound tags*/
3714 for(i=0; i<numparams; i++) {
3715 if (statusarray[i]==0) {
3716 struct parameterdescriptor *pd=task->descriptorarray[i];
3717 if (pd->numbertags>0) {
3718 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3719 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3725 /* Nothing with a tag enqueued */
3727 for(i=0; i<numparams; i++) {
3728 if (statusarray[i]==0) {
3729 struct parameterdescriptor *pd=task->descriptorarray[i];
3730 processobject(parameter, i, pd, &iteratorcount, statusarray, numparams);
3731 processtags(pd, i, parameter, &iteratorcount, statusarray, numparams);
3744 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3747 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3748 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3750 printf("%s\n", task->name);
3752 for(j=0; j<task->numParameters; j++) {
3753 struct parameterdescriptor *param=task->descriptorarray[j];
3754 struct parameterwrapper *parameter=param->queue;
3755 struct ObjectHash * set=parameter->objectset;
3756 struct ObjectIterator objit;
3758 printf(" Parameter %d\n", j);
3760 ObjectHashiterator(set, &objit);
3761 while(ObjhasNext(&objit)) {
3762 struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
3763 struct ___Object___ * tagptr=obj->___tags___;
3764 int nonfailed=Objdata4(&objit);
3765 int numflags=Objdata3(&objit);
3766 int flags=Objdata2(&objit);
3769 printf(" Contains %lx\n", obj);
3770 printf(" flag=%d\n", obj->flag);
3773 } else if (tagptr->type==TAGTYPE) {
3775 printf(" tag=%lx\n",tagptr);
3781 struct ArrayObject *ao=(struct ArrayObject *)tagptr;
3782 for(; tagindex<ao->___cachedCode___; tagindex++) {
3784 printf(" tag=%lx\n",ARRAYGET(ao, struct ___TagDescriptor___*,
3797 /* This function processes the task information to create queues for
3798 each parameter type. */
3800 void processtasks() {
3802 if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
3805 for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
3806 struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
3809 /* Build objectsets */
3810 for(j=0; j<task->numParameters; j++) {
3811 struct parameterdescriptor *param=task->descriptorarray[j];
3812 struct parameterwrapper *parameter=param->queue;
3813 parameter->objectset=allocateObjectHash(10);
3814 parameter->task=task;
3817 /* Build iterators for parameters */
3818 for(j=0; j<task->numParameters; j++) {
3819 struct parameterdescriptor *param=task->descriptorarray[j];
3820 struct parameterwrapper *parameter=param->queue;
3821 builditerators(task, j, parameter);
3826 void toiReset(struct tagobjectiterator * it) {
3829 } else if (it->numtags>0) {
3832 ObjectHashiterator(it->objectset, &it->it);
3836 int toiHasNext(struct tagobjectiterator *it,
3837 void ** objectarray OPTARG(int * failed)) {
3840 /* Get object with tags */
3841 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3842 struct ___Object___ *tagptr=obj->___tags___;
3843 if (tagptr->type==TAGTYPE) {
3844 if ((it->tagobjindex==0)&& /* First object */
3845 (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
3850 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3851 int tagindex=it->tagobjindex;
3852 for(; tagindex<ao->___cachedCode___; tagindex++) {
3853 struct ___TagDescriptor___ *td=
3854 ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
3855 if (td->flag==it->tagid) {
3856 it->tagobjindex=tagindex; /* Found right type of tag */
3862 } else if (it->numtags>0) {
3863 /* Use tags to locate appropriate objects */
3864 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3865 struct ___Object___ *objptr=tag->flagptr;
3867 if (objptr->type!=OBJECTARRAYTYPE) {
3868 if (it->tagobjindex>0)
3870 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3872 for(i=1; i<it->numtags; i++) {
3873 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3874 if (!containstag(objptr,tag2))
3879 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3882 for(tagindex=it->tagobjindex; tagindex<ao->___cachedCode___; tagindex++) {
3883 struct ___Object___ *objptr=ARRAYGET(ao, struct ___Object___*, tagindex);
3884 if (!ObjectHashcontainskey(it->objectset, (int) objptr))
3886 for(i=1; i<it->numtags; i++) {
3887 struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
3888 if (!containstag(objptr,tag2))
3891 it->tagobjindex=tagindex;
3896 it->tagobjindex=tagindex;
3900 return ObjhasNext(&it->it);
3904 int containstag(struct ___Object___ *ptr,
3905 struct ___TagDescriptor___ *tag) {
3907 struct ___Object___ * objptr=tag->flagptr;
3908 if (objptr->type==OBJECTARRAYTYPE) {
3909 struct ArrayObject *ao=(struct ArrayObject *)objptr;
3910 for(j=0; j<ao->___cachedCode___; j++) {
3911 if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
3921 void toiNext(struct tagobjectiterator *it,
3922 void ** objectarray OPTARG(int * failed)) {
3923 /* hasNext has all of the intelligence */
3926 /* Get object with tags */
3927 struct ___Object___ *obj=objectarray[it->tagobjectslot];
3928 struct ___Object___ *tagptr=obj->___tags___;
3929 if (tagptr->type==TAGTYPE) {
3931 objectarray[it->slot]=tagptr;
3933 struct ArrayObject *ao=(struct ArrayObject *) tagptr;
3934 objectarray[it->slot]=
3935 ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
3937 } else if (it->numtags>0) {
3938 /* Use tags to locate appropriate objects */
3939 struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
3940 struct ___Object___ *objptr=tag->flagptr;
3941 if (objptr->type!=OBJECTARRAYTYPE) {
3943 objectarray[it->slot]=objptr;
3945 struct ArrayObject *ao=(struct ArrayObject *) objptr;
3946 objectarray[it->slot]=
3947 ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
3950 /* Iterate object */
3951 objectarray[it->slot]=(void *)Objkey(&it->it);
3957 inline void profileTaskStart(char * taskname) {
3958 if(!taskInfoOverflow) {
3959 TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
3960 taskInfoArray[taskInfoIndex] = taskInfo;
3961 taskInfo->taskName = taskname;
3962 taskInfo->startTime = BAMBOO_GET_EXE_TIME();
3963 taskInfo->endTime = -1;
3964 taskInfo->exitIndex = -1;
3965 taskInfo->newObjs = NULL;
3969 inline void profileTaskEnd() {
3970 if(!taskInfoOverflow) {
3971 taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
3973 if(taskInfoIndex == TASKINFOLENGTH) {
3974 taskInfoOverflow = true;
3975 //taskInfoIndex = 0;
3980 // output the profiling data
3981 void outputProfileData() {
3984 unsigned long long totaltasktime = 0;
3985 unsigned long long preprocessingtime = 0;
3986 unsigned long long objqueuecheckingtime = 0;
3987 unsigned long long postprocessingtime = 0;
3988 //int interruptiontime = 0;
3989 unsigned long long other = 0;
3990 unsigned long long averagetasktime = 0;
3993 printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
3994 // output task related info
3995 for(i = 0; i < taskInfoIndex; i++) {
3996 TaskInfo* tmpTInfo = taskInfoArray[i];
3997 unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
3998 printf("%s, %lld, %lld, %lld, %lld",
3999 tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
4000 duration, tmpTInfo->exitIndex);
4001 // summarize new obj info
4002 if(tmpTInfo->newObjs != NULL) {
4003 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4004 struct RuntimeIterator * iter = NULL;
4005 while(0 == isEmpty(tmpTInfo->newObjs)) {
4006 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4007 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4009 RuntimeHashget(nobjtbl, (int)objtype, &num);
4010 RuntimeHashremovekey(nobjtbl, (int)objtype);
4012 RuntimeHashadd(nobjtbl, (int)objtype, num);
4014 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4016 //printf(stderr, "new obj!\n");
4019 // output all new obj info
4020 iter = RuntimeHashcreateiterator(nobjtbl);
4021 while(RunhasNext(iter)) {
4022 char * objtype = (char *)Runkey(iter);
4023 int num = Runnext(iter);
4024 printf(", %s, %d", objtype, num);
4028 if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
4029 preprocessingtime += duration;
4030 } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
4031 postprocessingtime += duration;
4032 } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
4033 objqueuecheckingtime += duration;
4035 totaltasktime += duration;
4036 averagetasktime += duration;
4041 if(taskInfoOverflow) {
4042 printf("Caution: task info overflow!\n");
4045 other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
4046 averagetasktime /= tasknum;
4048 printf("\nTotal time: %lld\n", totalexetime);
4049 printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
4050 (int)(((double)totaltasktime/(double)totalexetime)*100));
4051 printf("Total objqueue checking time: %lld (%d%%)\n",
4052 objqueuecheckingtime,
4053 (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
4054 printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
4055 (int)(((double)preprocessingtime/(double)totalexetime)*100));
4056 printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
4057 (int)(((double)postprocessingtime/(double)totalexetime)*100));
4058 printf("Other time: %lld (%d%%)\n", other,
4059 (int)(((double)other/(double)totalexetime)*100));
4062 printf("\nAverage task execution time: %lld\n", averagetasktime);
4064 //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
4069 BAMBOO_DEBUGPRINT(0xdddd);
4070 // output task related info
4071 for(i= 0; i < taskInfoIndex; i++) {
4072 TaskInfo* tmpTInfo = taskInfoArray[i];
4073 char* tmpName = tmpTInfo->taskName;
4074 int nameLen = strlen(tmpName);
4075 BAMBOO_DEBUGPRINT(0xddda);
4076 for(j = 0; j < nameLen; j++) {
4077 BAMBOO_DEBUGPRINT_REG(tmpName[j]);
4079 BAMBOO_DEBUGPRINT(0xdddb);
4080 BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
4081 BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
4082 BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
4083 if(tmpTInfo->newObjs != NULL) {
4084 struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
4085 struct RuntimeIterator * iter = NULL;
4086 while(0 == isEmpty(tmpTInfo->newObjs)) {
4087 char * objtype = (char *)(getItem(tmpTInfo->newObjs));
4088 if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
4090 RuntimeHashget(nobjtbl, (int)objtype, &num);
4091 RuntimeHashremovekey(nobjtbl, (int)objtype);
4093 RuntimeHashadd(nobjtbl, (int)objtype, num);
4095 RuntimeHashadd(nobjtbl, (int)objtype, 1);
4099 // ouput all new obj info
4100 iter = RuntimeHashcreateiterator(nobjtbl);
4101 while(RunhasNext(iter)) {
4102 char * objtype = (char *)Runkey(iter);
4103 int num = Runnext(iter);
4104 int nameLen = strlen(objtype);
4105 BAMBOO_DEBUGPRINT(0xddda);
4106 for(j = 0; j < nameLen; j++) {
4107 BAMBOO_DEBUGPRINT_REG(objtype[j]);
4109 BAMBOO_DEBUGPRINT(0xdddb);
4110 BAMBOO_DEBUGPRINT_REG(num);
4113 BAMBOO_DEBUGPRINT(0xdddc);
4116 if(taskInfoOverflow) {
4117 BAMBOO_DEBUGPRINT(0xefee);
4120 // output interrupt related info
4121 for(i = 0; i < interruptInfoIndex; i++) {
4122 InterruptInfo* tmpIInfo = interruptInfoArray[i];
4123 BAMBOO_DEBUGPRINT(0xddde);
4124 BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
4125 BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
4126 BAMBOO_DEBUGPRINT(0xdddf);
4129 if(interruptInfoOverflow) {
4130 BAMBOO_DEBUGPRINT(0xefef);
4133 BAMBOO_DEBUGPRINT(0xeeee);
4136 #endif // #ifdef PROFILE