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