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