changes
[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   4, //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   int data3 = msgdata[msgdataindex];
699   MSG_INDEXINC_I();
700 #ifdef MGC_SPEC
701   if(gc_profile_flag) {
702 #endif
703     gc_num_obj += data1;
704     gc_num_liveobj += data2;
705     gc_num_forwardobj += data3;
706 #ifdef MGC_SPEC
707   }
708 #endif
709   gc_num_profiles--;
710 }
711 #endif // GC_PROFILE
712
713 #ifdef GC_CACHE_ADAPT
714 void processmsg_gcstartcachepolicy_I() {
715   gc_status_info.gcphase = CACHEPOLICYPHASE;
716 }
717
718 void processmsg_gcfinishcachepolicy_I() {
719   int data1 = msgdata[msgdataindex];
720   MSG_INDEXINC_I();
721   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
722
723   // all cores should do update
724   if(data1 < NUMCORESACTIVE) {
725     gccorestatus[data1] = 0;
726   }
727 }
728
729 void processmsg_gcstartpref_I() {
730   gc_status_info.gcphase = PREFINISHPHASE;
731 }
732
733 void processmsg_gcfinishpref_I() {
734   int data1 = msgdata[msgdataindex];
735   MSG_INDEXINC_I();
736   // received a update phase finish msg
737   BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
738
739   // all cores should do update
740   if(data1 < NUMCORESACTIVE) {
741     gccorestatus[data1] = 0;
742   }
743 }
744 #endif // GC_CACHE_ADAPT
745 #endif // #ifdef MULTICORE_GC
746
747 void processmsg_req_notify_start() {
748   startflag=true;
749   if(BAMBOO_CHECK_SEND_MODE()) {
750     cache_msg_1_I(STARTUPCORE,NOTIFYSTART);
751   } else {
752     send_msg_1_I(STARTUPCORE,NOTIFYSTART);
753   }  
754 }
755
756 void processmsg_notify_start() {
757   numconfirm--;
758 }
759
760 // receive object transferred from other cores
761 // or the terminate message from other cores
762 // Should be invoked in critical sections!!
763 // NOTICE: following format is for threadsimulate version only
764 //         RAW version please see previous description
765 // format: type + object
766 // type: -1--stall msg
767 //      !-1--object
768 // return value: 0--received an object
769 //               1--received nothing
770 //               2--received a Stall Msg
771 //               3--received a lock Msg
772 //               RAW version: -1 -- received nothing
773 //                            otherwise -- received msg type
774 int receiveObject_I() {
775   PROFILE_INTERRUPT_START(); 
776 msg:
777   // get the incoming msgs
778   receiveMsg_I();
779   if((msgdataindex == msgdatalast) && (!msgdatafull)) {
780     return -1;
781   }
782   if(BAMBOO_CHECK_SEND_MODE()) {
783     // during send, don't process the msg now
784     return -3; 
785   }
786 processmsg:
787   // processing received msgs
788   int size;
789   MSG_REMAINSIZE_I(size);
790   if(size == 0) {
791     // not a whole msg
792     // have new coming msg
793     if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
794       goto msg;
795     } else {
796       return -1;
797     }
798   }
799
800   //we only ever read the first word
801   unsigned int realtype = msgdata[msgdataindex];
802   unsigned int msglength = checkMsgLength_I(realtype);
803
804 #if (defined(TASK)||defined(MULTICORE_GC))
805   unsigned int type = realtype & 0xff;
806 #else
807   unsigned int type = realtype;
808 #endif
809
810   if(msglength <= size) {
811     // have some whole msg
812     MSG_INDEXINC_I();
813     msgdatafull = false;
814
815     switch(type) {
816     case REQNOTIFYSTART: {
817       processmsg_req_notify_start();
818       break;
819     }
820
821     case NOTIFYSTART: {
822       processmsg_notify_start();
823       break;
824     }
825
826 #ifdef TASK
827     case TRANSOBJ: {
828       // receive a object transfer msg
829       processmsg_transobj_I(msglength);
830       break;
831     }  
832 #endif 
833     case TRANSTALL: {
834       // receive a stall msg
835       processmsg_transtall_I();
836       break;
837     }   
838
839 #ifdef TASK
840     // GC version have no lock msgs
841 #ifndef MULTICORE_GC
842     case LOCKREQUEST: {
843       // receive lock request msg, handle it right now
844       processmsg_lockrequest_I();
845       break;
846     }   
847     case LOCKGROUNT: {
848       // receive lock grount msg
849       processmsg_lockgrount_I();
850       break;
851     } 
852     case LOCKDENY: {
853       // receive lock deny msg
854       processmsg_lockdeny_I();
855       break;
856     }  
857     case LOCKRELEASE: {
858       processmsg_lockrelease_I();
859       break;
860     }   
861 #endif
862
863 #ifdef PROFILE
864     case PROFILEOUTPUT: {
865       // receive an output profile data request msg
866       processmsg_profileoutput_I();
867       break;
868     }   
869     case PROFILEFINISH: {
870       // receive a profile output finish msg
871       processmsg_profilefinish_I();
872       break;
873     }  
874 #endif 
875
876     // GC version has no lock msgs
877 #ifndef MULTICORE_GC
878     case REDIRECTLOCK: {
879       // receive a redirect lock request msg, handle it right now
880       processmsg_redirectlock_I();
881       break;
882     }  
883
884     case REDIRECTGROUNT: {
885       // receive a lock grant msg with redirect info
886       processmsg_redirectgrount_I();
887       break;
888     } 
889
890     case REDIRECTDENY: {
891       // receive a lock deny msg with redirect info
892       processmsg_redirectdeny_I();
893       break;
894     }   
895
896     case REDIRECTRELEASE: {
897       // receive a lock release msg with redirect info
898       processmsg_redirectrelease_I();
899       break;
900     }   // case REDIRECTRELEASE
901 #endif
902 #endif 
903
904     case STATUSCONFIRM: {
905       // receive a status confirm info
906       processmsg_statusconfirm_I();
907       break;
908     }  
909
910     case STATUSREPORT: {
911       processmsg_statusreport_I();
912       break;
913     } 
914
915     case TERMINATE: {
916       // receive a terminate msg
917       processmsg_terminate_I();
918       break;
919     } 
920 #ifndef PMC_GC
921     case MEMREQUEST: {
922       processmsg_memrequest_I();
923       break;
924     }
925
926     case MEMRESPONSE: {
927       processmsg_memresponse_I();
928       break;
929     }
930 #endif
931 #ifdef PERFCOUNT
932     case MSGPERFCOUNT: {
933       profile_stop();
934       if(BAMBOO_CHECK_SEND_MODE()) {
935         cache_msg_1_I(STARTUPCORE, MSGPERFRESPONSE);
936       } else {
937         send_msg_1_I(STARTUPCORE, MSGPERFRESPONSE);
938       }
939       break;
940     }
941     case MSGPERFRESPONSE: {
942       coreperfcount--;
943       break;
944     }
945 #endif
946 #if defined(MULTICORE_GC)||defined(PMC_GC)
947     // GC msgs
948     case GCINVOKE: {
949       processmsg_gcinvoke_I();
950       break;
951     }
952
953     case GCSTARTPRE: {
954       processmsg_gcstartpre_I();
955       break;
956     }
957 #endif
958 #ifdef MULTICORE_GC
959     case GCSTARTINIT: {
960       processmsg_gcstartinit_I();
961       break;
962     }
963
964     case GCSTART: {
965       // receive a start GC msg
966       processmsg_gcstart_I();
967       break;
968     }
969
970     case GCSTARTCOMPACT: {
971       // a compact phase start msg
972       processmsg_gcstartcompact_I();
973       break;
974     }
975
976     case GCSTARTUPDATE: {
977       // received a update phase start msg
978       processmsg_gcstartupdate_I();
979       break;
980     }
981
982     case GCFINISHPRE: {
983       processmsg_gcfinishpre_I();
984       break;
985     }
986         
987     case GCFINISHINIT: {
988       processmsg_gcfinishinit_I();
989       break;
990     }
991
992     case GCFINISHMARK: {
993       processmsg_gcfinishmark_I();
994       break;
995     }
996
997     case GCRETURNMEM: {
998       processmsg_returnmem_I();
999       break;
1000     }
1001
1002     case GCFINISHCOMPACT: {
1003       // received a compact phase finish msg
1004       processmsg_gcfinishcompact_I();
1005       break;
1006     }
1007
1008     case GCFINISHUPDATE: {
1009       processmsg_gcfinishupdate_I();
1010       break;
1011     }  
1012
1013     case GCFINISH: {
1014       processmsg_gcfinish_I();
1015       break;
1016     } 
1017
1018     case GCMARKCONFIRM: {
1019       // received a marked phase finish confirm request msg
1020       // all cores should do mark
1021       processmsg_gcmarkconfirm_I();
1022       break;
1023     } 
1024
1025     case GCMARKREPORT: {
1026       processmsg_gcmarkreport_I();
1027       break;
1028     } 
1029
1030     case GCMARKEDOBJ: {
1031       processmsg_gcmarkedobj_I();
1032       break;
1033     } 
1034
1035     case GCMOVESTART: {
1036       // received a start moving objs msg
1037       processmsg_gcmovestart_I();
1038       break;
1039     } 
1040
1041     case GCLOBJREQUEST: {
1042       // received a large objs info request msg
1043       transferMarkResults_I();
1044       break;
1045     } 
1046
1047     case GCREQBLOCK: {
1048       processmsg_reqblock_I();
1049       break;
1050     }
1051
1052     case GCGRANTBLOCK: {
1053       processmsg_grantblock_I();
1054       break;
1055     }
1056
1057     case GCLOBJINFO: {
1058       // received a large objs info response msg
1059       processmsg_gclobjinfo_I(msglength);
1060       break;
1061     } 
1062
1063 #ifdef GC_PROFILE
1064     case GCPROFILES: {
1065       // received a gcprofiles msg
1066       processmsg_gcprofiles_I();
1067       break;
1068     }
1069 #endif // GC_PROFILE
1070
1071 #ifdef GC_CACHE_ADAPT
1072     case GCSTARTCACHEPOLICY: {
1073       // received a gcstartcachepolicy msg
1074       processmsg_gcstartcachepolicy_I();
1075       break;
1076     }
1077
1078     case GCFINISHCACHEPOLICY: {
1079       // received a gcfinishcachepolicy msg
1080       processmsg_gcfinishcachepolicy_I();
1081       break;
1082     }
1083
1084     case GCSTARTPREF: {
1085       // received a gcstartpref msg
1086       processmsg_gcstartpref_I();
1087       break;
1088     }
1089
1090     case GCFINISHPREF: {
1091       // received a gcfinishpref msg
1092       processmsg_gcfinishpref_I();
1093       break;
1094     }
1095 #endif
1096 #endif 
1097
1098     default:
1099       break;
1100     }
1101
1102     if((msgdataindex != msgdatalast) || (msgdatafull)) {
1103       // still have available msg
1104       goto processmsg;
1105     }
1106
1107     // have new coming msg
1108     if(BAMBOO_MSG_AVAIL() != 0) {
1109       goto msg;
1110     } 
1111
1112     PROFILE_INTERRUPT_END();
1113     return (int)type;
1114   } else {
1115     // not a whole msg
1116     return -2;
1117   }
1118 }
1119 #endif // MULTICORE