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