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