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