2 #include "multicoremsg.h"
4 #include "multicoreruntime.h"
5 #include "multicoretaskprofile.h"
8 INLINE int checkMsgLength_I(int size) {
9 int type = msgdata[msgdataindex];
87 case TRANSOBJ: // nonfixed size
94 return msgdata[(msgdataindex+1)&(BAMBOO_MSG_BUF_MASK)];
103 tprintf("%x \n", type);
108 return BAMBOO_OUT_BUF_LENGTH;
111 INLINE void processmsg_transobj_I(int msglength) {
113 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
114 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
116 // store the object and its corresponding queue info, enqueue it later
117 transObj->objptr = (void *)msgdata[msgdataindex];
119 transObj->length = (msglength - 3) / 2;
120 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
121 for(int k = 0; k < transObj->length; k++) {
122 transObj->queues[2*k] = msgdata[msgdataindex];
124 transObj->queues[2*k+1] = msgdata[msgdataindex];
127 // check if there is an existing duplicate item
128 struct QueueItem * prev = NULL;
129 for(struct QueueItem * qitem = getHead(&objqueue);qitem != NULL;qitem=(prev==NULL)?getHead(&objqueue):getNextQueueItem(prev)) {
130 struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
131 if(tmpinfo->objptr == transObj->objptr) {
132 // the same object, remove outdate one
133 RUNFREE_I(tmpinfo->queues);
135 removeItem(&objqueue, qitem);
141 addNewItem_I(&objqueue, (void *)transObj);
143 self_numreceiveobjs++;
146 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
147 // set the gcprecheck to enable checking again
150 // send a update pregc information msg to the master core
151 if(BAMBOO_CHECK_SEND_MODE()) {
152 cache_msg_4_I(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
154 send_msg_4_I(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs, self_numreceiveobjs);
161 INLINE void processmsg_transtall_I() {
162 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
164 int num_core = msgdata[msgdataindex];
166 int data2 = msgdata[msgdataindex];
168 int data3 = msgdata[msgdataindex];
170 if(num_core < NUMCORESACTIVE) {
171 corestatus[num_core] = 0;
172 numsendobjs[num_core] = data2;
173 numreceiveobjs[num_core] = data3;
178 INLINE void processmsg_lockrequest_I() {
179 // check to see if there is a lock exist for the required obj
180 // msgdata[1] -> lock type
181 int locktype = msgdata[msgdataindex];
183 int data2 = msgdata[msgdataindex]; // obj pointer
185 int data3 = msgdata[msgdataindex]; // lock
187 int data4 = msgdata[msgdataindex]; // request core
189 // -1: redirected, 0: approved, 1: denied
190 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
193 // for 32 bit machine, the size is always 4 words, cache the msg first
194 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
195 if(BAMBOO_CHECK_SEND_MODE()) {
196 cache_msg_4_I(data4,tmp,locktype,data2,data3);
198 send_msg_4_I(data4,tmp,locktype,data2,data3);
203 INLINE void processmsg_lockgrount_I() {
205 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
206 int data2 = msgdata[msgdataindex];
208 int data3 = msgdata[msgdataindex];
210 BAMBOO_ASSERT((lockobj == data2) && (lock2require == data3));
218 INLINE void processmsg_lockdeny_I() {
220 int data2 = msgdata[msgdataindex];
222 int data3 = msgdata[msgdataindex];
224 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
225 BAMBOO_ASSERT((lockobj == data2) && (lock2require == data3));
233 INLINE void processmsg_lockrelease_I() {
234 int data1 = msgdata[msgdataindex];
236 int data2 = msgdata[msgdataindex];
238 int data3 = msgdata[msgdataindex];
240 // receive lock release msg
241 processlockrelease(data1, data2, 0, false);
244 INLINE void processmsg_redirectlock_I() {
245 // check to see if there is a lock exist for the required obj
246 int data1 = msgdata[msgdataindex];
247 MSG_INDEXINC_I(); // lock type
248 int data2 = msgdata[msgdataindex];
249 MSG_INDEXINC_I(); // obj pointer
250 int data3 = msgdata[msgdataindex];
251 MSG_INDEXINC_I(); // redirect lock
252 int data4 = msgdata[msgdataindex];
253 MSG_INDEXINC_I(); // root request core
254 int data5 = msgdata[msgdataindex];
255 MSG_INDEXINC_I(); // request core
256 int deny = processlockrequest_I(data1, data3, data2, data5, data4, true);
259 // for 32 bit machine, the size is always 4 words, cache the msg first
260 if(BAMBOO_CHECK_SEND_MODE()) {
261 cache_msg_4_I(data4,deny==1?REDIRECTDENY:REDIRECTGROUNT,data1,data2,data3);
263 send_msg_4_I(data4,deny==1?REDIRECTDENY:REDIRECTGROUNT,data1,data2,data3);
268 INLINE void processmsg_redirectgrount_I() {
270 int data2 = msgdata[msgdataindex];
272 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
273 BAMBOO_ASSERT(lockobj == data2, 0xe207);
274 int data3 = msgdata[msgdataindex];
278 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
284 INLINE void processmsg_redirectdeny_I() {
286 int data2 = msgdata[msgdataindex];
288 int data3 = msgdata[msgdataindex];
290 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
291 BAMBOO_ASSERT(lockobj == data2);
299 INLINE void processmsg_redirectrelease_I() {
300 int data1 = msgdata[msgdataindex];
302 int data2 = msgdata[msgdataindex];
304 int data3 = msgdata[msgdataindex];
306 processlockrelease_I(data1, data2, data3, true);
308 #endif // #ifndef MULTICORE_GC
311 INLINE void processmsg_profileoutput_I() {
312 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE != STARTUPCORE);
314 totalexetime = msgdata[msgdataindex];
320 // cache the msg first
321 if(BAMBOO_CHECK_SEND_MODE()) {
322 cache_msg_2_I(STARTUPCORE,PROFILEFINISH,BAMBOO_NUM_OF_CORE);
324 send_msg_2_I(STARTUPCORE,PROFILEFINISH,BAMBOO_NUM_OF_CORE);
328 INLINE void processmsg_profilefinish_I() {
329 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
330 int data1 = msgdata[msgdataindex];
332 profilestatus[data1] = 0;
336 INLINE void processmsg_statusconfirm_I() {
337 BAMBOO_ASSERT(((BAMBOO_NUM_OF_CORE != STARTUPCORE) && (BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1)));
339 // cache the msg first
340 if(BAMBOO_CHECK_SEND_MODE()) {
341 cache_msg_5_I(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
343 send_msg_5_I(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
347 INLINE void processmsg_statusreport_I() {
348 int data1 = msgdata[msgdataindex];
350 int data2 = msgdata[msgdataindex];
352 int data3 = msgdata[msgdataindex];
354 int data4 = msgdata[msgdataindex];
356 // receive a status confirm info
357 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
361 corestatus[data2] = data1;
362 numsendobjs[data2] = data3;
363 numreceiveobjs[data2] = data4;
366 INLINE void processmsg_terminate_I() {
369 #ifdef GC_CACHE_ADAPT
370 bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
376 INLINE void processmsg_memrequest_I() {
377 int data1 = msgdata[msgdataindex];
379 int data2 = msgdata[msgdataindex];
381 // receive a shared memory request msg
382 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
386 if(!gcprocessing || !gcflag) {
387 // either not doing GC or the master core has decided to stop GC but
388 // // still sending msgs to other cores to inform them to stop the GC
390 mem = smemalloc_I(data2, data1, &allocsize);
392 // send the start_va to request core, cache the msg first
393 if(BAMBOO_CHECK_SEND_MODE()) {
394 cache_msg_3_I(data2,MEMRESPONSE,mem,allocsize);
396 send_msg_3_I(data2,MEMRESPONSE,mem,allocsize);
398 } //else if mem == NULL, the gcflag of the startup core has been set
399 // and all the other cores have been informed to start gc
405 INLINE void processmsg_memresponse_I() {
406 int data1 = msgdata[msgdataindex];
408 int data2 = msgdata[msgdataindex];
410 // receive a shared memory response msg
412 // if is currently doing gc, dump this msg
417 // Zero out the remaining memory here because for the GC_CACHE_ADAPT
418 // version, we need to make sure during the gcinit phase the shared heap
419 // is not touched. Otherwise, there would be problem when adapt the cache
421 BAMBOO_CLOSE_CUR_MSP();
422 bamboo_smem_zero_top = NULL;
424 bamboo_smem_size = 0;
428 CLOSEBLOCK(data1, data2);
429 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
430 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
431 bamboo_smem_zero_top = bamboo_cur_msp;
433 bamboo_smem_size = data2;
434 bamboo_cur_msp =(void*)(data1);
444 INLINE void processmsg_gcstartpre_I() {
445 // the first time to be informed to start gc
448 // Zero out the remaining memory here because for the GC_CACHE_ADAPT
449 // version, we need to make sure during the gcinit phase the shared heap
450 // is not touched. Otherwise, there would be problem when adapt the cache
452 BAMBOO_CLOSE_CUR_MSP();
453 bamboo_smem_size = 0;
454 bamboo_cur_msp = NULL;
456 bamboo_smem_zero_top = NULL;
460 INLINE void processmsg_gcstartinit_I() {
464 INLINE void processmsg_gcstart_I() {
469 INLINE void processmsg_gcstartcompact_I() {
470 gcblock2fill = msgdata[msgdataindex];
472 gcphase = COMPACTPHASE;
475 INLINE void processmsg_gcstartflush_I() {
476 gcphase = FLUSHPHASE;
479 INLINE void processmsg_gcfinishpre_I() {
480 int data1 = msgdata[msgdataindex];
482 int data2 = msgdata[msgdataindex];
484 int data3 = msgdata[msgdataindex];
486 // received a init phase finish msg
487 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
489 // All cores should do init GC
491 gccorestatus[data1] = 0;
492 gcnumsendobjs[0][data1] = data2;
493 gcnumreceiveobjs[0][data1] = data3;
496 INLINE void processmsg_gcfinishinit_I() {
497 int data1 = msgdata[msgdataindex];
499 // received a init phase finish msg
500 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
502 // All cores should do init GC
503 if(data1 < NUMCORESACTIVE) {
504 gccorestatus[data1] = 0;
508 INLINE void processmsg_gcfinishmark_I() {
509 int data1 = msgdata[msgdataindex];
511 int data2 = msgdata[msgdataindex];
513 int data3 = msgdata[msgdataindex];
515 // received a mark phase finish msg
516 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
518 // all cores should do mark
519 if(data1 < NUMCORESACTIVE) {
520 gccorestatus[data1] = 0;
524 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
527 entry_index = gcnumsrobjs_index;
529 gcnumsendobjs[entry_index][data1] = data2;
530 gcnumreceiveobjs[entry_index][data1] = data3;
534 INLINE void processmsg_gcfinishcompact_I() {
535 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
537 int cnum = msgdata[msgdataindex];
539 int filledblocks = msgdata[msgdataindex];
541 int heaptop = msgdata[msgdataindex];
543 int data4 = msgdata[msgdataindex];
545 // only gc cores need to do compact
546 if(cnum < NUMCORES4GC) {
547 if(COMPACTPHASE == gcphase) {
548 gcfilledblocks[cnum] = filledblocks;
549 gcloads[cnum] = heaptop;
556 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
557 // cache the msg first
558 if(BAMBOO_CHECK_SEND_MODE()) {
559 cache_msg_4_I(cnum,GCMOVESTART,dstcore,startaddr,tomove);
561 send_msg_4_I(cnum,GCMOVESTART,dstcore,startaddr,tomove);
565 gccorestatus[cnum] = 0;
570 INLINE void processmsg_gcfinishflush_I() {
571 int data1 = msgdata[msgdataindex];
573 // received a flush phase finish msg
574 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
576 // all cores should do flush
577 if(data1 < NUMCORESACTIVE) {
578 gccorestatus[data1] = 0;
582 INLINE void processmsg_gcfinish_I() {
583 // received a GC finish msg
584 gcphase = FINISHPHASE;
585 gcprocessing = false;
588 INLINE void processmsg_gcmarkconfirm_I() {
589 BAMBOO_ASSERT(((BAMBOO_NUM_OF_CORE!=STARTUPCORE)&&(BAMBOO_NUM_OF_CORE<=NUMCORESACTIVE-1)));
590 gcbusystatus = gc_moreItems2_I();
591 // send response msg, cahce the msg first
592 if(BAMBOO_CHECK_SEND_MODE()) {
593 cache_msg_5_I(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gcbusystatus,gcself_numsendobjs,gcself_numreceiveobjs);
595 send_msg_5_I(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gcbusystatus,gcself_numsendobjs,gcself_numreceiveobjs);
599 INLINE void processmsg_gcmarkreport_I() {
600 int data1 = msgdata[msgdataindex];
602 int data2 = msgdata[msgdataindex];
604 int data3 = msgdata[msgdataindex];
606 int data4 = msgdata[msgdataindex];
608 // received a marked phase finish confirm response msg
609 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
611 BAMBOO_ASSERT(waitconfirm);
615 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
616 gccorestatus[data1] = data2;
617 gcnumsendobjs[entry_index][data1] = data3;
618 gcnumreceiveobjs[entry_index][data1] = data4;
622 INLINE void processmsg_gcmarkedobj_I() {
623 int data1 = msgdata[msgdataindex];
625 BAMBOO_ASSERT(ISSHAREDOBJ(data1));
627 // received a markedObj msg
628 if(((struct ___Object___ *)data1)->marked == INIT) {
629 // this is the first time that this object is discovered,
630 // set the flag as DISCOVERED
631 ((struct ___Object___ *)data1)->marked = DISCOVERED;
634 gcself_numreceiveobjs++;
638 INLINE void processmsg_gcmovestart_I() {
640 gcdstcore = msgdata[msgdataindex];
642 gcmovestartaddr = msgdata[msgdataindex];
644 gcblock2fill = msgdata[msgdataindex];
648 INLINE void processmsg_gclobjinfo_I() {
650 int data1 = msgdata[msgdataindex];
652 int data2 = msgdata[msgdataindex];
654 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORES4GC - 1);
656 // store the mark result info
658 gcloads[cnum] = msgdata[msgdataindex];
660 int data4 = msgdata[msgdataindex];
662 if(gcheaptop < data4) {
665 // large obj info here
666 for(int k = 5; k < data1; k+=2) {
667 int lobj = msgdata[msgdataindex];
669 int length = msgdata[msgdataindex];
671 gc_lobjenqueue_I(lobj, length, cnum);
677 INLINE void processmsg_gcprofiles_I() {
678 int data1 = msgdata[msgdataindex];
680 int data2 = msgdata[msgdataindex];
682 int data3 = msgdata[msgdataindex];
685 if(gc_profile_flag) {
688 gc_num_liveobj += data2;
689 gc_num_forwardobj += data3;
697 #ifdef GC_CACHE_ADAPT
698 INLINE void processmsg_gcstartpref_I() {
699 gcphase = PREFINISHPHASE;
702 INLINE void processmsg_gcfinishpref_I() {
703 int data1 = msgdata[msgdataindex];
705 // received a flush phase finish msg
706 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
708 // all cores should do flush
709 if(data1 < NUMCORESACTIVE) {
710 gccorestatus[data1] = 0;
713 #endif // GC_CACHE_ADAPT
714 #endif // #ifdef MULTICORE_GC
716 // receive object transferred from other cores
717 // or the terminate message from other cores
718 // Should be invoked in critical sections!!
719 // NOTICE: following format is for threadsimulate version only
720 // RAW version please see previous description
721 // format: type + object
722 // type: -1--stall msg
724 // return value: 0--received an object
725 // 1--received nothing
726 // 2--received a Stall Msg
727 // 3--received a lock Msg
728 // RAW version: -1 -- received nothing
729 // otherwise -- received msg type
730 int receiveObject_I() {
731 PROFILE_INTERRUPT_START();
733 // get the incoming msgs
735 if(BAMBOO_CHECK_SEND_MODE()) {
736 // during send, don't process the msg now
740 // processing received msgs
743 MSG_REMAINSIZE_I(&size);
744 if((size == 0) || ((msglength=checkMsgLength_I(size)) == -1)) {
746 // have new coming msg
747 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
754 if(msglength <= size) {
755 // have some whole msg
757 type = msgdata[msgdataindex]; //[0]
763 // receive a object transfer msg
764 processmsg_transobj_I(msglength);
769 // receive a stall msg
770 processmsg_transtall_I();
775 // GC version have no lock msgs
778 // receive lock request msg, handle it right now
779 processmsg_lockrequest_I();
783 // receive lock grount msg
784 processmsg_lockgrount_I();
788 // receive lock deny msg
789 processmsg_lockdeny_I();
793 processmsg_lockrelease_I();
799 case PROFILEOUTPUT: {
800 // receive an output profile data request msg
801 processmsg_profileoutput_I();
804 case PROFILEFINISH: {
805 // receive a profile output finish msg
806 processmsg_profilefinish_I();
811 // GC version has no lock msgs
814 // receive a redirect lock request msg, handle it right now
815 processmsg_redirectlock_I();
819 case REDIRECTGROUNT: {
820 // receive a lock grant msg with redirect info
821 processmsg_redirectgrount_I();
826 // receive a lock deny msg with redirect info
827 processmsg_redirectdeny_I();
831 case REDIRECTRELEASE: {
832 // receive a lock release msg with redirect info
833 processmsg_redirectrelease_I();
835 } // case REDIRECTRELEASE
839 case STATUSCONFIRM: {
840 // receive a status confirm info
841 processmsg_statusconfirm_I();
846 processmsg_statusreport_I();
851 // receive a terminate msg
852 processmsg_terminate_I();
857 processmsg_memrequest_I();
862 processmsg_memresponse_I();
869 processmsg_gcstartpre_I();
874 processmsg_gcstartinit_I();
879 // receive a start GC msg
880 processmsg_gcstart_I();
884 case GCSTARTCOMPACT: {
885 // a compact phase start msg
886 processmsg_gcstartcompact_I();
891 // received a flush phase start msg
892 processmsg_gcstartflush_I();
897 processmsg_gcfinishpre_I();
902 processmsg_gcfinishinit_I();
907 processmsg_gcfinishmark_I();
911 case GCFINISHCOMPACT: {
912 // received a compact phase finish msg
913 processmsg_gcfinishcompact_I();
917 case GCFINISHFLUSH: {
918 processmsg_gcfinishflush_I();
923 processmsg_gcfinish_I();
927 case GCMARKCONFIRM: {
928 // received a marked phase finish confirm request msg
929 // all cores should do mark
930 processmsg_gcmarkconfirm_I();
935 processmsg_gcmarkreport_I();
940 processmsg_gcmarkedobj_I();
945 // received a start moving objs msg
946 processmsg_gcmovestart_I();
950 case GCLOBJREQUEST: {
951 // received a large objs info request msg
952 transferMarkResults_I();
957 // received a large objs info response msg
958 processmsg_gclobjinfo_I();
964 // received a gcprofiles msg
965 processmsg_gcprofiles_I();
970 #ifdef GC_CACHE_ADAPT
972 // received a gcstartpref msg
973 processmsg_gcstartpref_I();
978 // received a gcfinishpref msg
979 processmsg_gcfinishpref_I();
989 if((msgdataindex != msgdatalast) || (msgdatafull)) {
990 // still have available msg
994 // have new coming msg
995 if(BAMBOO_MSG_AVAIL() != 0) {
999 PROFILE_INTERRUPT_END();