2 #include "multicoremsg.h"
4 #include "multicoreruntime.h"
5 #include "multicoretaskprofile.h"
8 #include "structdefs.h"
9 #include "runtime_arch.h"
14 int msgsizearray[] = {
16 -1, //TRANSOBJ, // 0xD1
17 4, //TRANSTALL, // 0xD2
18 5, //LOCKREQUEST, // 0xD3
19 4, //LOCKGROUNT, // 0xD4
20 4, //LOCKDENY, // 0xD5
21 4, //LOCKRELEASE, // 0xD6
22 2, //PROFILEOUTPUT, // 0xD7
23 2, //PROFILEFINISH, // 0xD8
24 6, //REDIRECTLOCK, // 0xD9
25 4, //REDIRECTGROUNT, // 0xDa
26 4, //REDIRECTDENY, // 0xDb
27 4, //REDIRECTRELEASE, // 0xDc
28 1, //STATUSCONFIRM, // 0xDd
29 5, //STATUSREPORT, // 0xDe
30 1, //TERMINATE, // 0xDf
31 3, //MEMREQUEST, // 0xE0
32 3, //MEMRESPONSE, // 0xE1
34 1, //GCSTARTPRE, // 0xE2
35 1, //GCSTARTINIT, // 0xE3
37 2, //GCSTARTCOMPACT, // 0xE5
38 1, //GCSTARTFLUSH, // 0xE6
39 4, //GCFINISHPRE, // 0xE7
40 2, //GCFINISHINIT, // 0xE8
41 4, //GCFINISHMARK, // 0xE9
42 5, //GCFINISHCOMPACT, // 0xEa
43 2, //GCFINISHFLUSH, // 0xEb
44 1, //GCFINISH, // 0xEc
45 1, //GCMARKCONFIRM, // 0xEd
46 5, //GCMARKREPORT, // 0xEe
47 2, //GCMARKEDOBJ, // 0xEf
48 4, //GCMOVESTART, // 0xF0
49 1, //GCLOBJREQUEST, // 0xF1
50 -1, //GCLOBJINFO, // 0xF2
52 4, //GCPROFILES, // 0xF3
55 1, //GCSTARTPREF, // 0xF5
56 2, //GCFINISHPREF, // 0xF7
57 #endif // GC_CACHE_ADAPT
58 #endif // MULTICORE_GC
62 INLINE unsigned int checkMsgLength_I(unsigned int * type) {
63 #if (defined(TASK)||defined(MULTICORE_GC))
64 unsigned int realtype = msgdata[msgdataindex];
67 *type = msgdata[msgdataindex];
75 if(*type==TRANSOBJ||*type==GCLOBJINFO) {
80 if (*type==GCLOBJINFO) {
82 #if (defined(TASK)||defined(MULTICORE_GC))
86 return msgsizearray[*type];
90 INLINE void processmsg_transobj_I(int msglength) {
91 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
92 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
94 // store the object and its corresponding queue info, enqueue it later
95 transObj->objptr = (void *)msgdata[msgdataindex];
97 transObj->length = (msglength - 2) / 2;
98 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
99 for(int k = 0; k < transObj->length; k++) {
100 transObj->queues[2*k] = msgdata[msgdataindex];
102 transObj->queues[2*k+1] = msgdata[msgdataindex];
105 // check if there is an existing duplicate item
106 struct QueueItem * prev = NULL;
107 for(struct QueueItem * qitem = getHead(&objqueue);qitem != NULL;qitem=(prev==NULL)?getHead(&objqueue):getNextQueueItem(prev)) {
108 struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
109 if(tmpinfo->objptr == transObj->objptr) {
110 // the same object, remove outdate one
111 RUNFREE_I(tmpinfo->queues);
113 removeItem(&objqueue, qitem);
119 addNewItem_I(&objqueue, (void *)transObj);
121 self_numreceiveobjs++;
124 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
125 // set the gcprecheck to enable checking again
128 // send a update pregc information msg to the master core
129 if(BAMBOO_CHECK_SEND_MODE()) {
130 cache_msg_4_I(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
132 send_msg_4_I(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs, self_numreceiveobjs);
140 INLINE void processmsg_transtall_I() {
141 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
143 int num_core = msgdata[msgdataindex];
145 int data2 = msgdata[msgdataindex];
147 int data3 = msgdata[msgdataindex];
149 if(num_core < NUMCORESACTIVE) {
150 corestatus[num_core] = 0;
151 numsendobjs[num_core] = data2;
152 numreceiveobjs[num_core] = data3;
157 INLINE void processmsg_lockrequest_I() {
158 // check to see if there is a lock exist for the required obj
159 // msgdata[1] -> lock type
160 int locktype = msgdata[msgdataindex];
162 int data2 = msgdata[msgdataindex]; // obj pointer
164 int data3 = msgdata[msgdataindex]; // lock
166 int data4 = msgdata[msgdataindex]; // request core
168 // -1: redirected, 0: approved, 1: denied
169 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
172 // for 32 bit machine, the size is always 4 words, cache the msg first
173 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
174 if(BAMBOO_CHECK_SEND_MODE()) {
175 cache_msg_4_I(data4,tmp,locktype,data2,data3);
177 send_msg_4_I(data4,tmp,locktype,data2,data3);
182 INLINE void processmsg_lockgrount_I() {
184 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
185 int data2 = msgdata[msgdataindex];
187 int data3 = msgdata[msgdataindex];
189 BAMBOO_ASSERT((lockobj == data2) && (lock2require == data3));
197 INLINE void processmsg_lockdeny_I() {
199 int data2 = msgdata[msgdataindex];
201 int data3 = msgdata[msgdataindex];
203 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
204 BAMBOO_ASSERT((lockobj == data2) && (lock2require == data3));
212 INLINE void processmsg_lockrelease_I() {
213 int data1 = msgdata[msgdataindex];
215 int data2 = msgdata[msgdataindex];
217 int data3 = msgdata[msgdataindex];
219 // receive lock release msg
220 processlockrelease(data1, data2, 0, false);
223 INLINE void processmsg_redirectlock_I() {
224 // check to see if there is a lock exist for the required obj
225 int data1 = msgdata[msgdataindex];
226 MSG_INDEXINC_I(); // lock type
227 int data2 = msgdata[msgdataindex];
228 MSG_INDEXINC_I(); // obj pointer
229 int data3 = msgdata[msgdataindex];
230 MSG_INDEXINC_I(); // redirect lock
231 int data4 = msgdata[msgdataindex];
232 MSG_INDEXINC_I(); // root request core
233 int data5 = msgdata[msgdataindex];
234 MSG_INDEXINC_I(); // request core
235 int deny = processlockrequest_I(data1, data3, data2, data5, data4, true);
238 // for 32 bit machine, the size is always 4 words, cache the msg first
239 if(BAMBOO_CHECK_SEND_MODE()) {
240 cache_msg_4_I(data4,deny==1?REDIRECTDENY:REDIRECTGROUNT,data1,data2,data3);
242 send_msg_4_I(data4,deny==1?REDIRECTDENY:REDIRECTGROUNT,data1,data2,data3);
247 INLINE void processmsg_redirectgrount_I() {
249 int data2 = msgdata[msgdataindex];
251 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
252 BAMBOO_ASSERT(lockobj == data2, 0xe207);
253 int data3 = msgdata[msgdataindex];
257 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
263 INLINE void processmsg_redirectdeny_I() {
265 int data2 = msgdata[msgdataindex];
267 int data3 = msgdata[msgdataindex];
269 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
270 BAMBOO_ASSERT(lockobj == data2);
278 INLINE void processmsg_redirectrelease_I() {
279 int data1 = msgdata[msgdataindex];
281 int data2 = msgdata[msgdataindex];
283 int data3 = msgdata[msgdataindex];
285 processlockrelease_I(data1, data2, data3, true);
287 #endif // #ifndef MULTICORE_GC
290 INLINE void processmsg_profileoutput_I() {
291 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE != STARTUPCORE);
293 totalexetime = msgdata[msgdataindex];
299 // cache the msg first
300 if(BAMBOO_CHECK_SEND_MODE()) {
301 cache_msg_2_I(STARTUPCORE,PROFILEFINISH,BAMBOO_NUM_OF_CORE);
303 send_msg_2_I(STARTUPCORE,PROFILEFINISH,BAMBOO_NUM_OF_CORE);
307 INLINE void processmsg_profilefinish_I() {
308 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
309 int data1 = msgdata[msgdataindex];
311 profilestatus[data1] = 0;
315 INLINE void processmsg_statusconfirm_I() {
316 BAMBOO_ASSERT(((BAMBOO_NUM_OF_CORE != STARTUPCORE) && (BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1)));
318 // cache the msg first
319 if(BAMBOO_CHECK_SEND_MODE()) {
320 cache_msg_5_I(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
322 send_msg_5_I(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
326 INLINE void processmsg_statusreport_I() {
327 int data1 = msgdata[msgdataindex];
329 int data2 = msgdata[msgdataindex];
331 int data3 = msgdata[msgdataindex];
333 int data4 = msgdata[msgdataindex];
335 // receive a status confirm info
336 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
340 corestatus[data2] = data1;
341 numsendobjs[data2] = data3;
342 numreceiveobjs[data2] = data4;
345 INLINE void processmsg_terminate_I() {
348 #ifdef GC_CACHE_ADAPT
349 bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
355 INLINE void processmsg_memrequest_I() {
356 int data1 = msgdata[msgdataindex];
358 int data2 = msgdata[msgdataindex];
360 // receive a shared memory request msg
361 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
365 if(!gcprocessing || !gcflag) {
366 // either not doing GC or the master core has decided to stop GC but
367 // // still sending msgs to other cores to inform them to stop the GC
369 mem = smemalloc_I(data2, data1, &allocsize);
371 // send the start_va to request core, cache the msg first
372 if(BAMBOO_CHECK_SEND_MODE()) {
373 cache_msg_3_I(data2,MEMRESPONSE,mem,allocsize);
375 send_msg_3_I(data2,MEMRESPONSE,mem,allocsize);
377 } //else if mem == NULL, the gcflag of the startup core has been set
378 // and all the other cores have been informed to start gc
384 INLINE void processmsg_memresponse_I() {
385 int data1 = msgdata[msgdataindex];
387 int data2 = msgdata[msgdataindex];
389 // receive a shared memory response msg
391 // if is currently doing gc, dump this msg
396 // Zero out the remaining memory here because for the GC_CACHE_ADAPT
397 // version, we need to make sure during the gcinit phase the shared heap
398 // is not touched. Otherwise, there would be problem when adapt the cache
400 BAMBOO_CLOSE_CUR_MSP();
401 bamboo_smem_zero_top = NULL;
403 bamboo_smem_size = 0;
407 CLOSEBLOCK(data1, data2);
408 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
409 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
410 bamboo_smem_zero_top = bamboo_cur_msp;
412 bamboo_smem_size = data2;
413 bamboo_cur_msp =(void*)(data1);
423 INLINE void processmsg_gcstartpre_I() {
424 // the first time to be informed to start gc
427 // Zero out the remaining memory here because for the GC_CACHE_ADAPT
428 // version, we need to make sure during the gcinit phase the shared heap
429 // is not touched. Otherwise, there would be problem when adapt the cache
431 BAMBOO_CLOSE_CUR_MSP();
432 bamboo_smem_size = 0;
433 bamboo_cur_msp = NULL;
435 bamboo_smem_zero_top = NULL;
439 INLINE void processmsg_gcstartinit_I() {
443 INLINE void processmsg_gcstart_I() {
448 INLINE void processmsg_gcstartcompact_I() {
449 gcblock2fill = msgdata[msgdataindex];
451 gcphase = COMPACTPHASE;
454 INLINE void processmsg_gcstartflush_I() {
455 gcphase = FLUSHPHASE;
458 INLINE void processmsg_gcfinishpre_I() {
459 int data1 = msgdata[msgdataindex];
461 int data2 = msgdata[msgdataindex];
463 int data3 = msgdata[msgdataindex];
465 // received a init phase finish msg
466 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
468 // All cores should do init GC
470 gccorestatus[data1] = 0;
471 gcnumsendobjs[0][data1] = data2;
472 gcnumreceiveobjs[0][data1] = data3;
475 INLINE void processmsg_gcfinishinit_I() {
476 int data1 = msgdata[msgdataindex];
478 // received a init phase finish msg
479 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
481 // All cores should do init GC
482 if(data1 < NUMCORESACTIVE) {
483 gccorestatus[data1] = 0;
487 INLINE void processmsg_gcfinishmark_I() {
488 int data1 = msgdata[msgdataindex];
490 int data2 = msgdata[msgdataindex];
492 int data3 = msgdata[msgdataindex];
494 // received a mark phase finish msg
495 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
497 // all cores should do mark
498 if(data1 < NUMCORESACTIVE) {
499 gccorestatus[data1] = 0;
503 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
506 entry_index = gcnumsrobjs_index;
508 gcnumsendobjs[entry_index][data1] = data2;
509 gcnumreceiveobjs[entry_index][data1] = data3;
513 INLINE void processmsg_gcfinishcompact_I() {
514 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
516 int cnum = msgdata[msgdataindex];
518 int filledblocks = msgdata[msgdataindex];
520 int heaptop = msgdata[msgdataindex];
522 int data4 = msgdata[msgdataindex];
524 // only gc cores need to do compact
525 if(cnum < NUMCORES4GC) {
526 if(COMPACTPHASE == gcphase) {
527 gcfilledblocks[cnum] = filledblocks;
528 gcloads[cnum] = heaptop;
535 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
536 // cache the msg first
537 if(BAMBOO_CHECK_SEND_MODE()) {
538 cache_msg_4_I(cnum,GCMOVESTART,dstcore,startaddr,tomove);
540 send_msg_4_I(cnum,GCMOVESTART,dstcore,startaddr,tomove);
544 gccorestatus[cnum] = 0;
549 INLINE void processmsg_gcfinishflush_I() {
550 int data1 = msgdata[msgdataindex];
552 // received a flush phase finish msg
553 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
555 // all cores should do flush
556 if(data1 < NUMCORESACTIVE) {
557 gccorestatus[data1] = 0;
561 INLINE void processmsg_gcfinish_I() {
562 // received a GC finish msg
563 gcphase = FINISHPHASE;
564 gcprocessing = false;
567 INLINE void processmsg_gcmarkconfirm_I() {
568 BAMBOO_ASSERT(((BAMBOO_NUM_OF_CORE!=STARTUPCORE)&&(BAMBOO_NUM_OF_CORE<=NUMCORESACTIVE-1)));
569 gcbusystatus = gc_moreItems2_I();
570 // send response msg, cahce the msg first
571 if(BAMBOO_CHECK_SEND_MODE()) {
572 cache_msg_5_I(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gcbusystatus,gcself_numsendobjs,gcself_numreceiveobjs);
574 send_msg_5_I(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gcbusystatus,gcself_numsendobjs,gcself_numreceiveobjs);
578 INLINE void processmsg_gcmarkreport_I() {
579 int data1 = msgdata[msgdataindex];
581 int data2 = msgdata[msgdataindex];
583 int data3 = msgdata[msgdataindex];
585 int data4 = msgdata[msgdataindex];
587 // received a marked phase finish confirm response msg
588 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
590 BAMBOO_ASSERT(waitconfirm);
594 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
595 gccorestatus[data1] = data2;
596 gcnumsendobjs[entry_index][data1] = data3;
597 gcnumreceiveobjs[entry_index][data1] = data4;
601 INLINE void processmsg_gcmarkedobj_I() {
602 int data1 = msgdata[msgdataindex];
604 BAMBOO_ASSERT(ISSHAREDOBJ(data1));
606 // received a markedObj msg
607 if(((struct ___Object___ *)data1)->marked == INIT) {
608 // this is the first time that this object is discovered,
609 // set the flag as DISCOVERED
610 ((struct ___Object___ *)data1)->marked = DISCOVERED;
613 gcself_numreceiveobjs++;
617 INLINE void processmsg_gcmovestart_I() {
619 gcdstcore = msgdata[msgdataindex];
621 gcmovestartaddr = msgdata[msgdataindex];
623 gcblock2fill = msgdata[msgdataindex];
627 INLINE void processmsg_gclobjinfo_I(unsigned int data1) {
629 int data2 = msgdata[msgdataindex];
631 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORES4GC - 1);
633 // store the mark result info
635 gcloads[cnum] = msgdata[msgdataindex];
637 int data4 = msgdata[msgdataindex];
639 if(gcheaptop < data4) {
642 // large obj info here
643 for(int k = 4; k < data1; k+=2) {
644 int lobj = msgdata[msgdataindex];
646 int length = msgdata[msgdataindex];
648 gc_lobjenqueue_I(lobj, length, cnum);
654 INLINE void processmsg_gcprofiles_I() {
655 int data1 = msgdata[msgdataindex];
657 int data2 = msgdata[msgdataindex];
659 int data3 = msgdata[msgdataindex];
662 if(gc_profile_flag) {
665 gc_num_liveobj += data2;
666 gc_num_forwardobj += data3;
674 #ifdef GC_CACHE_ADAPT
675 INLINE void processmsg_gcstartpref_I() {
676 gcphase = PREFINISHPHASE;
679 INLINE void processmsg_gcfinishpref_I() {
680 int data1 = msgdata[msgdataindex];
682 // received a flush phase finish msg
683 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
685 // all cores should do flush
686 if(data1 < NUMCORESACTIVE) {
687 gccorestatus[data1] = 0;
690 #endif // GC_CACHE_ADAPT
691 #endif // #ifdef MULTICORE_GC
693 // receive object transferred from other cores
694 // or the terminate message from other cores
695 // Should be invoked in critical sections!!
696 // NOTICE: following format is for threadsimulate version only
697 // RAW version please see previous description
698 // format: type + object
699 // type: -1--stall msg
701 // return value: 0--received an object
702 // 1--received nothing
703 // 2--received a Stall Msg
704 // 3--received a lock Msg
705 // RAW version: -1 -- received nothing
706 // otherwise -- received msg type
707 int receiveObject_I() {
708 PROFILE_INTERRUPT_START();
710 // get the incoming msgs
712 if((msgdataindex == msgdatalast) && (!msgdatafull)) {
715 if(BAMBOO_CHECK_SEND_MODE()) {
716 // during send, don't process the msg now
720 // processing received msgs
722 MSG_REMAINSIZE_I(&size);
725 // have new coming msg
726 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
733 //we only ever read the first word
735 unsigned int msglength = checkMsgLength_I((unsigned int*)(&type));
737 if(msglength <= size) {
738 // have some whole msg
744 // receive a object transfer msg
745 processmsg_transobj_I(msglength);
750 // receive a stall msg
751 processmsg_transtall_I();
756 // GC version have no lock msgs
759 // receive lock request msg, handle it right now
760 processmsg_lockrequest_I();
764 // receive lock grount msg
765 processmsg_lockgrount_I();
769 // receive lock deny msg
770 processmsg_lockdeny_I();
774 processmsg_lockrelease_I();
780 case PROFILEOUTPUT: {
781 // receive an output profile data request msg
782 processmsg_profileoutput_I();
785 case PROFILEFINISH: {
786 // receive a profile output finish msg
787 processmsg_profilefinish_I();
792 // GC version has no lock msgs
795 // receive a redirect lock request msg, handle it right now
796 processmsg_redirectlock_I();
800 case REDIRECTGROUNT: {
801 // receive a lock grant msg with redirect info
802 processmsg_redirectgrount_I();
807 // receive a lock deny msg with redirect info
808 processmsg_redirectdeny_I();
812 case REDIRECTRELEASE: {
813 // receive a lock release msg with redirect info
814 processmsg_redirectrelease_I();
816 } // case REDIRECTRELEASE
820 case STATUSCONFIRM: {
821 // receive a status confirm info
822 processmsg_statusconfirm_I();
827 processmsg_statusreport_I();
832 // receive a terminate msg
833 processmsg_terminate_I();
838 processmsg_memrequest_I();
843 processmsg_memresponse_I();
850 processmsg_gcstartpre_I();
855 processmsg_gcstartinit_I();
860 // receive a start GC msg
861 processmsg_gcstart_I();
865 case GCSTARTCOMPACT: {
866 // a compact phase start msg
867 processmsg_gcstartcompact_I();
872 // received a flush phase start msg
873 processmsg_gcstartflush_I();
878 processmsg_gcfinishpre_I();
883 processmsg_gcfinishinit_I();
888 processmsg_gcfinishmark_I();
892 case GCFINISHCOMPACT: {
893 // received a compact phase finish msg
894 processmsg_gcfinishcompact_I();
898 case GCFINISHFLUSH: {
899 processmsg_gcfinishflush_I();
904 processmsg_gcfinish_I();
908 case GCMARKCONFIRM: {
909 // received a marked phase finish confirm request msg
910 // all cores should do mark
911 processmsg_gcmarkconfirm_I();
916 processmsg_gcmarkreport_I();
921 processmsg_gcmarkedobj_I();
926 // received a start moving objs msg
927 processmsg_gcmovestart_I();
931 case GCLOBJREQUEST: {
932 // received a large objs info request msg
933 transferMarkResults_I();
938 // received a large objs info response msg
939 processmsg_gclobjinfo_I(msglength);
945 // received a gcprofiles msg
946 processmsg_gcprofiles_I();
951 #ifdef GC_CACHE_ADAPT
953 // received a gcstartpref msg
954 processmsg_gcstartpref_I();
959 // received a gcfinishpref msg
960 processmsg_gcfinishpref_I();
970 if((msgdataindex != msgdatalast) || (msgdatafull)) {
971 // still have available msg
975 // have new coming msg
976 if(BAMBOO_MSG_AVAIL() != 0) {
980 PROFILE_INTERRUPT_END();