code towards PMC compiling
[IRC.git] / Robust / src / Runtime / bamboo / multicoremsg.c
1 #ifdef MULTICORE
2 #include "multicoremsg.h"
3 #include "runtime.h"
4 #include "multicoreruntime.h"
5 #include "multicoregarbage.h"
6 #include "multicoretaskprofile.h"
7 #include "runtime_arch.h"
8 #ifdef MULTICORE_GC
9 #include "gcqueue.h"
10 #include "markbit.h"
11 #endif
12
13 int msgsizearray[] = {
14   0, //MSGSTART,
15   1, //REQNOTIFYSTART
16   1, //NOTIFYSTART
17  -1, //TRANSOBJ,              // 0xD1
18   4, //TRANSTALL,             // 0xD2
19   5, //LOCKREQUEST,           // 0xD3
20   4, //LOCKGROUNT,            // 0xD4
21   4, //LOCKDENY,              // 0xD5
22   4, //LOCKRELEASE,           // 0xD6
23   2, //PROFILEOUTPUT,         // 0xD7
24   1, //PROFILEFINISH,         // 0xD8
25   6, //REDIRECTLOCK,          // 0xD9
26   4, //REDIRECTGROUNT,        // 0xDa
27   4, //REDIRECTDENY,          // 0xDb
28   4, //REDIRECTRELEASE,       // 0xDc
29   1, //STATUSCONFIRM,         // 0xDd
30   5, //STATUSREPORT,          // 0xDe
31   1, //TERMINATE,             // 0xDf
32   3, //MEMREQUEST,            // 0xE0
33   3, //MEMRESPONSE,           // 0xE1
34 #ifdef MULTICORE_GC
35   1, //GCINVOKE
36   1, //GCSTARTPRE,            // 0xE2
37   1, //GCSTARTINIT,           // 0xE3
38   1, //GCSTART,               // 0xE4
39   2, //GCSTARTCOMPACT,        // 0xE5
40   1, //GCSTARTUPDATE,          // 0xE6
41   4, //GCFINISHPRE,           // 0xE7
42   2, //GCFINISHINIT,          // 0xE8
43   4, //GCFINISHMARK,          // 0xE9
44   4, //GCFINISHCOMPACT,       // 0xEa
45   3, //GCRETURNMEM,
46   2, //GCFINISHUPDATE,         // 0xEb
47   1, //GCFINISH,              // 0xEc
48   1, //GCMARKCONFIRM,         // 0xEd
49   5, //GCMARKREPORT,          // 0xEe
50   2, //GCMARKEDOBJ,           // 0xEf
51   2, //GCMOVESTART,           // 0xF0
52   1, //GCLOBJREQUEST,         // 0xF1
53   3, //GCREQBLOCK,
54   1, //GCGRANTBLOCK,  
55   -1, //GCLOBJINFO,            // 0xF2
56 #ifdef GC_PROFILE
57   4, //GCPROFILES,            // 0xF3
58 #endif // GC_PROFILE
59 #ifdef GC_CACHE_ADAPT
60   1, //GCSTARTCACHEPOLICY     // 0xF4
61   2, //GCFINISHCACHEPOLICY    // 0xF5
62   1, //GCSTARTPREF,           // 0xF6
63   2, //GCFINISHPREF,          // 0xF7
64 #endif // GC_CACHE_ADAPT
65 #endif // MULTICORE_GC
66   -1 //MSGEND
67 };
68
69 unsigned int checkMsgLength_I(unsigned int realtype) {
70 #if (defined(TASK)||defined(MULTICORE_GC))
71   unsigned int type = realtype & 0xff;
72 #else
73   unsigned int type = realtype;
74 #endif
75   BAMBOO_ASSERT(type<=MSGEND);
76 #ifdef TASK
77 #if defined(MULTICORE_GC)
78   if(type==TRANSOBJ||type==GCLOBJINFO) {
79 #else
80   if(type==TRANSOBJ) {
81 #endif
82 #elif defined(MULTICORE_GC)
83   if (type==GCLOBJINFO) {
84 #endif
85 #if (defined(TASK)||defined(MULTICORE_GC))
86     return realtype>>8;
87   }
88 #endif
89   return msgsizearray[type];
90 }
91
92 #ifdef TASK
93 void processmsg_transobj_I(int msglength) {
94   struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
95   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
96
97   // store the object and its corresponding queue info, enqueue it later
98   transObj->objptr = (void *)msgdata[msgdataindex]; 
99   MSG_INDEXINC_I();
100   transObj->length = (msglength - 2) / 2;
101   transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
102   for(int k = 0; k < transObj->length; k++) {
103     transObj->queues[2*k] = msgdata[msgdataindex];  
104     MSG_INDEXINC_I();
105     transObj->queues[2*k+1] = msgdata[msgdataindex]; 
106     MSG_INDEXINC_I();
107   }
108   // check if there is an existing duplicate item
109   struct QueueItem * prev = NULL;
110   for(struct QueueItem * qitem = getHead(&objqueue);qitem != NULL;qitem=(prev==NULL)?getHead(&objqueue):getNextQueueItem(prev)) {
111     struct transObjInfo * tmpinfo = (struct transObjInfo *)(qitem->objectptr);
112     if(tmpinfo->objptr == transObj->objptr) {
113       // the same object, remove outdate one
114       RUNFREE_I(tmpinfo->queues);
115       RUNFREE_I(tmpinfo);
116       removeItem(&objqueue, qitem);
117       //break;
118     } else {
119       prev = qitem;
120     }
121   }
122   addNewItem_I(&objqueue, (void *)transObj);
123   
124   self_numreceiveobjs++;
125 #ifdef MULTICORE_GC
126   if(gc_status_info.gcprocessing) {
127     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
128       // set the gcprecheck to enable checking again
129       gcprecheck = true;
130     } else {
131       // send a update pregc information msg to the master core
132       if(BAMBOO_CHECK_SEND_MODE()) {
133         cache_msg_4_I(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
134       } else {
135         send_msg_4_I(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs, self_numreceiveobjs);
136       }
137     }
138   }
139 #endif 
140 }
141 #endif
142
143 void processmsg_transtall_I() {
144   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
145   
146   int num_core = msgdata[msgdataindex];
147   MSG_INDEXINC_I();
148   int data2 = msgdata[msgdataindex]; 
149   MSG_INDEXINC_I();
150   int data3 = msgdata[msgdataindex];
151   MSG_INDEXINC_I();
152   if(num_core < NUMCORESACTIVE) {
153     corestatus[num_core] = 0;
154     numsendobjs[num_core] = data2; 
155     numreceiveobjs[num_core] = data3; 
156   }
157 }
158
159 #if !defined(MULTICORE_GC)&&!defined(PMC_GC)
160 void processmsg_lockrequest_I() {
161   // check to see if there is a lock exist for the required obj
162   // msgdata[1] -> lock type
163   int locktype = msgdata[msgdataindex]; 
164   MSG_INDEXINC_I();
165   int data2 = msgdata[msgdataindex];  // obj pointer
166   MSG_INDEXINC_I();
167   int data3 = msgdata[msgdataindex];  // lock
168   MSG_INDEXINC_I();
169   int data4 = msgdata[msgdataindex];  // request core
170   MSG_INDEXINC_I();
171   // -1: redirected, 0: approved, 1: denied
172   int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
173   if(deny != -1) {
174     // send response msg
175     // for 32 bit machine, the size is always 4 words, cache the msg first
176     int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
177     if(BAMBOO_CHECK_SEND_MODE()) {
178       cache_msg_4_I(data4,tmp,locktype,data2,data3);
179     } else {
180       send_msg_4_I(data4,tmp,locktype,data2,data3);
181     }
182   }
183 }
184
185 void processmsg_lockgrount_I() {
186   MSG_INDEXINC_I();
187   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
188   int data2 = msgdata[msgdataindex];
189   MSG_INDEXINC_I();
190   int data3 = msgdata[msgdataindex];
191   MSG_INDEXINC_I();
192   BAMBOO_ASSERT((lockobj == data2) && (lock2require == data3));
193   lockresult = 1;
194   lockflag = true;
195 #ifndef INTERRUPT
196   reside = false;
197 #endif
198 }
199
200 void processmsg_lockdeny_I() {
201   MSG_INDEXINC_I();
202   int data2 = msgdata[msgdataindex];
203   MSG_INDEXINC_I();
204   int data3 = msgdata[msgdataindex];
205   MSG_INDEXINC_I();
206   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
207   BAMBOO_ASSERT((lockobj == data2) && (lock2require == data3));
208   lockresult = 0;
209   lockflag = true;
210 #ifndef INTERRUPT
211   reside = false;
212 #endif
213 }
214
215 void processmsg_lockrelease_I() {
216   int data1 = msgdata[msgdataindex];
217   MSG_INDEXINC_I();
218   int data2 = msgdata[msgdataindex];
219   MSG_INDEXINC_I();
220   int data3 = msgdata[msgdataindex];
221   MSG_INDEXINC_I();
222   // receive lock release msg
223   processlockrelease(data1, data2, 0, false);
224 }
225
226 void processmsg_redirectlock_I() {
227   // check to see if there is a lock exist for the required obj
228   int data1 = msgdata[msgdataindex];
229   MSG_INDEXINC_I();    // lock type
230   int data2 = msgdata[msgdataindex];
231   MSG_INDEXINC_I();    // obj pointer
232   int data3 = msgdata[msgdataindex];
233   MSG_INDEXINC_I();    // redirect lock
234   int data4 = msgdata[msgdataindex];
235   MSG_INDEXINC_I();    // root request core
236   int data5 = msgdata[msgdataindex];
237   MSG_INDEXINC_I();    // request core
238   int deny = processlockrequest_I(data1, data3, data2, data5, data4, true);
239   if(deny != -1) {
240     // send response msg
241     // for 32 bit machine, the size is always 4 words, cache the msg first
242     if(BAMBOO_CHECK_SEND_MODE()) {
243       cache_msg_4_I(data4,deny==1?REDIRECTDENY:REDIRECTGROUNT,data1,data2,data3);
244     } else {
245       send_msg_4_I(data4,deny==1?REDIRECTDENY:REDIRECTGROUNT,data1,data2,data3);
246     }
247   }
248 }
249
250 void processmsg_redirectgrount_I() {
251   MSG_INDEXINC_I();
252   int data2 = msgdata[msgdataindex];
253   MSG_INDEXINC_I();
254   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
255   BAMBOO_ASSERT(lockobj == data2, 0xe207);
256   int data3 = msgdata[msgdataindex];
257   MSG_INDEXINC_I();
258   lockresult = 1;
259   lockflag = true;
260   RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
261 #ifndef INTERRUPT
262   reside = false;
263 #endif
264 }
265
266 void processmsg_redirectdeny_I() {
267   MSG_INDEXINC_I();
268   int data2 = msgdata[msgdataindex];
269   MSG_INDEXINC_I();
270   int data3 = msgdata[msgdataindex];
271   MSG_INDEXINC_I();
272   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
273   BAMBOO_ASSERT(lockobj == data2);
274   lockresult = 0;
275   lockflag = true;
276 #ifndef INTERRUPT
277   reside = false;
278 #endif
279 }
280
281 void processmsg_redirectrelease_I() {
282   int data1 = msgdata[msgdataindex];
283   MSG_INDEXINC_I();
284   int data2 = msgdata[msgdataindex];
285   MSG_INDEXINC_I();
286   int data3 = msgdata[msgdataindex];
287   MSG_INDEXINC_I();
288   processlockrelease_I(data1, data2, data3, true);
289 }
290 #endif // #ifndef MULTICORE_GC
291
292 #ifdef PROFILE
293 void processmsg_profileoutput_I() {
294   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE != STARTUPCORE);
295   stall = true;
296   totalexetime = msgdata[msgdataindex];
297   MSG_INDEXINC_I();
298 #ifdef RT_TEST
299 #else
300   outputProfileData();
301 #endif
302   // cache the msg first
303   if(BAMBOO_CHECK_SEND_MODE()) {
304     cache_msg_1_I(STARTUPCORE,PROFILEFINISH);
305   } else {
306     send_msg_1_I(STARTUPCORE,PROFILEFINISH);
307   }
308 }
309
310 void processmsg_profilefinish_I() {
311   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
312   numconfirm--;
313 }
314 #endif // PROFILE
315
316 void processmsg_statusconfirm_I() {
317   BAMBOO_ASSERT(((BAMBOO_NUM_OF_CORE != STARTUPCORE) && (BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1)));
318   // send response msg
319   // cache the msg first
320   if(BAMBOO_CHECK_SEND_MODE()) {
321     cache_msg_5_I(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
322   } else {
323     send_msg_5_I(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
324   }
325 }
326
327 void processmsg_statusreport_I() {
328   int data1 = msgdata[msgdataindex];
329   MSG_INDEXINC_I();
330   int data2 = msgdata[msgdataindex];
331   MSG_INDEXINC_I();
332   int data3 = msgdata[msgdataindex];
333   MSG_INDEXINC_I();
334   int data4 = msgdata[msgdataindex];
335   MSG_INDEXINC_I();
336   // receive a status confirm info
337   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
338   if(waitconfirm) {
339     numconfirm--;
340   }
341   corestatus[data2] = data1;
342   numsendobjs[data2] = data3;
343   numreceiveobjs[data2] = data4;
344 }
345
346 void processmsg_terminate_I() {
347   disruntimedata();
348 #ifdef MULTICORE_GC
349 #ifdef GC_CACHE_ADAPT
350   bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
351 #endif
352 #endif
353   BAMBOO_EXIT_APP(0);
354 }
355
356 void processmsg_memrequest_I() {
357   int data1 = msgdata[msgdataindex];
358   MSG_INDEXINC_I();
359   int data2 = msgdata[msgdataindex];
360   MSG_INDEXINC_I();
361   // receive a shared memory request msg
362   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
363 #ifdef MULTICORE_GC
364   if(!gc_status_info.gcprocessing || !gcflag) {
365     // either not doing GC or the master core has decided to stop GC but 
366     // // still sending msgs to other cores to inform them to stop the GC
367 #endif
368     unsigned INTPTR allocsize = 0;
369     void * mem = smemalloc_I(data2, data1, &allocsize);
370     if(mem != NULL) {
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,(unsigned INTPTR) mem,allocsize);
374       } else {
375         send_msg_3_I(data2,MEMRESPONSE,(unsigned INTPTR) mem,allocsize);
376       }
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
379 #ifdef MULTICORE_GC
380   }
381 #endif
382 }
383
384 void processmsg_memresponse_I() {
385   void * memptr =(void *) msgdata[msgdataindex];
386   MSG_INDEXINC_I();
387   unsigned int numbytes = msgdata[msgdataindex];
388   MSG_INDEXINC_I();
389   // receive a shared memory response msg
390 #ifdef MULTICORE_GC
391   // if is currently doing gc, dump this msg
392   if(!gc_status_info.gcprocessing) {
393 #endif
394   if(numbytes == 0) {
395 #ifdef MULTICORE_GC
396     bamboo_smem_zero_top = NULL;
397 #endif
398     bamboo_smem_size = 0;
399     bamboo_cur_msp = NULL;
400   } else {
401 #ifdef MULTICORE_GC
402     bamboo_smem_size = numbytes;
403     bamboo_cur_msp = memptr;
404 #else
405     bamboo_smem_size = numbytes;
406     bamboo_cur_msp =memptr;
407 #endif
408   }
409   smemflag = true;
410 #ifdef MULTICORE_GC
411   }
412 #endif
413 }
414
415 #ifdef MULTICORE_GC
416 void processmsg_gcinvoke_I() {
417   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE==STARTUPCORE);
418   if(!gc_status_info.gcprocessing && !gcflag) {
419     gcflag = true;
420     gcprecheck = true;
421     for(int i = 0; i < NUMCORESACTIVE; i++) {
422       // reuse the gcnumsendobjs & gcnumreceiveobjs
423       gcnumsendobjs[0][i] = 0;
424       gcnumreceiveobjs[0][i] = 0;
425     }
426     for(int i = 0; i < NUMCORES4GC; i++) {
427       if(i != STARTUPCORE) {
428         if(BAMBOO_CHECK_SEND_MODE()) {
429           cache_msg_1_I(i,GCSTARTPRE);
430         } else {
431           send_msg_1_I(i,GCSTARTPRE);
432         }
433       }
434     }
435   }
436 }
437
438 void processmsg_gcstartpre_I() {
439   // the first time to be informed to start gc
440   gcflag = true;
441 }
442
443 void processmsg_gcstartinit_I() {
444   gc_status_info.gcphase = INITPHASE;
445 }
446
447 void processmsg_gcstart_I() {
448   // set the GC flag
449   gc_status_info.gcphase = MARKPHASE;
450 }
451
452 void processmsg_gcstartcompact_I() {
453   gcblock2fill = msgdata[msgdataindex];
454   MSG_INDEXINC_I();  
455   BAMBOO_ASSERT(!gc_status_info.gcbusystatus);
456   gc_status_info.gcphase = COMPACTPHASE;
457 }
458
459 void processmsg_gcstartupdate_I() {
460   gc_status_info.gcphase = UPDATEPHASE;
461 }
462
463 void processmsg_gcfinishpre_I() {
464   int data1 = msgdata[msgdataindex];
465   MSG_INDEXINC_I();
466   int data2 = msgdata[msgdataindex];
467   MSG_INDEXINC_I();
468   int data3 = msgdata[msgdataindex];
469   MSG_INDEXINC_I();
470   // received a init phase finish msg
471   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
472
473   // All cores should do init GC
474   gcprecheck = true;
475   gccorestatus[data1] = 0;
476   gcnumsendobjs[0][data1] = data2;
477   gcnumreceiveobjs[0][data1] = data3;
478 }
479
480 void processmsg_gcfinishinit_I() {
481   int data1 = msgdata[msgdataindex];
482   MSG_INDEXINC_I();
483   // received a init phase finish msg
484   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
485
486   // All cores should do init GC
487   if(data1 < NUMCORESACTIVE) {
488     gccorestatus[data1] = 0;
489   }
490 }
491
492 void processmsg_reqblock_I() {
493   int cnum=msgdata[msgdataindex];
494   MSG_INDEXINC_I();
495   void * topptr= (void *)msgdata[msgdataindex];
496   MSG_INDEXINC_I();
497   if (topptr<=update_origblockptr) {
498     //send message
499     if(BAMBOO_CHECK_SEND_MODE()) {
500       cache_msg_1_I(cnum,GCGRANTBLOCK);
501     } else {
502       send_msg_1_I(cnum,GCGRANTBLOCK);
503     }
504   } else {
505     //store message
506     origblockarray[cnum]=topptr;
507     origarraycount++;
508   }
509 }
510
511 void processmsg_grantblock_I() {
512   blockgranted=true;
513 }
514
515
516 void processmsg_gcfinishmark_I() {
517   int cnum = msgdata[msgdataindex];
518   MSG_INDEXINC_I();
519   int nsend = msgdata[msgdataindex];
520   MSG_INDEXINC_I();
521   int nrecv = msgdata[msgdataindex];
522   MSG_INDEXINC_I();
523   // received a mark phase finish msg
524   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
525   BAMBOO_ASSERT(gc_status_info.gcphase == MARKPHASE);
526
527   // all cores should do mark
528   if(cnum < NUMCORESACTIVE) {
529     gccorestatus[cnum] = 0;
530     int entry_index = 0;
531     if(waitconfirm)  {
532       // phase 2
533       entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
534     } else {
535       // phase 1
536       entry_index = gcnumsrobjs_index;
537     }
538     gcnumsendobjs[entry_index][cnum] = nsend;
539     gcnumreceiveobjs[entry_index][cnum] = nrecv;
540   }
541 }
542  
543 void processmsg_returnmem_I() {
544   unsigned int cnum = msgdata[msgdataindex];
545   MSG_INDEXINC_I();  
546   void * heaptop = (void *) msgdata[msgdataindex];
547   MSG_INDEXINC_I();   
548
549   handleReturnMem_I(cnum, heaptop);
550 }
551
552 void * handlegcfinishcompact_I(int cnum, unsigned int bytesneeded, unsigned int maxbytesneeded) {
553   if(bytesneeded > 0) {
554     // ask for more mem
555     return gcfindSpareMem_I(bytesneeded, maxbytesneeded, cnum);
556   } else {
557     //done with compacting
558     gccorestatus[cnum] = 0;
559     return NULL;
560   }
561 }
562
563 void processmsg_gcfinishcompact_I() {
564   int cnum = msgdata[msgdataindex];
565   MSG_INDEXINC_I();  
566   unsigned int bytesneeded = msgdata[msgdataindex];
567   MSG_INDEXINC_I(); 
568   unsigned int maxbytesneeded = msgdata[msgdataindex];
569   MSG_INDEXINC_I();
570
571   void * startaddr=handlegcfinishcompact_I(cnum, bytesneeded, maxbytesneeded);
572   if (startaddr) {
573     if(BAMBOO_CHECK_SEND_MODE()) {
574       cache_msg_2_I(cnum,GCMOVESTART,(unsigned INTPTR)startaddr);
575     } else {
576       send_msg_2_I(cnum,GCMOVESTART,(unsigned INTPTR)startaddr);
577     }
578   }
579 }
580
581 void processmsg_gcfinishupdate_I() {
582   int data1 = msgdata[msgdataindex];
583   MSG_INDEXINC_I();
584   // received a update phase finish msg
585   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
586
587   // all cores should do update
588   if(data1 < NUMCORESACTIVE) {
589     gccorestatus[data1] = 0;
590   }
591 }
592
593 void processmsg_gcfinish_I() {
594   // received a GC finish msg
595   gc_status_info.gcphase = FINISHPHASE;
596   gc_status_info.gcprocessing = false;
597 }
598
599 void processmsg_gcmarkconfirm_I() {
600   BAMBOO_ASSERT(((BAMBOO_NUM_OF_CORE!=STARTUPCORE)&&(BAMBOO_NUM_OF_CORE<=NUMCORESACTIVE-1)));
601   // send response msg, cahce the msg first
602   if(BAMBOO_CHECK_SEND_MODE()) {
603     cache_msg_5_I(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gc_status_info.gcbusystatus,gcself_numsendobjs,gcself_numreceiveobjs);
604   } else {
605     send_msg_5_I(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gc_status_info.gcbusystatus,gcself_numsendobjs,gcself_numreceiveobjs);
606   }
607 }
608
609 void processmsg_gcmarkreport_I() {
610   int data1 = msgdata[msgdataindex];
611   MSG_INDEXINC_I();
612   int data2 = msgdata[msgdataindex];
613   MSG_INDEXINC_I();
614   int data3 = msgdata[msgdataindex];
615   MSG_INDEXINC_I();
616   int data4 = msgdata[msgdataindex];
617   MSG_INDEXINC_I();
618   // received a marked phase finish confirm response msg
619   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
620   int entry_index = 0;
621   BAMBOO_ASSERT(waitconfirm);
622
623   // phase 2
624   numconfirm--;
625   entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
626   gccorestatus[data1] = data2;
627   gcnumsendobjs[entry_index][data1] = data3;
628   gcnumreceiveobjs[entry_index][data1] = data4;
629
630 }
631
632 void processmsg_gcmarkedobj_I() {
633   void * objptr = (void *) msgdata[msgdataindex];
634   MSG_INDEXINC_I();
635   
636   // received a markedObj msg
637   if(!checkMark(objptr)) {
638     // this is the first time that this object is discovered,
639     // set the flag as DISCOVERED
640
641     setMark_I(objptr);
642     gc_enqueue_I(objptr);
643   }
644   gcself_numreceiveobjs++;
645   gc_status_info.gcbusystatus = true;
646 }
647
648 void processmsg_gcmovestart_I() {
649   gctomove = true;
650   gcmovestartaddr = msgdata[msgdataindex];
651   MSG_INDEXINC_I();     
652 }
653
654 void processmsg_gclobjinfo_I(unsigned int msglength) {
655   numconfirm--;
656   int cnum = msgdata[msgdataindex];
657   MSG_INDEXINC_I();
658   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORES4GC - 1);
659
660   // store the mark result info
661   gcloads[cnum] = msgdata[msgdataindex];
662   MSG_INDEXINC_I();     
663
664   // large obj info here
665   for(int k = 3; k < msglength; k+=2) {
666     void * lobj = (void *) msgdata[msgdataindex];
667     MSG_INDEXINC_I();  
668     int length = msgdata[msgdataindex];
669     MSG_INDEXINC_I();   
670     gc_lobjenqueue_I(lobj, length, cnum);
671   }
672 }
673
674 #ifdef GC_PROFILE
675 void processmsg_gcprofiles_I() {
676   int data1 = msgdata[msgdataindex];
677   MSG_INDEXINC_I();
678   int data2 = msgdata[msgdataindex];
679   MSG_INDEXINC_I();
680   int data3 = msgdata[msgdataindex];
681   MSG_INDEXINC_I();
682 #ifdef MGC_SPEC
683   if(gc_profile_flag) {
684 #endif
685     gc_num_obj += data1;
686     gc_num_liveobj += data2;
687     gc_num_forwardobj += data3;
688 #ifdef MGC_SPEC
689   }
690 #endif
691   gc_num_profiles--;
692 }
693 #endif // GC_PROFILE
694
695 #ifdef GC_CACHE_ADAPT
696 void processmsg_gcstartcachepolicy_I() {
697   gc_status_info.gcphase = CACHEPOLICYPHASE;
698 }
699
700 void processmsg_gcfinishcachepolicy_I() {
701   int data1 = msgdata[msgdataindex];
702   MSG_INDEXINC_I();
703   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
704
705   // all cores should do update
706   if(data1 < NUMCORESACTIVE) {
707     gccorestatus[data1] = 0;
708   }
709 }
710
711 void processmsg_gcstartpref_I() {
712   gc_status_info.gcphase = PREFINISHPHASE;
713 }
714
715 void processmsg_gcfinishpref_I() {
716   int data1 = msgdata[msgdataindex];
717   MSG_INDEXINC_I();
718   // received a update phase finish msg
719   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
720
721   // all cores should do update
722   if(data1 < NUMCORESACTIVE) {
723     gccorestatus[data1] = 0;
724   }
725 }
726 #endif // GC_CACHE_ADAPT
727 #endif // #ifdef MULTICORE_GC
728
729 void processmsg_req_notify_start() {
730   startflag=true;
731   if(BAMBOO_CHECK_SEND_MODE()) {
732     cache_msg_1_I(STARTUPCORE,NOTIFYSTART);
733   } else {
734     send_msg_1_I(STARTUPCORE,NOTIFYSTART);
735   }  
736 }
737
738 void processmsg_notify_start() {
739   numconfirm--;
740 }
741
742 // receive object transferred from other cores
743 // or the terminate message from other cores
744 // Should be invoked in critical sections!!
745 // NOTICE: following format is for threadsimulate version only
746 //         RAW version please see previous description
747 // format: type + object
748 // type: -1--stall msg
749 //      !-1--object
750 // return value: 0--received an object
751 //               1--received nothing
752 //               2--received a Stall Msg
753 //               3--received a lock Msg
754 //               RAW version: -1 -- received nothing
755 //                            otherwise -- received msg type
756 int receiveObject_I() {
757   PROFILE_INTERRUPT_START(); 
758 msg:
759   // get the incoming msgs
760   receiveMsg_I();
761   if((msgdataindex == msgdatalast) && (!msgdatafull)) {
762     return -1;
763   }
764   if(BAMBOO_CHECK_SEND_MODE()) {
765     // during send, don't process the msg now
766     return -3; 
767   }
768 processmsg:
769   // processing received msgs
770   int size;
771   MSG_REMAINSIZE_I(size);
772   if(size == 0) {
773     // not a whole msg
774     // have new coming msg
775     if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
776       goto msg;
777     } else {
778       return -1;
779     }
780   }
781
782   //we only ever read the first word
783   unsigned int realtype = msgdata[msgdataindex];
784   unsigned int msglength = checkMsgLength_I(realtype);
785
786 #if (defined(TASK)||defined(MULTICORE_GC))
787   unsigned int type = realtype & 0xff;
788 #else
789   unsigned int type = realtype;
790 #endif
791
792   if(msglength <= size) {
793     // have some whole msg
794     MSG_INDEXINC_I();
795     msgdatafull = false;
796
797     switch(type) {
798     case REQNOTIFYSTART: {
799       processmsg_req_notify_start();
800       break;
801     }
802
803     case NOTIFYSTART: {
804       processmsg_notify_start();
805       break;
806     }
807
808 #ifdef TASK
809     case TRANSOBJ: {
810       // receive a object transfer msg
811       processmsg_transobj_I(msglength);
812       break;
813     }  
814 #endif 
815     case TRANSTALL: {
816       // receive a stall msg
817       processmsg_transtall_I();
818       break;
819     }   
820
821 #ifdef TASK
822     // GC version have no lock msgs
823 #ifndef MULTICORE_GC
824     case LOCKREQUEST: {
825       // receive lock request msg, handle it right now
826       processmsg_lockrequest_I();
827       break;
828     }   
829     case LOCKGROUNT: {
830       // receive lock grount msg
831       processmsg_lockgrount_I();
832       break;
833     } 
834     case LOCKDENY: {
835       // receive lock deny msg
836       processmsg_lockdeny_I();
837       break;
838     }  
839     case LOCKRELEASE: {
840       processmsg_lockrelease_I();
841       break;
842     }   
843 #endif
844
845 #ifdef PROFILE
846     case PROFILEOUTPUT: {
847       // receive an output profile data request msg
848       processmsg_profileoutput_I();
849       break;
850     }   
851     case PROFILEFINISH: {
852       // receive a profile output finish msg
853       processmsg_profilefinish_I();
854       break;
855     }  
856 #endif 
857
858     // GC version has no lock msgs
859 #ifndef MULTICORE_GC
860     case REDIRECTLOCK: {
861       // receive a redirect lock request msg, handle it right now
862       processmsg_redirectlock_I();
863       break;
864     }  
865
866     case REDIRECTGROUNT: {
867       // receive a lock grant msg with redirect info
868       processmsg_redirectgrount_I();
869       break;
870     } 
871
872     case REDIRECTDENY: {
873       // receive a lock deny msg with redirect info
874       processmsg_redirectdeny_I();
875       break;
876     }   
877
878     case REDIRECTRELEASE: {
879       // receive a lock release msg with redirect info
880       processmsg_redirectrelease_I();
881       break;
882     }   // case REDIRECTRELEASE
883 #endif
884 #endif 
885
886     case STATUSCONFIRM: {
887       // receive a status confirm info
888       processmsg_statusconfirm_I();
889       break;
890     }  
891
892     case STATUSREPORT: {
893       processmsg_statusreport_I();
894       break;
895     } 
896
897     case TERMINATE: {
898       // receive a terminate msg
899       processmsg_terminate_I();
900       break;
901     } 
902
903     case MEMREQUEST: {
904       processmsg_memrequest_I();
905       break;
906     }
907
908     case MEMRESPONSE: {
909       processmsg_memresponse_I();
910       break;
911     }
912
913 #ifdef MULTICORE_GC
914     // GC msgs
915     case GCINVOKE: {
916       processmsg_gcinvoke_I();
917       break;
918     }
919
920     case GCSTARTPRE: {
921       processmsg_gcstartpre_I();
922       break;
923     }
924         
925     case GCSTARTINIT: {
926       processmsg_gcstartinit_I();
927       break;
928     }
929
930     case GCSTART: {
931       // receive a start GC msg
932       processmsg_gcstart_I();
933       break;
934     }
935
936     case GCSTARTCOMPACT: {
937       // a compact phase start msg
938       processmsg_gcstartcompact_I();
939       break;
940     }
941
942     case GCSTARTUPDATE: {
943       // received a update phase start msg
944       processmsg_gcstartupdate_I();
945       break;
946     }
947
948     case GCFINISHPRE: {
949       processmsg_gcfinishpre_I();
950       break;
951     }
952         
953     case GCFINISHINIT: {
954       processmsg_gcfinishinit_I();
955       break;
956     }
957
958     case GCFINISHMARK: {
959       processmsg_gcfinishmark_I();
960       break;
961     }
962
963     case GCRETURNMEM: {
964       processmsg_returnmem_I();
965       break;
966     }
967
968     case GCFINISHCOMPACT: {
969       // received a compact phase finish msg
970       processmsg_gcfinishcompact_I();
971       break;
972     }
973
974     case GCFINISHUPDATE: {
975       processmsg_gcfinishupdate_I();
976       break;
977     }  
978
979     case GCFINISH: {
980       processmsg_gcfinish_I();
981       break;
982     } 
983
984     case GCMARKCONFIRM: {
985       // received a marked phase finish confirm request msg
986       // all cores should do mark
987       processmsg_gcmarkconfirm_I();
988       break;
989     } 
990
991     case GCMARKREPORT: {
992       processmsg_gcmarkreport_I();
993       break;
994     } 
995
996     case GCMARKEDOBJ: {
997       processmsg_gcmarkedobj_I();
998       break;
999     } 
1000
1001     case GCMOVESTART: {
1002       // received a start moving objs msg
1003       processmsg_gcmovestart_I();
1004       break;
1005     } 
1006
1007     case GCLOBJREQUEST: {
1008       // received a large objs info request msg
1009       transferMarkResults_I();
1010       break;
1011     } 
1012
1013     case GCREQBLOCK: {
1014       processmsg_reqblock_I();
1015       break;
1016     }
1017
1018     case GCGRANTBLOCK: {
1019       processmsg_grantblock_I();
1020       break;
1021     }
1022
1023     case GCLOBJINFO: {
1024       // received a large objs info response msg
1025       processmsg_gclobjinfo_I(msglength);
1026       break;
1027     } 
1028
1029 #ifdef GC_PROFILE
1030     case GCPROFILES: {
1031       // received a gcprofiles msg
1032       processmsg_gcprofiles_I();
1033       break;
1034     }
1035 #endif // GC_PROFILE
1036
1037 #ifdef GC_CACHE_ADAPT
1038     case GCSTARTCACHEPOLICY: {
1039       // received a gcstartcachepolicy msg
1040       processmsg_gcstartcachepolicy_I();
1041       break;
1042     }
1043
1044     case GCFINISHCACHEPOLICY: {
1045       // received a gcfinishcachepolicy msg
1046       processmsg_gcfinishcachepolicy_I();
1047       break;
1048     }
1049
1050     case GCSTARTPREF: {
1051       // received a gcstartpref msg
1052       processmsg_gcstartpref_I();
1053       break;
1054     }
1055
1056     case GCFINISHPREF: {
1057       // received a gcfinishpref msg
1058       processmsg_gcfinishpref_I();
1059       break;
1060     }
1061 #endif
1062 #endif 
1063
1064     default:
1065       break;
1066     }
1067
1068     if((msgdataindex != msgdatalast) || (msgdatafull)) {
1069       // still have available msg
1070       goto processmsg;
1071     }
1072
1073     // have new coming msg
1074     if(BAMBOO_MSG_AVAIL() != 0) {
1075       goto msg;
1076     } 
1077
1078     PROFILE_INTERRUPT_END();
1079     return (int)type;
1080   } else {
1081     // not a whole msg
1082     return -2;
1083   }
1084 }
1085 #endif // MULTICORE