get it to 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 "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   3, //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  -1, //GCLOBJINFO,            // 0xF2
49 #ifdef GC_PROFILE
50   4, //GCPROFILES,            // 0xF3
51 #endif // GC_PROFILE
52 #ifdef GC_CACHE_ADAPT
53   1, //GCSTARTCACHEPOLICY     // 0xF4
54   2, //GCFINISHCACHEPOLICY    // 0xF5
55   1, //GCSTARTPREF,           // 0xF6
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(gc_status_info.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_1_I(STARTUPCORE,PROFILEFINISH);
298   } else {
299     send_msg_1_I(STARTUPCORE,PROFILEFINISH);
300   }
301 }
302
303 INLINE void processmsg_profilefinish_I() {
304   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
305   numconfirm--;
306 }
307 #endif // PROFILE
308
309 INLINE void processmsg_statusconfirm_I() {
310   BAMBOO_ASSERT(((BAMBOO_NUM_OF_CORE != STARTUPCORE) && (BAMBOO_NUM_OF_CORE <= NUMCORESACTIVE - 1)));
311   // send response msg
312   // cache the msg first
313   if(BAMBOO_CHECK_SEND_MODE()) {
314     cache_msg_5_I(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
315   } else {
316     send_msg_5_I(STARTUPCORE,STATUSREPORT,busystatus?1:0,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
317   }
318 }
319
320 INLINE void processmsg_statusreport_I() {
321   int data1 = msgdata[msgdataindex];
322   MSG_INDEXINC_I();
323   int data2 = msgdata[msgdataindex];
324   MSG_INDEXINC_I();
325   int data3 = msgdata[msgdataindex];
326   MSG_INDEXINC_I();
327   int data4 = msgdata[msgdataindex];
328   MSG_INDEXINC_I();
329   // receive a status confirm info
330   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
331   if(waitconfirm) {
332     numconfirm--;
333   }
334   corestatus[data2] = data1;
335   numsendobjs[data2] = data3;
336   numreceiveobjs[data2] = data4;
337 }
338
339 INLINE void processmsg_terminate_I() {
340   disruntimedata();
341 #ifdef MULTICORE_GC
342 #ifdef GC_CACHE_ADAPT
343   bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
344 #endif
345 #endif
346   BAMBOO_EXIT_APP(0);
347 }
348
349 INLINE void processmsg_memrequest_I() {
350   int data1 = msgdata[msgdataindex];
351   MSG_INDEXINC_I();
352   int data2 = msgdata[msgdataindex];
353   MSG_INDEXINC_I();
354   // receive a shared memory request msg
355   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
356   int allocsize = 0;
357   void * mem = NULL;
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     mem = smemalloc_I(data2, data1, &allocsize);
364     if(mem != NULL) {
365       // send the start_va to request core, cache the msg first
366       if(BAMBOO_CHECK_SEND_MODE()) {
367         cache_msg_3_I(data2,MEMRESPONSE,mem,allocsize);
368       } else {
369         send_msg_3_I(data2,MEMRESPONSE,mem,allocsize);
370       }
371     } //else if mem == NULL, the gcflag of the startup core has been set
372     // and all the other cores have been informed to start gc
373 #ifdef MULTICORE_GC
374   }
375 #endif
376 }
377
378 INLINE void processmsg_memresponse_I() {
379   void * memptr = msgdata[msgdataindex];
380   MSG_INDEXINC_I();
381   unsigned int numbytes = msgdata[msgdataindex];
382   MSG_INDEXINC_I();
383   // receive a shared memory response msg
384 #ifdef MULTICORE_GC
385   // if is currently doing gc, dump this msg
386   if(!gc_status_info.gcprocessing) {
387 #endif
388   if(numbytes == 0) {
389 #ifdef MULTICORE_GC
390     bamboo_smem_zero_top = NULL;
391 #endif
392     bamboo_smem_size = 0;
393     bamboo_cur_msp = NULL;
394   } else {
395 #ifdef MULTICORE_GC
396     bamboo_smem_size = numbytes;
397     bamboo_cur_msp = memptr;
398     bamboo_smem_zero_top = bamboo_cur_msp;
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   if(!smemflag) {
415     // Zero out the remaining memory here because for the GC_CACHE_ADAPT 
416     // version, we need to make sure during the gcinit phase the shared heap 
417     // is not touched. Otherwise, there would be problem when adapt the cache 
418     // strategy.
419     bamboo_smem_size = 0;
420     bamboo_cur_msp = NULL;
421     smemflag = true;
422     bamboo_smem_zero_top = NULL;
423   }
424 }
425
426 INLINE void processmsg_gcstartinit_I() {
427   gc_status_info.gcphase = INITPHASE;
428 }
429
430 INLINE void processmsg_gcstart_I() {
431   // set the GC flag
432   gc_status_info.gcphase = MARKPHASE;
433 }
434
435 INLINE void processmsg_gcstartcompact_I() {
436   gcblock2fill = msgdata[msgdataindex];
437   MSG_INDEXINC_I();  
438   gc_status_info.gcphase = COMPACTPHASE;
439 }
440
441 INLINE void processmsg_gcstartupdate_I() {
442   gc_status_info.gcphase = UPDATEPHASE;
443 }
444
445 INLINE void processmsg_gcfinishpre_I() {
446   int data1 = msgdata[msgdataindex];
447   MSG_INDEXINC_I();
448   int data2 = msgdata[msgdataindex];
449   MSG_INDEXINC_I();
450   int data3 = msgdata[msgdataindex];
451   MSG_INDEXINC_I();
452   // received a init phase finish msg
453   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
454
455   // All cores should do init GC
456   gcprecheck = true;
457   gccorestatus[data1] = 0;
458   gcnumsendobjs[0][data1] = data2;
459   gcnumreceiveobjs[0][data1] = data3;
460 }
461
462 INLINE void processmsg_gcfinishinit_I() {
463   int data1 = 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   if(data1 < NUMCORESACTIVE) {
470     gccorestatus[data1] = 0;
471   }
472 }
473
474 INLINE void processmsg_gcfinishmark_I() {
475   int data1 = msgdata[msgdataindex];
476   MSG_INDEXINC_I();
477   int data2 = msgdata[msgdataindex];
478   MSG_INDEXINC_I();
479   int data3 = msgdata[msgdataindex];
480   MSG_INDEXINC_I();
481   // received a mark phase finish msg
482   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
483
484   // all cores should do mark
485   if(data1 < NUMCORESACTIVE) {
486     gccorestatus[data1] = 0;
487     int entry_index = 0;
488     if(waitconfirm)  {
489       // phase 2
490       entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
491     } else {
492       // phase 1
493       entry_index = gcnumsrobjs_index;
494     }
495     gcnumsendobjs[entry_index][data1] = data2;
496     gcnumreceiveobjs[entry_index][data1] = data3;
497   }
498 }
499  
500 void processmsg_returnmem_I() {
501   unsigned int cnum = msgdata[msgdataindex];
502   MSG_INDEXINC_I();  
503   void * heaptop = (void *) msgdata[msgdataindex];
504   MSG_INDEXINC_I();   
505   unsigned int blockindex;
506   BLOCKINDEX(blockindex, heaptop);
507   unsigned INTPTR localblocknum=GLOBALBLOCK2LOCAL(blockindex);
508
509   struct blockrecord * blockrecord=&allocationinfo.blocktable[blockindex];
510
511   blockrecord->status=BS_FREE;
512   blockrecord->usedspace=(unsigned INTPTR)(heaptop-OFFSET2BASEVA(blockindex));
513   blockrecord->freespace=BLOCKSIZE(localblocknum)-blockrecord->usedspace;
514   /* Update the lowest free block */
515   if (blockindex < allocationinfo.lowestfreeblock) {
516     blockindex=allocationinfo.lowestfreeblock;
517   }
518
519   /* This is our own block...means we should mark other blocks above us as free*/
520   if (cnum==blockrecord->corenum) {
521     unsigned INTPTR nextlocalblocknum=localblocknum+1;
522     for(;nextlocalblocknum<numblockspercore;nextlocalblocknum++) {
523       unsigned INTPTR blocknum=BLOCKINDEX2(cnum, nextlocalblocknum);
524       struct blockrecord * nextblockrecord=&allocationinfo.blocktable[blockindex];
525       nextblockrecord->status=BS_FREE;
526       nextblockrecord->usedspace=0;
527       //this is true because this cannot be the lowest block
528       nextblockrecord->freespace=BLOCKSIZE(1);
529     }
530   }
531 }
532
533 INLINE void processmsg_gcfinishcompact_I() {
534   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
535
536   int cnum = msgdata[msgdataindex];
537   MSG_INDEXINC_I();  
538   unsigned int bytesneeded = msgdata[msgdataindex];
539   MSG_INDEXINC_I(); 
540
541   if(bytesneeded > 0) {
542     // ask for more mem
543     void * startaddr = gcfindSpareMem_I(bytesneeded, cnum);
544     if(startaddr) {
545       // cache the msg first
546       if(BAMBOO_CHECK_SEND_MODE()) {
547         cache_msg_2_I(cnum,GCMOVESTART,startaddr);
548       } else {
549         send_msg_2_I(cnum,GCMOVESTART,startaddr);
550       }
551     }
552   } else {
553     //done with compacting
554     gccorestatus[cnum] = 0;
555   }
556 }
557
558 INLINE void processmsg_gcfinishupdate_I() {
559   int data1 = msgdata[msgdataindex];
560   MSG_INDEXINC_I();
561   // received a update phase finish msg
562   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
563
564   // all cores should do update
565   if(data1 < NUMCORESACTIVE) {
566     gccorestatus[data1] = 0;
567   }
568 }
569
570 INLINE void processmsg_gcfinish_I() {
571   // received a GC finish msg
572   gc_status_info.gcphase = FINISHPHASE;
573   gc_status_info.gcprocessing = false;
574 }
575
576 INLINE void processmsg_gcmarkconfirm_I() {
577   BAMBOO_ASSERT(((BAMBOO_NUM_OF_CORE!=STARTUPCORE)&&(BAMBOO_NUM_OF_CORE<=NUMCORESACTIVE-1)));
578   gc_status_info.gcbusystatus = gc_moreItems_I();
579   // send response msg, cahce the msg first
580   if(BAMBOO_CHECK_SEND_MODE()) {
581     cache_msg_5_I(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gc_status_info.gcbusystatus,gcself_numsendobjs,gcself_numreceiveobjs);
582   } else {
583     send_msg_5_I(STARTUPCORE,GCMARKREPORT,BAMBOO_NUM_OF_CORE,gc_status_info.gcbusystatus,gcself_numsendobjs,gcself_numreceiveobjs);
584   }
585 }
586
587 INLINE void processmsg_gcmarkreport_I() {
588   int data1 = msgdata[msgdataindex];
589   MSG_INDEXINC_I();
590   int data2 = msgdata[msgdataindex];
591   MSG_INDEXINC_I();
592   int data3 = msgdata[msgdataindex];
593   MSG_INDEXINC_I();
594   int data4 = msgdata[msgdataindex];
595   MSG_INDEXINC_I();
596   // received a marked phase finish confirm response msg
597   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
598   int entry_index = 0;
599   BAMBOO_ASSERT(waitconfirm);
600
601   // phase 2
602   numconfirm--;
603   entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
604   gccorestatus[data1] = data2;
605   gcnumsendobjs[entry_index][data1] = data3;
606   gcnumreceiveobjs[entry_index][data1] = data4;
607
608 }
609
610 INLINE void processmsg_gcmarkedobj_I() {
611   void * objptr = (void *) msgdata[msgdataindex];
612   MSG_INDEXINC_I();
613   
614   // received a markedObj msg
615   if(!checkMark(objptr)) {
616     // this is the first time that this object is discovered,
617     // set the flag as DISCOVERED
618     setMark(objptr);
619     gc_enqueue_I(objptr);
620   }
621   gcself_numreceiveobjs++;
622   gc_status_info.gcbusystatus = true;
623 }
624
625 INLINE void processmsg_gcmovestart_I() {
626   gctomove = true;
627   gcmovestartaddr = msgdata[msgdataindex];
628   MSG_INDEXINC_I();     
629 }
630
631 INLINE void processmsg_gclobjinfo_I(unsigned int msglength) {
632   numconfirm--;
633   int cnum = msgdata[msgdataindex];
634   MSG_INDEXINC_I();
635   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE <= NUMCORES4GC - 1);
636
637   // store the mark result info
638   gcloads[cnum] = msgdata[msgdataindex];
639   MSG_INDEXINC_I();     
640
641   // large obj info here
642   for(int k = 3; k < msglength; k+=2) {
643     int lobj = msgdata[msgdataindex];
644     MSG_INDEXINC_I();  
645     int length = msgdata[msgdataindex];
646     MSG_INDEXINC_I();   
647     gc_lobjenqueue_I(lobj, length, cnum);
648   }
649 }
650
651 #ifdef GC_PROFILE
652 INLINE void processmsg_gcprofiles_I() {
653   int data1 = msgdata[msgdataindex];
654   MSG_INDEXINC_I();
655   int data2 = msgdata[msgdataindex];
656   MSG_INDEXINC_I();
657   int data3 = msgdata[msgdataindex];
658   MSG_INDEXINC_I();
659 #ifdef MGC_SPEC
660   if(gc_profile_flag) {
661 #endif
662     gc_num_obj += data1;
663     gc_num_liveobj += data2;
664     gc_num_forwardobj += data3;
665 #ifdef MGC_SPEC
666   }
667 #endif
668   gc_num_profiles--;
669 }
670 #endif // GC_PROFILE
671
672 #ifdef GC_CACHE_ADAPT
673 INLINE void processmsg_gcstartcachepolicy_I() {
674   gc_status_info.gcphase = CACHEPOLICYPHASE;
675 }
676
677 INLINE void processmsg_gcfinishcachepolicy_I() {
678   int data1 = msgdata[msgdataindex];
679   MSG_INDEXINC_I();
680   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
681
682   // all cores should do update
683   if(data1 < NUMCORESACTIVE) {
684     gccorestatus[data1] = 0;
685   }
686 }
687
688 INLINE void processmsg_gcstartpref_I() {
689   gc_status_info.gcphase = PREFINISHPHASE;
690 }
691
692 INLINE void processmsg_gcfinishpref_I() {
693   int data1 = msgdata[msgdataindex];
694   MSG_INDEXINC_I();
695   // received a update phase finish msg
696   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
697
698   // all cores should do update
699   if(data1 < NUMCORESACTIVE) {
700     gccorestatus[data1] = 0;
701   }
702 }
703 #endif // GC_CACHE_ADAPT
704 #endif // #ifdef MULTICORE_GC
705
706 // receive object transferred from other cores
707 // or the terminate message from other cores
708 // Should be invoked in critical sections!!
709 // NOTICE: following format is for threadsimulate version only
710 //         RAW version please see previous description
711 // format: type + object
712 // type: -1--stall msg
713 //      !-1--object
714 // return value: 0--received an object
715 //               1--received nothing
716 //               2--received a Stall Msg
717 //               3--received a lock Msg
718 //               RAW version: -1 -- received nothing
719 //                            otherwise -- received msg type
720 int receiveObject_I() {
721   PROFILE_INTERRUPT_START(); 
722 msg:
723   // get the incoming msgs
724   receiveMsg_I();
725   if((msgdataindex == msgdatalast) && (!msgdatafull)) {
726     return -1;
727   }
728   if(BAMBOO_CHECK_SEND_MODE()) {
729     // during send, don't process the msg now
730     return -3; 
731   }
732 processmsg:
733   // processing received msgs
734   int size;
735   MSG_REMAINSIZE_I(size);
736   if(size == 0) {
737     // not a whole msg
738     // have new coming msg
739     if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
740       goto msg;
741     } else {
742       return -1;
743     }
744   }
745
746   //we only ever read the first word
747   unsigned int realtype = msgdata[msgdataindex];
748   unsigned int msglength = checkMsgLength_I(realtype);
749
750 #if (defined(TASK)||defined(MULTICORE_GC))
751   unsigned int type = realtype & 0xff;
752 #else
753   unsigned int type = realtype;
754 #endif
755
756   if(msglength <= size) {
757     // have some whole msg
758     MSG_INDEXINC_I();
759     msgdatafull = false;
760     switch(type) {
761 #ifdef TASK
762     case TRANSOBJ: {
763       // receive a object transfer msg
764       processmsg_transobj_I(msglength);
765       break;
766     }  
767 #endif 
768     case TRANSTALL: {
769       // receive a stall msg
770       processmsg_transtall_I();
771       break;
772     }   
773
774 #ifdef TASK
775     // GC version have no lock msgs
776 #ifndef MULTICORE_GC
777     case LOCKREQUEST: {
778       // receive lock request msg, handle it right now
779       processmsg_lockrequest_I();
780       break;
781     }   
782     case LOCKGROUNT: {
783       // receive lock grount msg
784       processmsg_lockgrount_I();
785       break;
786     } 
787     case LOCKDENY: {
788       // receive lock deny msg
789       processmsg_lockdeny_I();
790       break;
791     }  
792     case LOCKRELEASE: {
793       processmsg_lockrelease_I();
794       break;
795     }   
796 #endif
797
798 #ifdef PROFILE
799     case PROFILEOUTPUT: {
800       // receive an output profile data request msg
801       processmsg_profileoutput_I();
802       break;
803     }   
804     case PROFILEFINISH: {
805       // receive a profile output finish msg
806       processmsg_profilefinish_I();
807       break;
808     }  
809 #endif 
810
811     // GC version has no lock msgs
812 #ifndef MULTICORE_GC
813     case REDIRECTLOCK: {
814       // receive a redirect lock request msg, handle it right now
815       processmsg_redirectlock_I();
816       break;
817     }  
818
819     case REDIRECTGROUNT: {
820       // receive a lock grant msg with redirect info
821       processmsg_redirectgrount_I();
822       break;
823     } 
824
825     case REDIRECTDENY: {
826       // receive a lock deny msg with redirect info
827       processmsg_redirectdeny_I();
828       break;
829     }   
830
831     case REDIRECTRELEASE: {
832       // receive a lock release msg with redirect info
833       processmsg_redirectrelease_I();
834       break;
835     }   // case REDIRECTRELEASE
836 #endif
837 #endif 
838
839     case STATUSCONFIRM: {
840       // receive a status confirm info
841       processmsg_statusconfirm_I();
842       break;
843     }  
844
845     case STATUSREPORT: {
846       processmsg_statusreport_I();
847       break;
848     } 
849
850     case TERMINATE: {
851       // receive a terminate msg
852       processmsg_terminate_I();
853       break;
854     } 
855
856     case MEMREQUEST: {
857       processmsg_memrequest_I();
858       break;
859     }
860
861     case MEMRESPONSE: {
862       processmsg_memresponse_I();
863       break;
864     }
865
866 #ifdef MULTICORE_GC
867     // GC msgs
868     case GCSTARTPRE: {
869       processmsg_gcstartpre_I();
870       break;
871     }
872         
873     case GCSTARTINIT: {
874       processmsg_gcstartinit_I();
875       break;
876     }
877
878     case GCSTART: {
879       // receive a start GC msg
880       processmsg_gcstart_I();
881       break;
882     }
883
884     case GCSTARTCOMPACT: {
885       // a compact phase start msg
886       processmsg_gcstartcompact_I();
887       break;
888     }
889
890     case GCSTARTUPDATE: {
891       // received a update phase start msg
892       processmsg_gcstartupdate_I();
893       break;
894     }
895
896     case GCFINISHPRE: {
897       processmsg_gcfinishpre_I();
898       break;
899     }
900         
901     case GCFINISHINIT: {
902       processmsg_gcfinishinit_I();
903       break;
904     }
905
906     case GCFINISHMARK: {
907       processmsg_gcfinishmark_I();
908       break;
909     }
910
911     case GCRETURNMEM: {
912       processmsg_returnmem_I();
913       break;
914     }
915
916     case GCFINISHCOMPACT: {
917       // received a compact phase finish msg
918       processmsg_gcfinishcompact_I();
919       break;
920     }
921
922     case GCFINISHUPDATE: {
923       processmsg_gcfinishupdate_I();
924       break;
925     }  
926
927     case GCFINISH: {
928       processmsg_gcfinish_I();
929       break;
930     } 
931
932     case GCMARKCONFIRM: {
933       // received a marked phase finish confirm request msg
934       // all cores should do mark
935       processmsg_gcmarkconfirm_I();
936       break;
937     } 
938
939     case GCMARKREPORT: {
940       processmsg_gcmarkreport_I();
941       break;
942     } 
943
944     case GCMARKEDOBJ: {
945       processmsg_gcmarkedobj_I();
946       break;
947     } 
948
949     case GCMOVESTART: {
950       // received a start moving objs msg
951       processmsg_gcmovestart_I();
952       break;
953     } 
954
955     case GCLOBJREQUEST: {
956       // received a large objs info request msg
957       transferMarkResults_I();
958       break;
959     } 
960
961     case GCLOBJINFO: {
962       // received a large objs info response msg
963       processmsg_gclobjinfo_I(msglength);
964       break;
965     } 
966
967 #ifdef GC_PROFILE
968     case GCPROFILES: {
969       // received a gcprofiles msg
970       processmsg_gcprofiles_I();
971       break;
972     }
973 #endif // GC_PROFILE
974
975 #ifdef GC_CACHE_ADAPT
976     case GCSTARTCACHEPOLICY: {
977       // received a gcstartcachepolicy msg
978       processmsg_gcstartcachepolicy_I();
979       break;
980     }
981
982     case GCFINISHCACHEPOLICY: {
983       // received a gcfinishcachepolicy msg
984       processmsg_gcfinishcachepolicy_I();
985       break;
986     }
987
988     case GCSTARTPREF: {
989       // received a gcstartpref msg
990       processmsg_gcstartpref_I();
991       break;
992     }
993
994     case GCFINISHPREF: {
995       // received a gcfinishpref msg
996       processmsg_gcfinishpref_I();
997       break;
998     }
999 #endif
1000 #endif 
1001
1002     default:
1003       break;
1004     }
1005
1006     if((msgdataindex != msgdatalast) || (msgdatafull)) {
1007       // still have available msg
1008       goto processmsg;
1009     }
1010
1011     // have new coming msg
1012     if(BAMBOO_MSG_AVAIL() != 0) {
1013       goto msg;
1014     } 
1015
1016     PROFILE_INTERRUPT_END();
1017     return (int)type;
1018   } else {
1019     // not a whole msg
1020     return -2;
1021   }
1022 }
1023 #endif // MULTICORE