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