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