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