2 #include "multicoremsg.h"
4 #include "multicoreruntime.h"
5 #include "multicoretaskprofile.h"
7 INLINE int checkMsgLength_I(int size) {
8 int type = msgdata[msgdataindex];
86 case TRANSOBJ: // nonfixed size
93 msglength = msgdata[(msgdataindex+1)&(BAMBOO_MSG_BUF_MASK)];
107 INLINE void processmsg_transobj_I() {
109 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
110 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1, 0xe201);
112 // store the object and its corresponding queue info, enqueue it later
113 transObj->objptr = (void *)msgdata[msgdataindex];
115 transObj->length = (msglength - 3) / 2;
116 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
117 for(int k = 0; k < transObj->length; k++) {
118 transObj->queues[2*k] = msgdata[msgdataindex];
120 transObj->queues[2*k+1] = msgdata[msgdataindex];
123 // check if there is an existing duplicate item
124 struct QueueItem * prev = NULL;
125 for(struct QueueItem * qitem = getHead(&objqueue);qitem != NULL;qitem=(prev==NULL)?getHead(&objqueue):getNextQueueItem(prev)) {
126 struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
127 if(tmpinfo->objptr == transObj->objptr) {
128 // the same object, remove outdate one
129 RUNFREE_I(tmpinfo->queues);
131 removeItem(&objqueue, qitem);
137 addNewItem_I(&objqueue, (void *)transObj);
139 self_numreceiveobjs++;
142 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
143 // set the gcprecheck to enable checking again
146 // send a update pregc information msg to the master core
147 if(BAMBOO_CHECK_SEND_MODE()) {
148 cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
149 self_numsendobjs, self_numreceiveobjs);
151 send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
152 self_numsendobjs, self_numreceiveobjs, true);
159 INLINE void processmsg_transtall_I() {
160 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE,0xe002);
162 int num_core = msgdata[msgdataindex];
164 int data2 = msgdata[msgdataindex];
166 int data3 = msgdata[msgdataindex];
168 if(num_core < NUMCORESACTIVE) {
169 corestatus[num_core] = 0;
170 numsendobjs[num_core] = data2;
171 numreceiveobjs[num_core] = data3;
176 INLINE void processmsg_lockrequest_I() {
177 // check to see if there is a lock exist for the required obj
178 // msgdata[1] -> lock type
179 int locktype = msgdata[msgdataindex];
181 int data2 = msgdata[msgdataindex]; // obj pointer
183 int data3 = msgdata[msgdataindex]; // lock
185 int data4 = msgdata[msgdataindex]; // request core
187 // -1: redirected, 0: approved, 1: denied
188 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
191 // for 32 bit machine, the size is always 4 words, cache the msg first
192 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
193 if(BAMBOO_CHECK_SEND_MODE()) {
194 cache_msg_4(data4, tmp, locktype, data2, data3);
196 send_msg_4(data4, tmp, locktype, data2, data3, true);
201 INLINE void processmsg_lockgrount_I() {
203 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1, 0xe202);
204 int data2 = msgdata[msgdataindex];
206 int data3 = msgdata[msgdataindex];
208 BAMBOO_ASSERT((lockobj == data2) && (lock2require == data3), 0xe203);
216 INLINE void processmsg_lockdeny_I() {
218 int data2 = msgdata[msgdataindex];
220 int data3 = msgdata[msgdataindex];
222 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1, 0xe204);
223 BAMBOO_ASSERT((lockobj == data2) && (lock2require == data3), 0xe205);
231 INLINE void processmsg_lockrelease_I() {
232 int data1 = msgdata[msgdataindex];
234 int data2 = msgdata[msgdataindex];
236 int data3 = msgdata[msgdataindex];
238 // receive lock release msg
239 processlockrelease(data1, data2, 0, false);
242 INLINE void processmsg_redirectlock_I() {
243 // check to see if there is a lock exist for the required obj
244 int data1 = msgdata[msgdataindex];
245 MSG_INDEXINC_I(); // lock type
246 int data2 = msgdata[msgdataindex];
247 MSG_INDEXINC_I(); // obj pointer
248 int data3 = msgdata[msgdataindex];
249 MSG_INDEXINC_I(); // redirect lock
250 int data4 = msgdata[msgdataindex];
251 MSG_INDEXINC_I(); // root request core
252 int data5 = msgdata[msgdataindex];
253 MSG_INDEXINC_I(); // request core
254 int deny = processlockrequest(data1, data3, data2, data5, data4, true);
257 // for 32 bit machine, the size is always 4 words, cache the msg first
258 if(BAMBOO_CHECK_SEND_MODE()) {
259 cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
260 data1, data2, data3);
262 send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
263 data1, data2, data3, true);
268 INLINE void processmsg_redirectgrount_I() {
270 int data2 = msgdata[msgdataindex];
272 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1, 0xe206);
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, 0x2e08);
291 BAMBOO_ASSERT(lockobj == data2, 0xe209);
299 INLINE void processmsg_redirectrelease_I() {
300 int data1 = msgdata[msgdataindex];
302 int data2 = msgdata[msgdataindex];
304 int data3 = msgdata[msgdataindex];
306 processlockrelease(data1, data2, data3, true);
308 #endif // #ifndef MULTICORE_GC
311 INLINE void processmsg_profileoutput_I() {
312 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE != STARTUPCORE, 0xe20a);
314 totalexetime = msgdata[msgdataindex];
320 // cache the msg first
321 if(BAMBOO_CHECK_SEND_MODE()) {
322 cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
324 send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
328 INLINE void processmsg_profilefinish_I() {
329 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE, 0xe20b);
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)), 0xe003);
339 // cache the msg first
340 if(BAMBOO_CHECK_SEND_MODE()) {
341 cache_msg_5(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,
342 self_numsendobjs, self_numreceiveobjs);
344 send_msg_5(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,
345 self_numsendobjs,self_numreceiveobjs, true);
349 INLINE void processmsg_statusreport_I() {
350 int data1 = msgdata[msgdataindex];
352 int data2 = msgdata[msgdataindex];
354 int data3 = msgdata[msgdataindex];
356 int data4 = msgdata[msgdataindex];
358 // receive a status confirm info
359 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE, 0xe004);
363 corestatus[data2] = data1;
364 numsendobjs[data2] = data3;
365 numreceiveobjs[data2] = data4;
368 INLINE void processmsg_terminate_I() {
371 #ifdef GC_CACHE_ADAPT
372 bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
378 INLINE void processmsg_memrequest_I() {
379 int data1 = msgdata[msgdataindex];
381 int data2 = msgdata[msgdataindex];
383 // receive a shared memory request msg
384 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE, 0xe005);
388 if(!gcprocessing || !gcflag) {
389 // either not doing GC or the master core has decided to stop GC but
390 // // still sending msgs to other cores to inform them to stop the GC
392 mem = smemalloc_I(data2, data1, &allocsize);
394 // send the start_va to request core, cache the msg first
395 if(BAMBOO_CHECK_SEND_MODE()) {
396 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
398 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
400 } //else if mem == NULL, the gcflag of the startup core has been set
401 // and all the other cores have been informed to start gc
407 INLINE void processmsg_memresponse_I() {
408 int data1 = msgdata[msgdataindex];
410 int data2 = msgdata[msgdataindex];
412 // receive a shared memory response msg
414 // if is currently doing gc, dump this msg
419 // Zero out the remaining memory here because for the GC_CACHE_ADAPT
420 // version, we need to make sure during the gcinit phase the shared heap
421 // is not touched. Otherwise, there would be problem when adapt the cache
423 BAMBOO_CLOSE_CUR_MSP();
424 bamboo_smem_zero_top = NULL;
426 bamboo_smem_size = 0;
430 CLOSEBLOCK(data1, data2);
431 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
432 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
433 bamboo_smem_zero_top = bamboo_cur_msp;
435 bamboo_smem_size = data2;
436 bamboo_cur_msp =(void*)(data1);
446 INLINE void processmsg_gcstartpre_I() {
447 // the first time to be informed to start gc
450 // Zero out the remaining memory here because for the GC_CACHE_ADAPT
451 // version, we need to make sure during the gcinit phase the shared heap
452 // is not touched. Otherwise, there would be problem when adapt the cache
454 BAMBOO_CLOSE_CUR_MSP();
455 bamboo_smem_size = 0;
456 bamboo_cur_msp = NULL;
458 bamboo_smem_zero_top = NULL;
462 INLINE void processmsg_gcstartinit_I() {
466 INLINE void processmsg_gcstart_I() {
471 INLINE void processmsg_gcstartcompact_I() {
472 gcblock2fill = msgdata[msgdataindex];
474 gcphase = COMPACTPHASE;
477 INLINE void processmsg_gcstartflush_I() {
478 gcphase = FLUSHPHASE;
481 INLINE void processmsg_gcfinishpre_I() {
482 int data1 = msgdata[msgdataindex];
484 int data2 = msgdata[msgdataindex];
486 int data3 = msgdata[msgdataindex];
488 // received a init phase finish msg
489 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE, 0xe006);
491 // All cores should do init GC
493 gccorestatus[data1] = 0;
494 gcnumsendobjs[0][data1] = data2;
495 gcnumreceiveobjs[0][data1] = data3;
498 INLINE void processmsg_gcfinishinit_I() {
499 int data1 = msgdata[msgdataindex];
501 // received a init phase finish msg
502 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE, 0xe007);
504 // All cores should do init GC
505 if(data1 < NUMCORESACTIVE) {
506 gccorestatus[data1] = 0;
510 INLINE void processmsg_gcfinishmark_I() {
511 int data1 = msgdata[msgdataindex];
513 int data2 = msgdata[msgdataindex];
515 int data3 = msgdata[msgdataindex];
517 // received a mark phase finish msg
518 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE, 0xe008);
520 // all cores should do mark
521 if(data1 < NUMCORESACTIVE) {
522 gccorestatus[data1] = 0;
526 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
529 entry_index = gcnumsrobjs_index;
531 gcnumsendobjs[entry_index][data1] = data2;
532 gcnumreceiveobjs[entry_index][data1] = data3;
536 INLINE void processmsg_gcfinishcompact_I() {
537 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE, 0xe009);
539 int cnum = msgdata[msgdataindex];
541 int filledblocks = msgdata[msgdataindex];
543 int heaptop = msgdata[msgdataindex];
545 int data4 = msgdata[msgdataindex];
547 // only gc cores need to do compact
548 if(cnum < NUMCORES4GC) {
549 if(COMPACTPHASE == gcphase) {
550 gcfilledblocks[cnum] = filledblocks;
551 gcloads[cnum] = heaptop;
558 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
559 // cache the msg first
560 if(BAMBOO_CHECK_SEND_MODE()) {
561 cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
563 send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
567 gccorestatus[cnum] = 0;
572 INLINE void processmsg_gcfinishflush_I() {
573 int data1 = msgdata[msgdataindex];
575 // received a flush phase finish msg
576 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE, 0xe00a);
578 // all cores should do flush
579 if(data1 < NUMCORESACTIVE) {
580 gccorestatus[data1] = 0;
584 INLINE void processmsg_gcfinish_I() {
585 // received a GC finish msg
586 gcphase = FINISHPHASE;
587 gcprocessing = false;
590 INLINE void processmsg_gcmarkconfirm_I() {
591 BAMBOO_ASSERT(((BAMBOO_NUM_OF_CORE!=STARTUPCORE)&&(BAMBOO_NUM_OF_CORE<=NUMCORESACTIVE-1)), 0xe00b);
592 gcbusystatus = gc_moreItems2_I();
593 // send response msg, cahce the msg first
594 if(BAMBOO_CHECK_SEND_MODE()) {
595 cache_msg_5(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gcbusystatus,
596 gcself_numsendobjs,gcself_numreceiveobjs);
598 send_msg_5(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gcbusystatus,
599 gcself_numsendobjs,gcself_numreceiveobjs, true);
603 INLINE void processmsg_gcmarkreport_I() {
604 int data1 = msgdata[msgdataindex];
606 int data2 = msgdata[msgdataindex];
608 int data3 = msgdata[msgdataindex];
610 int data4 = msgdata[msgdataindex];
612 // received a marked phase finish confirm response msg
613 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE, 0xe00c);
615 BAMBOO_ASSERT(waitconfirm, 0xe00d);
619 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
620 gccorestatus[data1] = data2;
621 gcnumsendobjs[entry_index][data1] = data3;
622 gcnumreceiveobjs[entry_index][data1] = data4;
626 INLINE void processmsg_gcmarkedobj_I() {
627 int data1 = msgdata[msgdataindex];
629 BAMBOO_ASSERT(ISSHAREDOBJ(data1), 0xa0000000+(int)data1);
631 // received a markedObj msg
632 if(((struct ___Object___ *)data1)->marked == INIT) {
633 // this is the first time that this object is discovered,
634 // set the flag as DISCOVERED
635 ((struct ___Object___ *)data1)->marked = DISCOVERED;
638 gcself_numreceiveobjs++;
642 INLINE void processmsg_gcmovestart_I() {
644 gcdstcore = msgdata[msgdataindex];
646 gcmovestartaddr = msgdata[msgdataindex];
648 gcblock2fill = msgdata[msgdataindex];
652 INLINE void processmsg_gclobjinfo_I() {
654 int data1 = msgdata[msgdataindex];
656 int data2 = msgdata[msgdataindex];
658 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORES4GC - 1, 0xe00e);
660 // store the mark result info
662 gcloads[cnum] = msgdata[msgdataindex];
664 int data4 = msgdata[msgdataindex];
666 if(gcheaptop < data4) {
669 // large obj info here
670 for(int k = 5; k < data1; k+=2) {
671 int lobj = msgdata[msgdataindex];
673 int length = msgdata[msgdataindex];
675 gc_lobjenqueue_I(lobj, length, cnum);
681 INLINE void processmsg_gcprofiles_I() {
682 int data1 = msgdata[msgdataindex];
684 int data2 = msgdata[msgdataindex];
686 int data3 = msgdata[msgdataindex];
689 if(gc_profile_flag) {
692 gc_num_liveobj += data2;
693 gc_num_forwardobj += data3;
701 #ifdef GC_CACHE_ADAPT
702 INLINE void processmsg_gcstartpref_I() {
703 gcphase = PREFINISHPHASE;
706 INLINE void processmsg_gcfinishpref_I() {
707 int data1 = msgdata[msgdataindex];
709 // received a flush phase finish msg
710 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE, 0xe00f);
712 // all cores should do flush
713 if(data1 < NUMCORESACTIVE) {
714 gccorestatus[data1] = 0;
717 #endif // GC_CACHE_ADAPT
718 #endif // #ifdef MULTICORE_GC
720 // receive object transferred from other cores
721 // or the terminate message from other cores
722 // Should be invoked in critical sections!!
723 // NOTICE: following format is for threadsimulate version only
724 // RAW version please see previous description
725 // format: type + object
726 // type: -1--stall msg
728 // return value: 0--received an object
729 // 1--received nothing
730 // 2--received a Stall Msg
731 // 3--received a lock Msg
732 // RAW version: -1 -- received nothing
733 // otherwise -- received msg type
734 int receiveObject(int send_port_pending) {
735 PROFILE_INTERRUPT_START();
737 // get the incoming msgs
738 if(receiveMsg(send_port_pending) == -1) {
741 if(BAMBOO_CHECK_SEND_MODE()) {
742 // during send, don't process the msg now
746 // processing received msgs
748 MSG_REMAINSIZE_I(&size);
749 if((size == 0) || (checkMsgLength_I(size) == -1)) {
751 // have new coming msg
752 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
759 if(msglength <= size) {
760 // have some whole msg
762 type = msgdata[msgdataindex]; //[0]
768 // receive a object transfer msg
769 processmsg_transobj_I();
774 // receive a stall msg
775 processmsg_transtall_I();
780 // GC version have no lock msgs
783 // receive lock request msg, handle it right now
784 processmsg_lockrequest_I();
788 // receive lock grount msg
789 processmsg_lockgrount_I();
793 // receive lock deny msg
794 processmsg_lockdeny_I();
798 processmsg_lockrelease_I();
804 case PROFILEOUTPUT: {
805 // receive an output profile data request msg
806 processmsg_profileoutput_I();
809 case PROFILEFINISH: {
810 // receive a profile output finish msg
811 processmsg_profilefinish_I();
816 // GC version has no lock msgs
819 // receive a redirect lock request msg, handle it right now
820 processmsg_redirectlock_I();
824 case REDIRECTGROUNT: {
825 // receive a lock grant msg with redirect info
826 processmsg_redirectgrount_I();
831 // receive a lock deny msg with redirect info
832 processmsg_redirectdeny_I();
836 case REDIRECTRELEASE: {
837 // receive a lock release msg with redirect info
838 processmsg_redirectrelease_I();
840 } // case REDIRECTRELEASE
844 case STATUSCONFIRM: {
845 // receive a status confirm info
846 processmsg_statusconfirm_I();
851 processmsg_statusreport_I();
856 // receive a terminate msg
857 processmsg_terminate_I();
862 processmsg_memrequest_I();
867 processmsg_memresponse_I();
874 processmsg_gcstartpre_I();
879 processmsg_gcstartinit_I();
884 // receive a start GC msg
885 processmsg_gcstart_I();
889 case GCSTARTCOMPACT: {
890 // a compact phase start msg
891 processmsg_gcstartcompact_I();
896 // received a flush phase start msg
897 processmsg_gcstartflush_I();
902 processmsg_gcfinishpre_I();
907 processmsg_gcfinishinit_I();
912 processmsg_gcfinishmark_I();
916 case GCFINISHCOMPACT: {
917 // received a compact phase finish msg
918 processmsg_gcfinishcompact_I();
922 case GCFINISHFLUSH: {
923 processmsg_gcfinishflush_I();
928 processmsg_gcfinish_I();
932 case GCMARKCONFIRM: {
933 // received a marked phase finish confirm request msg
934 // all cores should do mark
935 processmsg_gcmarkconfirm_I();
940 processmsg_gcmarkreport_I();
945 processmsg_gcmarkedobj_I();
950 // received a start moving objs msg
951 processmsg_gcmovestart_I();
955 case GCLOBJREQUEST: {
956 // received a large objs info request msg
957 transferMarkResults_I();
962 // received a large objs info response msg
963 processmsg_gclobjinfo_I();
969 // received a gcprofiles msg
970 processmsg_gcprofiles_I();
975 #ifdef GC_CACHE_ADAPT
977 // received a gcstartpref msg
978 processmsg_gcstartpref_I();
983 // received a gcfinishpref msg
984 processmsg_gcfinishpref_I();
993 msglength = BAMBOO_MSG_BUF_LENGTH;
995 if((msgdataindex != msgdatalast) || (msgdatafull)) {
996 // still have available msg
1000 // have new coming msg
1001 if(BAMBOO_MSG_AVAIL() != 0) {
1005 PROFILE_INTERRUPT_END();