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