Make SPECjbb compile again
[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 "multicoretaskprofile.h"
6 #include "gcqueue.h"
7 #ifdef MGC
8 #include "structdefs.h"
9 #include "runtime_arch.h"
10
11 extern int corenum;
12 #endif
13
14 int msgsizearray[] = {
15   0, //MSGSTART,
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
33 #ifdef MULTICORE_GC
34   1, //GCSTARTPRE,            // 0xE2
35   1, //GCSTARTINIT,           // 0xE3
36   1, //GCSTART,               // 0xE4
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
51 #ifdef GC_PROFILE
52   4, //GCPROFILES,            // 0xF3
53 #endif // GC_PROFILE
54 #ifdef GC_CACHE_ADAPT
55   1, //GCSTARTPREF,           // 0xF5
56   2, //GCFINISHPREF,          // 0xF7
57 #endif // GC_CACHE_ADAPT
58 #endif // MULTICORE_GC
59   -1 //MSGEND
60 };
61
62 INLINE unsigned int checkMsgLength_I(unsigned int * type) {
63 #if (defined(TASK)||defined(MULTICORE_GC))
64   unsigned int realtype = msgdata[msgdataindex];
65   *type=realtype&0xff;
66 #else
67   *type = msgdata[msgdataindex];
68 #endif
69   if(*type>MSGEND) {
70     // invalid msg type
71     BAMBOO_EXIT();
72   }
73 #ifdef TASK
74 #ifdef MULTICORE_GC
75   if(*type==TRANSOBJ||*type==GCLOBJINFO) {
76 #else
77   if(*type==TRANSOBJ) {
78 #endif
79 #elif MULTICORE_GC
80   if (*type==GCLOBJINFO) {
81 #endif
82 #if (defined(TASK)||defined(MULTICORE_GC))
83     return realtype>>8;
84   }
85 #endif
86   return msgsizearray[*type];
87 }
88
89 #ifdef TASK
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);
93
94   // store the object and its corresponding queue info, enqueue it later
95   transObj->objptr = (void *)msgdata[msgdataindex]; 
96   MSG_INDEXINC_I();
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];  
101     MSG_INDEXINC_I();
102     transObj->queues[2*k+1] = msgdata[msgdataindex]; 
103     MSG_INDEXINC_I();
104   }
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);
112       RUNFREE_I(tmpinfo);
113       removeItem(&objqueue, qitem);
114       //break;
115     } else {
116       prev = qitem;
117     }
118   }
119   addNewItem_I(&objqueue, (void *)transObj);
120   
121   self_numreceiveobjs++;
122 #ifdef MULTICORE_GC
123   if(gcprocessing) {
124     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
125       // set the gcprecheck to enable checking again
126       gcprecheck = true;
127     } else {
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);
131       } else {
132         send_msg_4_I(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs, self_numreceiveobjs);
133       }
134     }
135   }
136 #endif 
137 }
138 #endif
139
140 INLINE void processmsg_transtall_I() {
141   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
142   
143   int num_core = msgdata[msgdataindex];
144   MSG_INDEXINC_I();
145   int data2 = msgdata[msgdataindex]; 
146   MSG_INDEXINC_I();
147   int data3 = msgdata[msgdataindex];
148   MSG_INDEXINC_I();
149   if(num_core < NUMCORESACTIVE) {
150     corestatus[num_core] = 0;
151     numsendobjs[num_core] = data2; 
152     numreceiveobjs[num_core] = data3; 
153   }
154 }
155
156 #ifndef MULTICORE_GC
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]; 
161   MSG_INDEXINC_I();
162   int data2 = msgdata[msgdataindex];  // obj pointer
163   MSG_INDEXINC_I();
164   int data3 = msgdata[msgdataindex];  // lock
165   MSG_INDEXINC_I();
166   int data4 = msgdata[msgdataindex];  // request core
167   MSG_INDEXINC_I();
168   // -1: redirected, 0: approved, 1: denied
169   int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
170   if(deny != -1) {
171     // send response msg
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);
176     } else {
177       send_msg_4_I(data4,tmp,locktype,data2,data3);
178     }
179   }
180 }
181
182 INLINE void processmsg_lockgrount_I() {
183   MSG_INDEXINC_I();
184   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
185   int data2 = msgdata[msgdataindex];
186   MSG_INDEXINC_I();
187   int data3 = msgdata[msgdataindex];
188   MSG_INDEXINC_I();
189   BAMBOO_ASSERT((lockobj == data2) && (lock2require == data3));
190   lockresult = 1;
191   lockflag = true;
192 #ifndef INTERRUPT
193   reside = false;
194 #endif
195 }
196
197 INLINE void processmsg_lockdeny_I() {
198   MSG_INDEXINC_I();
199   int data2 = msgdata[msgdataindex];
200   MSG_INDEXINC_I();
201   int data3 = msgdata[msgdataindex];
202   MSG_INDEXINC_I();
203   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
204   BAMBOO_ASSERT((lockobj == data2) && (lock2require == data3));
205   lockresult = 0;
206   lockflag = true;
207 #ifndef INTERRUPT
208   reside = false;
209 #endif
210 }
211
212 INLINE void processmsg_lockrelease_I() {
213   int data1 = msgdata[msgdataindex];
214   MSG_INDEXINC_I();
215   int data2 = msgdata[msgdataindex];
216   MSG_INDEXINC_I();
217   int data3 = msgdata[msgdataindex];
218   MSG_INDEXINC_I();
219   // receive lock release msg
220   processlockrelease(data1, data2, 0, false);
221 }
222
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);
236   if(deny != -1) {
237     // send response msg
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);
241     } else {
242       send_msg_4_I(data4,deny==1?REDIRECTDENY:REDIRECTGROUNT,data1,data2,data3);
243     }
244   }
245 }
246
247 INLINE void processmsg_redirectgrount_I() {
248   MSG_INDEXINC_I();
249   int data2 = msgdata[msgdataindex];
250   MSG_INDEXINC_I();
251   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
252   BAMBOO_ASSERT(lockobj == data2, 0xe207);
253   int data3 = msgdata[msgdataindex];
254   MSG_INDEXINC_I();
255   lockresult = 1;
256   lockflag = true;
257   RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
258 #ifndef INTERRUPT
259   reside = false;
260 #endif
261 }
262
263 INLINE void processmsg_redirectdeny_I() {
264   MSG_INDEXINC_I();
265   int data2 = msgdata[msgdataindex];
266   MSG_INDEXINC_I();
267   int data3 = msgdata[msgdataindex];
268   MSG_INDEXINC_I();
269   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1);
270   BAMBOO_ASSERT(lockobj == data2);
271   lockresult = 0;
272   lockflag = true;
273 #ifndef INTERRUPT
274   reside = false;
275 #endif
276 }
277
278 INLINE void processmsg_redirectrelease_I() {
279   int data1 = msgdata[msgdataindex];
280   MSG_INDEXINC_I();
281   int data2 = msgdata[msgdataindex];
282   MSG_INDEXINC_I();
283   int data3 = msgdata[msgdataindex];
284   MSG_INDEXINC_I();
285   processlockrelease_I(data1, data2, data3, true);
286 }
287 #endif // #ifndef MULTICORE_GC
288
289 #ifdef PROFILE
290 INLINE void processmsg_profileoutput_I() {
291   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE != STARTUPCORE);
292   stall = true;
293   totalexetime = msgdata[msgdataindex];
294   MSG_INDEXINC_I();
295 #ifdef RT_TEST
296 #else
297   outputProfileData();
298 #endif
299   // cache the msg first
300   if(BAMBOO_CHECK_SEND_MODE()) {
301     cache_msg_2_I(STARTUPCORE,PROFILEFINISH,BAMBOO_NUM_OF_CORE);
302   } else {
303     send_msg_2_I(STARTUPCORE,PROFILEFINISH,BAMBOO_NUM_OF_CORE);
304   }
305 }
306
307 INLINE void processmsg_profilefinish_I() {
308   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
309   int data1 = msgdata[msgdataindex];
310   MSG_INDEXINC_I();
311   profilestatus[data1] = 0;
312 }
313 #endif // PROFILE
314
315 INLINE void processmsg_statusconfirm_I() {
316   BAMBOO_ASSERT(((BAMBOO_NUM_OF_CORE != STARTUPCORE) && (BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1)));
317   // send response msg
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);
321   } else {
322     send_msg_5_I(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
323   }
324 }
325
326 INLINE void processmsg_statusreport_I() {
327   int data1 = msgdata[msgdataindex];
328   MSG_INDEXINC_I();
329   int data2 = msgdata[msgdataindex];
330   MSG_INDEXINC_I();
331   int data3 = msgdata[msgdataindex];
332   MSG_INDEXINC_I();
333   int data4 = msgdata[msgdataindex];
334   MSG_INDEXINC_I();
335   // receive a status confirm info
336   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
337   if(waitconfirm) {
338     numconfirm--;
339   }
340   corestatus[data2] = data1;
341   numsendobjs[data2] = data3;
342   numreceiveobjs[data2] = data4;
343 }
344
345 INLINE void processmsg_terminate_I() {
346   disruntimedata();
347 #ifdef MULTICORE_GC
348 #ifdef GC_CACHE_ADAPT
349   bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
350 #endif
351 #endif
352   BAMBOO_EXIT_APP(0);
353 }
354
355 INLINE void processmsg_memrequest_I() {
356   int data1 = msgdata[msgdataindex];
357   MSG_INDEXINC_I();
358   int data2 = msgdata[msgdataindex];
359   MSG_INDEXINC_I();
360   // receive a shared memory request msg
361   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
362   int allocsize = 0;
363   void * mem = NULL;
364 #ifdef MULTICORE_GC
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
368 #endif
369     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,mem,allocsize);
374       } else {
375         send_msg_3_I(data2,MEMRESPONSE,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 INLINE void processmsg_memresponse_I() {
385   int data1 = msgdata[msgdataindex];
386   MSG_INDEXINC_I();
387   int data2 = 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(!gcprocessing) {
393 #endif
394   if(data2 == 0) {
395 #ifdef MULTICORE_GC
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 
399     // strategy.
400     BAMBOO_CLOSE_CUR_MSP();
401     bamboo_smem_zero_top = NULL;
402 #endif
403     bamboo_smem_size = 0;
404     bamboo_cur_msp = 0;
405   } else {
406 #ifdef MULTICORE_GC
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;
411 #else
412     bamboo_smem_size = data2;
413     bamboo_cur_msp =(void*)(data1);
414 #endif
415   }
416   smemflag = true;
417 #ifdef MULTICORE_GC
418   }
419 #endif
420 }
421
422 #ifdef MULTICORE_GC
423 INLINE void processmsg_gcstartpre_I() {
424   // the first time to be informed to start gc
425   gcflag = true;
426   if(!smemflag) {
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 
430     // strategy.
431     BAMBOO_CLOSE_CUR_MSP();
432     bamboo_smem_size = 0;
433     bamboo_cur_msp = NULL;
434     smemflag = true;
435     bamboo_smem_zero_top = NULL;
436   }
437 }
438
439 INLINE void processmsg_gcstartinit_I() {
440   gcphase = INITPHASE;
441 }
442
443 INLINE void processmsg_gcstart_I() {
444   // set the GC flag
445   gcphase = MARKPHASE;
446 }
447
448 INLINE void processmsg_gcstartcompact_I() {
449   gcblock2fill = msgdata[msgdataindex];
450   MSG_INDEXINC_I();  
451   gcphase = COMPACTPHASE;
452 }
453
454 INLINE void processmsg_gcstartflush_I() {
455   gcphase = FLUSHPHASE;
456 }
457
458 INLINE void processmsg_gcfinishpre_I() {
459   int data1 = msgdata[msgdataindex];
460   MSG_INDEXINC_I();
461   int data2 = msgdata[msgdataindex];
462   MSG_INDEXINC_I();
463   int data3 = msgdata[msgdataindex];
464   MSG_INDEXINC_I();
465   // received a init phase finish msg
466   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
467
468   // All cores should do init GC
469   gcprecheck = true;
470   gccorestatus[data1] = 0;
471   gcnumsendobjs[0][data1] = data2;
472   gcnumreceiveobjs[0][data1] = data3;
473 }
474
475 INLINE void processmsg_gcfinishinit_I() {
476   int data1 = msgdata[msgdataindex];
477   MSG_INDEXINC_I();
478   // received a init phase finish msg
479   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
480
481   // All cores should do init GC
482   if(data1 < NUMCORESACTIVE) {
483     gccorestatus[data1] = 0;
484   }
485 }
486
487 INLINE void processmsg_gcfinishmark_I() {
488   int data1 = msgdata[msgdataindex];
489   MSG_INDEXINC_I();
490   int data2 = msgdata[msgdataindex];
491   MSG_INDEXINC_I();
492   int data3 = msgdata[msgdataindex];
493   MSG_INDEXINC_I();
494   // received a mark phase finish msg
495   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
496
497   // all cores should do mark
498   if(data1 < NUMCORESACTIVE) {
499     gccorestatus[data1] = 0;
500     int entry_index = 0;
501     if(waitconfirm)  {
502       // phase 2
503       entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
504     } else {
505       // phase 1
506       entry_index = gcnumsrobjs_index;
507     }
508     gcnumsendobjs[entry_index][data1] = data2;
509     gcnumreceiveobjs[entry_index][data1] = data3;
510   }
511 }
512
513 INLINE void processmsg_gcfinishcompact_I() {
514   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
515
516   int cnum = msgdata[msgdataindex];
517   MSG_INDEXINC_I();      
518   int filledblocks = msgdata[msgdataindex];
519   MSG_INDEXINC_I();    
520   int heaptop = msgdata[msgdataindex];
521   MSG_INDEXINC_I();   
522   int data4 = msgdata[msgdataindex];
523   MSG_INDEXINC_I(); 
524   // only gc cores need to do compact
525   if(cnum < NUMCORES4GC) {
526     if(COMPACTPHASE == gcphase) {
527       gcfilledblocks[cnum] = filledblocks;
528       gcloads[cnum] = heaptop;
529     }
530     if(data4 > 0) {
531       // ask for more mem
532       int startaddr = 0;
533       int tomove = 0;
534       int dstcore = 0;
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);
539         } else {
540           send_msg_4_I(cnum,GCMOVESTART,dstcore,startaddr,tomove);
541         }
542       }
543     } else {
544       gccorestatus[cnum] = 0;
545     } 
546   }  
547 }
548
549 INLINE void processmsg_gcfinishflush_I() {
550   int data1 = msgdata[msgdataindex];
551   MSG_INDEXINC_I();
552   // received a flush phase finish msg
553   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
554
555   // all cores should do flush
556   if(data1 < NUMCORESACTIVE) {
557     gccorestatus[data1] = 0;
558   }
559 }
560
561 INLINE void processmsg_gcfinish_I() {
562   // received a GC finish msg
563   gcphase = FINISHPHASE;
564   gcprocessing = false;
565 }
566
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);
573   } else {
574     send_msg_5_I(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gcbusystatus,gcself_numsendobjs,gcself_numreceiveobjs);
575   }
576 }
577
578 INLINE void processmsg_gcmarkreport_I() {
579   int data1 = msgdata[msgdataindex];
580   MSG_INDEXINC_I();
581   int data2 = msgdata[msgdataindex];
582   MSG_INDEXINC_I();
583   int data3 = msgdata[msgdataindex];
584   MSG_INDEXINC_I();
585   int data4 = msgdata[msgdataindex];
586   MSG_INDEXINC_I();
587   // received a marked phase finish confirm response msg
588   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
589   int entry_index = 0;
590   BAMBOO_ASSERT(waitconfirm);
591
592   // phase 2
593   numconfirm--;
594   entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
595   gccorestatus[data1] = data2;
596   gcnumsendobjs[entry_index][data1] = data3;
597   gcnumreceiveobjs[entry_index][data1] = data4;
598
599 }
600
601 INLINE void processmsg_gcmarkedobj_I() {
602   int data1 = msgdata[msgdataindex];
603   MSG_INDEXINC_I();
604   BAMBOO_ASSERT(ISSHAREDOBJ(data1));
605
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;
611     gc_enqueue_I(data1);
612   }
613   gcself_numreceiveobjs++;
614   gcbusystatus = true;
615 }
616
617 INLINE void processmsg_gcmovestart_I() {
618   gctomove = true;
619   gcdstcore = msgdata[msgdataindex];
620   MSG_INDEXINC_I();       
621   gcmovestartaddr = msgdata[msgdataindex];
622   MSG_INDEXINC_I();     
623   gcblock2fill = msgdata[msgdataindex];
624   MSG_INDEXINC_I();     
625 }
626
627 INLINE void processmsg_gclobjinfo_I(unsigned int data1) {
628   numconfirm--;
629   int data2 = msgdata[msgdataindex];
630   MSG_INDEXINC_I();
631   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORES4GC - 1);
632
633   // store the mark result info
634   int cnum = data2;
635   gcloads[cnum] = msgdata[msgdataindex];
636   MSG_INDEXINC_I();     
637   int data4 = msgdata[msgdataindex];
638   MSG_INDEXINC_I();
639   if(gcheaptop < data4) {
640     gcheaptop = data4;
641   }
642   // large obj info here
643   for(int k = 4; k < data1; k+=2) {
644     int lobj = msgdata[msgdataindex];
645     MSG_INDEXINC_I();  
646     int length = msgdata[msgdataindex];
647     MSG_INDEXINC_I();   
648     gc_lobjenqueue_I(lobj, length, cnum);
649     gcnumlobjs++;
650   }
651 }
652
653 #ifdef GC_PROFILE
654 INLINE void processmsg_gcprofiles_I() {
655   int data1 = msgdata[msgdataindex];
656   MSG_INDEXINC_I();
657   int data2 = msgdata[msgdataindex];
658   MSG_INDEXINC_I();
659   int data3 = msgdata[msgdataindex];
660   MSG_INDEXINC_I();
661 #ifdef MGC_SPEC
662   if(gc_profile_flag) {
663 #endif
664     gc_num_obj += data1;
665     gc_num_liveobj += data2;
666     gc_num_forwardobj += data3;
667 #ifdef MGC_SPEC
668   }
669 #endif
670   gc_num_profiles--;
671 }
672 #endif // GC_PROFILE
673
674 #ifdef GC_CACHE_ADAPT
675 INLINE void processmsg_gcstartpref_I() {
676   gcphase = PREFINISHPHASE;
677 }
678
679 INLINE void processmsg_gcfinishpref_I() {
680   int data1 = msgdata[msgdataindex];
681   MSG_INDEXINC_I();
682   // received a flush phase finish msg
683   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
684
685   // all cores should do flush
686   if(data1 < NUMCORESACTIVE) {
687     gccorestatus[data1] = 0;
688   }
689 }
690 #endif // GC_CACHE_ADAPT
691 #endif // #ifdef MULTICORE_GC
692
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
700 //      !-1--object
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(); 
709 msg:
710   // get the incoming msgs
711   receiveMsg_I();
712   if((msgdataindex == msgdatalast) && (!msgdatafull)) {
713     return -1;
714   }
715   if(BAMBOO_CHECK_SEND_MODE()) {
716     // during send, don't process the msg now
717     return -3; 
718   }
719 processmsg:
720   // processing received msgs
721   int size = 0;
722   MSG_REMAINSIZE_I(&size);
723   if(size == 0) {
724     // not a whole msg
725     // have new coming msg
726     if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
727       goto msg;
728     } else {
729       return -1;
730     }
731   }
732
733   //we only ever read the first word
734   MSGTYPE type;
735   unsigned int msglength = checkMsgLength_I((unsigned int*)(&type));
736   
737   if(msglength <= size) {
738     // have some whole msg
739     MSG_INDEXINC_I();
740     msgdatafull = false;
741     switch(type) {
742 #ifdef TASK
743     case TRANSOBJ: {
744       // receive a object transfer msg
745       processmsg_transobj_I(msglength);
746       break;
747     }  
748 #endif 
749     case TRANSTALL: {
750       // receive a stall msg
751       processmsg_transtall_I();
752       break;
753     }   
754
755 #ifdef TASK
756     // GC version have no lock msgs
757 #ifndef MULTICORE_GC
758     case LOCKREQUEST: {
759       // receive lock request msg, handle it right now
760       processmsg_lockrequest_I();
761       break;
762     }   
763     case LOCKGROUNT: {
764       // receive lock grount msg
765       processmsg_lockgrount_I();
766       break;
767     } 
768     case LOCKDENY: {
769       // receive lock deny msg
770       processmsg_lockdeny_I();
771       break;
772     }  
773     case LOCKRELEASE: {
774       processmsg_lockrelease_I();
775       break;
776     }   
777 #endif
778
779 #ifdef PROFILE
780     case PROFILEOUTPUT: {
781       // receive an output profile data request msg
782       processmsg_profileoutput_I();
783       break;
784     }   
785     case PROFILEFINISH: {
786       // receive a profile output finish msg
787       processmsg_profilefinish_I();
788       break;
789     }  
790 #endif 
791
792     // GC version has no lock msgs
793 #ifndef MULTICORE_GC
794     case REDIRECTLOCK: {
795       // receive a redirect lock request msg, handle it right now
796       processmsg_redirectlock_I();
797       break;
798     }  
799
800     case REDIRECTGROUNT: {
801       // receive a lock grant msg with redirect info
802       processmsg_redirectgrount_I();
803       break;
804     } 
805
806     case REDIRECTDENY: {
807       // receive a lock deny msg with redirect info
808       processmsg_redirectdeny_I();
809       break;
810     }   
811
812     case REDIRECTRELEASE: {
813       // receive a lock release msg with redirect info
814       processmsg_redirectrelease_I();
815       break;
816     }   // case REDIRECTRELEASE
817 #endif
818 #endif 
819
820     case STATUSCONFIRM: {
821       // receive a status confirm info
822       processmsg_statusconfirm_I();
823       break;
824     }  
825
826     case STATUSREPORT: {
827       processmsg_statusreport_I();
828       break;
829     } 
830
831     case TERMINATE: {
832       // receive a terminate msg
833       processmsg_terminate_I();
834       break;
835     } 
836
837     case MEMREQUEST: {
838       processmsg_memrequest_I();
839       break;
840     }
841
842     case MEMRESPONSE: {
843       processmsg_memresponse_I();
844       break;
845     }
846
847 #ifdef MULTICORE_GC
848     // GC msgs
849     case GCSTARTPRE: {
850       processmsg_gcstartpre_I();
851       break;
852     }
853         
854     case GCSTARTINIT: {
855       processmsg_gcstartinit_I();
856       break;
857     }
858
859     case GCSTART: {
860       // receive a start GC msg
861       processmsg_gcstart_I();
862       break;
863     }
864
865     case GCSTARTCOMPACT: {
866       // a compact phase start msg
867       processmsg_gcstartcompact_I();
868       break;
869     }
870
871     case GCSTARTFLUSH: {
872       // received a flush phase start msg
873       processmsg_gcstartflush_I();
874       break;
875     }
876
877     case GCFINISHPRE: {
878       processmsg_gcfinishpre_I();
879       break;
880     }
881         
882     case GCFINISHINIT: {
883       processmsg_gcfinishinit_I();
884       break;
885     }
886
887     case GCFINISHMARK: {
888       processmsg_gcfinishmark_I();
889       break;
890     }
891
892     case GCFINISHCOMPACT: {
893       // received a compact phase finish msg
894       processmsg_gcfinishcompact_I();
895       break;
896     }
897
898     case GCFINISHFLUSH: {
899       processmsg_gcfinishflush_I();
900       break;
901     }  
902
903     case GCFINISH: {
904       processmsg_gcfinish_I();
905       break;
906     } 
907
908     case GCMARKCONFIRM: {
909       // received a marked phase finish confirm request msg
910       // all cores should do mark
911       processmsg_gcmarkconfirm_I();
912       break;
913     } 
914
915     case GCMARKREPORT: {
916       processmsg_gcmarkreport_I();
917       break;
918     } 
919
920     case GCMARKEDOBJ: {
921       processmsg_gcmarkedobj_I();
922       break;
923     } 
924
925     case GCMOVESTART: {
926       // received a start moving objs msg
927       processmsg_gcmovestart_I();
928       break;
929     } 
930
931     case GCLOBJREQUEST: {
932       // received a large objs info request msg
933       transferMarkResults_I();
934       break;
935     } 
936
937     case GCLOBJINFO: {
938       // received a large objs info response msg
939       processmsg_gclobjinfo_I(msglength);
940       break;
941     } 
942
943 #ifdef GC_PROFILE
944     case GCPROFILES: {
945       // received a gcprofiles msg
946       processmsg_gcprofiles_I();
947       break;
948     }
949 #endif // GC_PROFILE
950
951 #ifdef GC_CACHE_ADAPT
952     case GCSTARTPREF: {
953       // received a gcstartpref msg
954       processmsg_gcstartpref_I();
955       break;
956     }
957
958     case GCFINISHPREF: {
959       // received a gcfinishpref msg
960       processmsg_gcfinishpref_I();
961       break;
962     }
963 #endif
964 #endif 
965
966     default:
967       break;
968     }
969
970     if((msgdataindex != msgdatalast) || (msgdatafull)) {
971       // still have available msg
972       goto processmsg;
973     }
974
975     // have new coming msg
976     if(BAMBOO_MSG_AVAIL() != 0) {
977       goto msg;
978     } 
979
980     PROFILE_INTERRUPT_END();
981     return (int)type;
982   } else {
983     // not a whole msg
984     return -2;
985   }
986 }
987 #endif // MULTICORE