2 #include "multicoremsg.h"
4 #include "multicoreruntime.h"
5 #include "multicoretaskprofile.h"
10 -1, //TRANSOBJ, // 0xD1
11 4, //TRANSTALL, // 0xD2
12 5, //LOCKREQUEST, // 0xD3
13 4, //LOCKGROUNT, // 0xD4
14 4, //LOCKDENY, // 0xD5
15 4, //LOCKRELEASE, // 0xD6
16 2, //PROFILEOUTPUT, // 0xD7
17 2, //PROFILEFINISH, // 0xD8
18 6, //REDIRECTLOCK, // 0xD9
19 4, //REDIRECTGROUNT, // 0xDa
20 4, //REDIRECTDENY, // 0xDb
21 4, //REDIRECTRELEASE, // 0xDc
22 1, //STATUSCONFIRM, // 0xDd
23 5, //STATUSREPORT, // 0xDe
24 1, //TERMINATE, // 0xDf
25 3, //MEMREQUEST, // 0xE0
26 3, //MEMRESPONSE, // 0xE1
28 1, //GCSTARTPRE, // 0xE2
29 1, //GCSTARTINIT, // 0xE3
31 2, //GCSTARTCOMPACT, // 0xE5
32 1, //GCSTARTFLUSH, // 0xE6
33 4, //GCFINISHPRE, // 0xE7
34 2, //GCFINISHINIT, // 0xE8
35 4, //GCFINISHMARK, // 0xE9
36 5, //GCFINISHCOMPACT, // 0xEa
37 2, //GCFINISHFLUSH, // 0xEb
38 1, //GCFINISH, // 0xEc
39 1, //GCMARKCONFIRM, // 0xEd
40 5, //GCMARKREPORT, // 0xEe
41 2, //GCMARKEDOBJ, // 0xEf
42 4, //GCMOVESTART, // 0xF0
43 1, //GCLOBJREQUEST, // 0xF1
44 -1, //GCLOBJINFO, // 0xF2
46 4, //GCPROFILES, // 0xF3
49 1, //GCSTARTPREF, // 0xF5
50 2, //GCFINISHPREF, // 0xF7
51 #endif // GC_CACHE_ADAPT
52 #endif // MULTICORE_GC
56 INLINE unsigned int checkMsgLength_I(unsigned int * type) {
57 #if (defined(TASK)||defined(MULTICORE_GC))
58 unsigned int realtype = msgdata[msgdataindex];
61 *type = msgdata[msgdataindex];
69 if(*type==TRANSOBJ||*type==GCLOBJINFO) {
74 if (*type==GCLOBJINFO) {
76 #if (defined(TASK)||defined(MULTICORE_GC))
80 return msgsizearray[*type];
83 INLINE void processmsg_transobj_I(int msglength) {
84 struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
85 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
87 // store the object and its corresponding queue info, enqueue it later
88 transObj->objptr = (void *)msgdata[msgdataindex];
90 transObj->length = (msglength - 2) / 2;
91 transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
92 for(int k = 0; k < transObj->length; k++) {
93 transObj->queues[2*k] = msgdata[msgdataindex];
95 transObj->queues[2*k+1] = msgdata[msgdataindex];
98 // check if there is an existing duplicate item
99 struct QueueItem * prev = NULL;
100 for(struct QueueItem * qitem = getHead(&objqueue);qitem != NULL;qitem=(prev==NULL)?getHead(&objqueue):getNextQueueItem(prev)) {
101 struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
102 if(tmpinfo->objptr == transObj->objptr) {
103 // the same object, remove outdate one
104 RUNFREE_I(tmpinfo->queues);
106 removeItem(&objqueue, qitem);
112 addNewItem_I(&objqueue, (void *)transObj);
114 self_numreceiveobjs++;
117 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
118 // set the gcprecheck to enable checking again
121 // send a update pregc information msg to the master core
122 if(BAMBOO_CHECK_SEND_MODE()) {
123 cache_msg_4_I(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
125 send_msg_4_I(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs, self_numreceiveobjs);
132 INLINE void processmsg_transtall_I() {
133 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
135 int num_core = msgdata[msgdataindex];
137 int data2 = msgdata[msgdataindex];
139 int data3 = msgdata[msgdataindex];
141 if(num_core < NUMCORESACTIVE) {
142 corestatus[num_core] = 0;
143 numsendobjs[num_core] = data2;
144 numreceiveobjs[num_core] = data3;
149 INLINE void processmsg_lockrequest_I() {
150 // check to see if there is a lock exist for the required obj
151 // msgdata[1] -> lock type
152 int locktype = msgdata[msgdataindex];
154 int data2 = msgdata[msgdataindex]; // obj pointer
156 int data3 = msgdata[msgdataindex]; // lock
158 int data4 = msgdata[msgdataindex]; // request core
160 // -1: redirected, 0: approved, 1: denied
161 int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
164 // for 32 bit machine, the size is always 4 words, cache the msg first
165 int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
166 if(BAMBOO_CHECK_SEND_MODE()) {
167 cache_msg_4_I(data4,tmp,locktype,data2,data3);
169 send_msg_4_I(data4,tmp,locktype,data2,data3);
174 INLINE void processmsg_lockgrount_I() {
176 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
177 int data2 = msgdata[msgdataindex];
179 int data3 = msgdata[msgdataindex];
181 BAMBOO_ASSERT((lockobj == data2) && (lock2require == data3));
189 INLINE void processmsg_lockdeny_I() {
191 int data2 = msgdata[msgdataindex];
193 int data3 = msgdata[msgdataindex];
195 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
196 BAMBOO_ASSERT((lockobj == data2) && (lock2require == data3));
204 INLINE void processmsg_lockrelease_I() {
205 int data1 = msgdata[msgdataindex];
207 int data2 = msgdata[msgdataindex];
209 int data3 = msgdata[msgdataindex];
211 // receive lock release msg
212 processlockrelease(data1, data2, 0, false);
215 INLINE void processmsg_redirectlock_I() {
216 // check to see if there is a lock exist for the required obj
217 int data1 = msgdata[msgdataindex];
218 MSG_INDEXINC_I(); // lock type
219 int data2 = msgdata[msgdataindex];
220 MSG_INDEXINC_I(); // obj pointer
221 int data3 = msgdata[msgdataindex];
222 MSG_INDEXINC_I(); // redirect lock
223 int data4 = msgdata[msgdataindex];
224 MSG_INDEXINC_I(); // root request core
225 int data5 = msgdata[msgdataindex];
226 MSG_INDEXINC_I(); // request core
227 int deny = processlockrequest_I(data1, data3, data2, data5, data4, true);
230 // for 32 bit machine, the size is always 4 words, cache the msg first
231 if(BAMBOO_CHECK_SEND_MODE()) {
232 cache_msg_4_I(data4,deny==1?REDIRECTDENY:REDIRECTGROUNT,data1,data2,data3);
234 send_msg_4_I(data4,deny==1?REDIRECTDENY:REDIRECTGROUNT,data1,data2,data3);
239 INLINE void processmsg_redirectgrount_I() {
241 int data2 = msgdata[msgdataindex];
243 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
244 BAMBOO_ASSERT(lockobj == data2, 0xe207);
245 int data3 = msgdata[msgdataindex];
249 RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
255 INLINE void processmsg_redirectdeny_I() {
257 int data2 = msgdata[msgdataindex];
259 int data3 = msgdata[msgdataindex];
261 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
262 BAMBOO_ASSERT(lockobj == data2);
270 INLINE void processmsg_redirectrelease_I() {
271 int data1 = msgdata[msgdataindex];
273 int data2 = msgdata[msgdataindex];
275 int data3 = msgdata[msgdataindex];
277 processlockrelease_I(data1, data2, data3, true);
279 #endif // #ifndef MULTICORE_GC
282 INLINE void processmsg_profileoutput_I() {
283 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE != STARTUPCORE);
285 totalexetime = msgdata[msgdataindex];
291 // cache the msg first
292 if(BAMBOO_CHECK_SEND_MODE()) {
293 cache_msg_2_I(STARTUPCORE,PROFILEFINISH,BAMBOO_NUM_OF_CORE);
295 send_msg_2_I(STARTUPCORE,PROFILEFINISH,BAMBOO_NUM_OF_CORE);
299 INLINE void processmsg_profilefinish_I() {
300 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
301 int data1 = msgdata[msgdataindex];
303 profilestatus[data1] = 0;
307 INLINE void processmsg_statusconfirm_I() {
308 BAMBOO_ASSERT(((BAMBOO_NUM_OF_CORE != STARTUPCORE) && (BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1)));
310 // cache the msg first
311 if(BAMBOO_CHECK_SEND_MODE()) {
312 cache_msg_5_I(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
314 send_msg_5_I(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
318 INLINE void processmsg_statusreport_I() {
319 int data1 = msgdata[msgdataindex];
321 int data2 = msgdata[msgdataindex];
323 int data3 = msgdata[msgdataindex];
325 int data4 = msgdata[msgdataindex];
327 // receive a status confirm info
328 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
332 corestatus[data2] = data1;
333 numsendobjs[data2] = data3;
334 numreceiveobjs[data2] = data4;
337 INLINE void processmsg_terminate_I() {
340 #ifdef GC_CACHE_ADAPT
341 bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
347 INLINE void processmsg_memrequest_I() {
348 int data1 = msgdata[msgdataindex];
350 int data2 = msgdata[msgdataindex];
352 // receive a shared memory request msg
353 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
357 if(!gcprocessing || !gcflag) {
358 // either not doing GC or the master core has decided to stop GC but
359 // // still sending msgs to other cores to inform them to stop the GC
361 mem = smemalloc_I(data2, data1, &allocsize);
363 // send the start_va to request core, cache the msg first
364 if(BAMBOO_CHECK_SEND_MODE()) {
365 cache_msg_3_I(data2,MEMRESPONSE,mem,allocsize);
367 send_msg_3_I(data2,MEMRESPONSE,mem,allocsize);
369 } //else if mem == NULL, the gcflag of the startup core has been set
370 // and all the other cores have been informed to start gc
376 INLINE void processmsg_memresponse_I() {
377 int data1 = msgdata[msgdataindex];
379 int data2 = msgdata[msgdataindex];
381 // receive a shared memory response msg
383 // if is currently doing gc, dump this msg
388 // Zero out the remaining memory here because for the GC_CACHE_ADAPT
389 // version, we need to make sure during the gcinit phase the shared heap
390 // is not touched. Otherwise, there would be problem when adapt the cache
392 BAMBOO_CLOSE_CUR_MSP();
393 bamboo_smem_zero_top = NULL;
395 bamboo_smem_size = 0;
399 CLOSEBLOCK(data1, data2);
400 bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
401 bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
402 bamboo_smem_zero_top = bamboo_cur_msp;
404 bamboo_smem_size = data2;
405 bamboo_cur_msp =(void*)(data1);
415 INLINE void processmsg_gcstartpre_I() {
416 // the first time to be informed to start gc
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_size = 0;
425 bamboo_cur_msp = NULL;
427 bamboo_smem_zero_top = NULL;
431 INLINE void processmsg_gcstartinit_I() {
435 INLINE void processmsg_gcstart_I() {
440 INLINE void processmsg_gcstartcompact_I() {
441 gcblock2fill = msgdata[msgdataindex];
443 gcphase = COMPACTPHASE;
446 INLINE void processmsg_gcstartflush_I() {
447 gcphase = FLUSHPHASE;
450 INLINE void processmsg_gcfinishpre_I() {
451 int data1 = msgdata[msgdataindex];
453 int data2 = msgdata[msgdataindex];
455 int data3 = msgdata[msgdataindex];
457 // received a init phase finish msg
458 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
460 // All cores should do init GC
462 gccorestatus[data1] = 0;
463 gcnumsendobjs[0][data1] = data2;
464 gcnumreceiveobjs[0][data1] = data3;
467 INLINE void processmsg_gcfinishinit_I() {
468 int data1 = msgdata[msgdataindex];
470 // received a init phase finish msg
471 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
473 // All cores should do init GC
474 if(data1 < NUMCORESACTIVE) {
475 gccorestatus[data1] = 0;
479 INLINE void processmsg_gcfinishmark_I() {
480 int data1 = msgdata[msgdataindex];
482 int data2 = msgdata[msgdataindex];
484 int data3 = msgdata[msgdataindex];
486 // received a mark phase finish msg
487 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
489 // all cores should do mark
490 if(data1 < NUMCORESACTIVE) {
491 gccorestatus[data1] = 0;
495 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
498 entry_index = gcnumsrobjs_index;
500 gcnumsendobjs[entry_index][data1] = data2;
501 gcnumreceiveobjs[entry_index][data1] = data3;
505 INLINE void processmsg_gcfinishcompact_I() {
506 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
508 int cnum = msgdata[msgdataindex];
510 int filledblocks = msgdata[msgdataindex];
512 int heaptop = msgdata[msgdataindex];
514 int data4 = msgdata[msgdataindex];
516 // only gc cores need to do compact
517 if(cnum < NUMCORES4GC) {
518 if(COMPACTPHASE == gcphase) {
519 gcfilledblocks[cnum] = filledblocks;
520 gcloads[cnum] = heaptop;
527 if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
528 // cache the msg first
529 if(BAMBOO_CHECK_SEND_MODE()) {
530 cache_msg_4_I(cnum,GCMOVESTART,dstcore,startaddr,tomove);
532 send_msg_4_I(cnum,GCMOVESTART,dstcore,startaddr,tomove);
536 gccorestatus[cnum] = 0;
541 INLINE void processmsg_gcfinishflush_I() {
542 int data1 = msgdata[msgdataindex];
544 // received a flush phase finish msg
545 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
547 // all cores should do flush
548 if(data1 < NUMCORESACTIVE) {
549 gccorestatus[data1] = 0;
553 INLINE void processmsg_gcfinish_I() {
554 // received a GC finish msg
555 gcphase = FINISHPHASE;
556 gcprocessing = false;
559 INLINE void processmsg_gcmarkconfirm_I() {
560 BAMBOO_ASSERT(((BAMBOO_NUM_OF_CORE!=STARTUPCORE)&&(BAMBOO_NUM_OF_CORE<=NUMCORESACTIVE-1)));
561 gcbusystatus = gc_moreItems2_I();
562 // send response msg, cahce the msg first
563 if(BAMBOO_CHECK_SEND_MODE()) {
564 cache_msg_5_I(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gcbusystatus,gcself_numsendobjs,gcself_numreceiveobjs);
566 send_msg_5_I(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gcbusystatus,gcself_numsendobjs,gcself_numreceiveobjs);
570 INLINE void processmsg_gcmarkreport_I() {
571 int data1 = msgdata[msgdataindex];
573 int data2 = msgdata[msgdataindex];
575 int data3 = msgdata[msgdataindex];
577 int data4 = msgdata[msgdataindex];
579 // received a marked phase finish confirm response msg
580 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
582 BAMBOO_ASSERT(waitconfirm);
586 entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
587 gccorestatus[data1] = data2;
588 gcnumsendobjs[entry_index][data1] = data3;
589 gcnumreceiveobjs[entry_index][data1] = data4;
593 INLINE void processmsg_gcmarkedobj_I() {
594 int data1 = msgdata[msgdataindex];
596 BAMBOO_ASSERT(ISSHAREDOBJ(data1));
598 // received a markedObj msg
599 if(((struct ___Object___ *)data1)->marked == INIT) {
600 // this is the first time that this object is discovered,
601 // set the flag as DISCOVERED
602 ((struct ___Object___ *)data1)->marked = DISCOVERED;
605 gcself_numreceiveobjs++;
609 INLINE void processmsg_gcmovestart_I() {
611 gcdstcore = msgdata[msgdataindex];
613 gcmovestartaddr = msgdata[msgdataindex];
615 gcblock2fill = msgdata[msgdataindex];
619 INLINE void processmsg_gclobjinfo_I(unsigned int data1) {
621 int data2 = msgdata[msgdataindex];
623 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORES4GC - 1);
625 // store the mark result info
627 gcloads[cnum] = msgdata[msgdataindex];
629 int data4 = msgdata[msgdataindex];
631 if(gcheaptop < data4) {
634 // large obj info here
635 for(int k = 4; k < data1; k+=2) {
636 int lobj = msgdata[msgdataindex];
638 int length = msgdata[msgdataindex];
640 gc_lobjenqueue_I(lobj, length, cnum);
646 INLINE void processmsg_gcprofiles_I() {
647 int data1 = msgdata[msgdataindex];
649 int data2 = msgdata[msgdataindex];
651 int data3 = msgdata[msgdataindex];
654 if(gc_profile_flag) {
657 gc_num_liveobj += data2;
658 gc_num_forwardobj += data3;
666 #ifdef GC_CACHE_ADAPT
667 INLINE void processmsg_gcstartpref_I() {
668 gcphase = PREFINISHPHASE;
671 INLINE void processmsg_gcfinishpref_I() {
672 int data1 = msgdata[msgdataindex];
674 // received a flush phase finish msg
675 BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
677 // all cores should do flush
678 if(data1 < NUMCORESACTIVE) {
679 gccorestatus[data1] = 0;
682 #endif // GC_CACHE_ADAPT
683 #endif // #ifdef MULTICORE_GC
685 // receive object transferred from other cores
686 // or the terminate message from other cores
687 // Should be invoked in critical sections!!
688 // NOTICE: following format is for threadsimulate version only
689 // RAW version please see previous description
690 // format: type + object
691 // type: -1--stall msg
693 // return value: 0--received an object
694 // 1--received nothing
695 // 2--received a Stall Msg
696 // 3--received a lock Msg
697 // RAW version: -1 -- received nothing
698 // otherwise -- received msg type
699 int receiveObject_I() {
700 PROFILE_INTERRUPT_START();
702 // get the incoming msgs
704 if((msgdataindex == msgdatalast) && (!msgdatafull)) {
707 if(BAMBOO_CHECK_SEND_MODE()) {
708 // during send, don't process the msg now
712 // processing received msgs
714 MSG_REMAINSIZE_I(&size);
717 // have new coming msg
718 if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
725 //we only ever read the first word
727 unsigned int msglength = checkMsgLength_I((unsigned int*)(&type));
729 if(msglength <= size) {
730 // have some whole msg
736 // receive a object transfer msg
737 processmsg_transobj_I(msglength);
742 // receive a stall msg
743 processmsg_transtall_I();
748 // GC version have no lock msgs
751 // receive lock request msg, handle it right now
752 processmsg_lockrequest_I();
756 // receive lock grount msg
757 processmsg_lockgrount_I();
761 // receive lock deny msg
762 processmsg_lockdeny_I();
766 processmsg_lockrelease_I();
772 case PROFILEOUTPUT: {
773 // receive an output profile data request msg
774 processmsg_profileoutput_I();
777 case PROFILEFINISH: {
778 // receive a profile output finish msg
779 processmsg_profilefinish_I();
784 // GC version has no lock msgs
787 // receive a redirect lock request msg, handle it right now
788 processmsg_redirectlock_I();
792 case REDIRECTGROUNT: {
793 // receive a lock grant msg with redirect info
794 processmsg_redirectgrount_I();
799 // receive a lock deny msg with redirect info
800 processmsg_redirectdeny_I();
804 case REDIRECTRELEASE: {
805 // receive a lock release msg with redirect info
806 processmsg_redirectrelease_I();
808 } // case REDIRECTRELEASE
812 case STATUSCONFIRM: {
813 // receive a status confirm info
814 processmsg_statusconfirm_I();
819 processmsg_statusreport_I();
824 // receive a terminate msg
825 processmsg_terminate_I();
830 processmsg_memrequest_I();
835 processmsg_memresponse_I();
842 processmsg_gcstartpre_I();
847 processmsg_gcstartinit_I();
852 // receive a start GC msg
853 processmsg_gcstart_I();
857 case GCSTARTCOMPACT: {
858 // a compact phase start msg
859 processmsg_gcstartcompact_I();
864 // received a flush phase start msg
865 processmsg_gcstartflush_I();
870 processmsg_gcfinishpre_I();
875 processmsg_gcfinishinit_I();
880 processmsg_gcfinishmark_I();
884 case GCFINISHCOMPACT: {
885 // received a compact phase finish msg
886 processmsg_gcfinishcompact_I();
890 case GCFINISHFLUSH: {
891 processmsg_gcfinishflush_I();
896 processmsg_gcfinish_I();
900 case GCMARKCONFIRM: {
901 // received a marked phase finish confirm request msg
902 // all cores should do mark
903 processmsg_gcmarkconfirm_I();
908 processmsg_gcmarkreport_I();
913 processmsg_gcmarkedobj_I();
918 // received a start moving objs msg
919 processmsg_gcmovestart_I();
923 case GCLOBJREQUEST: {
924 // received a large objs info request msg
925 transferMarkResults_I();
930 // received a large objs info response msg
931 processmsg_gclobjinfo_I(msglength);
937 // received a gcprofiles msg
938 processmsg_gcprofiles_I();
943 #ifdef GC_CACHE_ADAPT
945 // received a gcstartpref msg
946 processmsg_gcstartpref_I();
951 // received a gcfinishpref msg
952 processmsg_gcfinishpref_I();
962 if((msgdataindex != msgdatalast) || (msgdatafull)) {
963 // still have available msg
967 // have new coming msg
968 if(BAMBOO_MSG_AVAIL() != 0) {
972 PROFILE_INTERRUPT_END();