changes.
[IRC.git] / Robust / src / Runtime / bamboo / multicoremsg.c
1 #ifdef MULTICORE
2 #include "multicoremsg.h"
3 #include "runtime.h"
4 #include "multicoreruntime.h"
5 #include "multicoregarbage.h"
6 #include "multicoretaskprofile.h"
7 #include "runtime_arch.h"
8 #ifdef MULTICORE_GC
9 #include "gcqueue.h"
10 #include "markbit.h"
11 #endif
12 #ifdef PERFCOUNT
13 #include "bme_perf_counter.h"
14 #endif
15
16 int msgsizearray[] = {
17   0, //MSGSTART,
18   1, //REQNOTIFYSTART
19   1, //NOTIFYSTART
20  -1, //TRANSOBJ,              // 0xD1
21   4, //TRANSTALL,             // 0xD2
22   5, //LOCKREQUEST,           // 0xD3
23   4, //LOCKGROUNT,            // 0xD4
24   4, //LOCKDENY,              // 0xD5
25   4, //LOCKRELEASE,           // 0xD6
26   2, //PROFILEOUTPUT,         // 0xD7
27   1, //PROFILEFINISH,         // 0xD8
28   6, //REDIRECTLOCK,          // 0xD9
29   4, //REDIRECTGROUNT,        // 0xDa
30   4, //REDIRECTDENY,          // 0xDb
31   4, //REDIRECTRELEASE,       // 0xDc
32   1, //STATUSCONFIRM,         // 0xDd
33   5, //STATUSREPORT,          // 0xDe
34   1, //TERMINATE,             // 0xDf
35   3, //MEMREQUEST,            // 0xE0
36   3, //MEMRESPONSE,           // 0xE1
37 #ifdef PERFCOUNT
38   1,
39   1,
40 #endif
41 #if defined(MULTICORE_GC)||defined(PMC_GC)
42   1, //GCINVOKE
43   1, //GCSTARTPRE,            // 0xE2
44 #endif
45 #ifdef MULTICORE_GC
46   1, //GCSTARTINIT,           // 0xE3
47   1, //GCSTART,               // 0xE4
48   2, //GCSTARTCOMPACT,        // 0xE5
49   1, //GCSTARTUPDATE,          // 0xE6
50   4, //GCFINISHPRE,           // 0xE7
51   2, //GCFINISHINIT,          // 0xE8
52   4, //GCFINISHMARK,          // 0xE9
53   4, //GCFINISHCOMPACT,       // 0xEa
54   3, //GCRETURNMEM,
55   2, //GCFINISHUPDATE,         // 0xEb
56   1, //GCFINISH,              // 0xEc
57   1, //GCMARKCONFIRM,         // 0xEd
58   5, //GCMARKREPORT,          // 0xEe
59   2, //GCMARKEDOBJ,           // 0xEf
60   2, //GCMOVESTART,           // 0xF0
61   1, //GCLOBJREQUEST,         // 0xF1
62   3, //GCREQBLOCK,
63   1, //GCGRANTBLOCK,  
64   -1, //GCLOBJINFO,            // 0xF2
65 #ifdef GC_PROFILE
66   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)||defined(GC_CACHE_ADAPT_POLICY3))
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     BAMBOO_ASSERT((msgdataindex!=msgdatalast)||(!msgdatafull));
779     // during send, don't process the msg now
780     return -3; 
781   }
782 processmsg:
783   // processing received msgs
784   int size;
785   MSG_REMAINSIZE_I(size);
786   if(size == 0) {
787     // not a whole msg
788     // have new coming msg
789     if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
790       goto msg;
791     } else {
792       return -1;
793     }
794   }
795
796   //we only ever read the first word
797   unsigned int realtype = msgdata[msgdataindex];
798   unsigned int msglength = checkMsgLength_I(realtype);
799
800 #if (defined(TASK)||defined(MULTICORE_GC))
801   unsigned int type = realtype & 0xff;
802 #else
803   unsigned int type = realtype;
804 #endif
805
806   if(msglength <= size) {
807     // have some whole msg
808     MSG_INDEXINC_I();
809     msgdatafull = false;
810
811     switch(type) {
812     case REQNOTIFYSTART: {
813       processmsg_req_notify_start();
814       break;
815     }
816
817     case NOTIFYSTART: {
818       processmsg_notify_start();
819       break;
820     }
821
822 #ifdef TASK
823     case TRANSOBJ: {
824       // receive a object transfer msg
825       processmsg_transobj_I(msglength);
826       break;
827     }  
828 #endif 
829     case TRANSTALL: {
830       // receive a stall msg
831       processmsg_transtall_I();
832       break;
833     }   
834
835 #ifdef TASK
836     // GC version have no lock msgs
837 #ifndef MULTICORE_GC
838     case LOCKREQUEST: {
839       // receive lock request msg, handle it right now
840       processmsg_lockrequest_I();
841       break;
842     }   
843     case LOCKGROUNT: {
844       // receive lock grount msg
845       processmsg_lockgrount_I();
846       break;
847     } 
848     case LOCKDENY: {
849       // receive lock deny msg
850       processmsg_lockdeny_I();
851       break;
852     }  
853     case LOCKRELEASE: {
854       processmsg_lockrelease_I();
855       break;
856     }   
857 #endif
858
859 #ifdef PROFILE
860     case PROFILEOUTPUT: {
861       // receive an output profile data request msg
862       processmsg_profileoutput_I();
863       break;
864     }   
865     case PROFILEFINISH: {
866       // receive a profile output finish msg
867       processmsg_profilefinish_I();
868       break;
869     }  
870 #endif 
871
872     // GC version has no lock msgs
873 #ifndef MULTICORE_GC
874     case REDIRECTLOCK: {
875       // receive a redirect lock request msg, handle it right now
876       processmsg_redirectlock_I();
877       break;
878     }  
879
880     case REDIRECTGROUNT: {
881       // receive a lock grant msg with redirect info
882       processmsg_redirectgrount_I();
883       break;
884     } 
885
886     case REDIRECTDENY: {
887       // receive a lock deny msg with redirect info
888       processmsg_redirectdeny_I();
889       break;
890     }   
891
892     case REDIRECTRELEASE: {
893       // receive a lock release msg with redirect info
894       processmsg_redirectrelease_I();
895       break;
896     }   // case REDIRECTRELEASE
897 #endif
898 #endif 
899
900     case STATUSCONFIRM: {
901       // receive a status confirm info
902       processmsg_statusconfirm_I();
903       break;
904     }  
905
906     case STATUSREPORT: {
907       processmsg_statusreport_I();
908       break;
909     } 
910
911     case TERMINATE: {
912       // receive a terminate msg
913       processmsg_terminate_I();
914       break;
915     } 
916 #ifndef PMC_GC
917     case MEMREQUEST: {
918       processmsg_memrequest_I();
919       break;
920     }
921
922     case MEMRESPONSE: {
923       processmsg_memresponse_I();
924       break;
925     }
926 #endif
927 #ifdef PERFCOUNT
928     case MSGPERFCOUNT: {
929       profile_stop();
930       if(BAMBOO_CHECK_SEND_MODE()) {
931         cache_msg_1_I(STARTUPCORE, MSGPERFRESPONSE);
932       } else {
933         send_msg_1_I(STARTUPCORE, MSGPERFRESPONSE);
934       }
935       break;
936     }
937     case MSGPERFRESPONSE: {
938       coreperfcount--;
939       break;
940     }
941 #endif
942 #if defined(MULTICORE_GC)||defined(PMC_GC)
943     // GC msgs
944     case GCINVOKE: {
945       processmsg_gcinvoke_I();
946       break;
947     }
948
949     case GCSTARTPRE: {
950       processmsg_gcstartpre_I();
951       break;
952     }
953 #endif
954 #ifdef MULTICORE_GC
955     case GCSTARTINIT: {
956       processmsg_gcstartinit_I();
957       break;
958     }
959
960     case GCSTART: {
961       // receive a start GC msg
962       processmsg_gcstart_I();
963       break;
964     }
965
966     case GCSTARTCOMPACT: {
967       // a compact phase start msg
968       processmsg_gcstartcompact_I();
969       break;
970     }
971
972     case GCSTARTUPDATE: {
973       // received a update phase start msg
974       processmsg_gcstartupdate_I();
975       break;
976     }
977
978     case GCFINISHPRE: {
979       processmsg_gcfinishpre_I();
980       break;
981     }
982         
983     case GCFINISHINIT: {
984       processmsg_gcfinishinit_I();
985       break;
986     }
987
988     case GCFINISHMARK: {
989       processmsg_gcfinishmark_I();
990       break;
991     }
992
993     case GCRETURNMEM: {
994       processmsg_returnmem_I();
995       break;
996     }
997
998     case GCFINISHCOMPACT: {
999       // received a compact phase finish msg
1000       processmsg_gcfinishcompact_I();
1001       break;
1002     }
1003
1004     case GCFINISHUPDATE: {
1005       processmsg_gcfinishupdate_I();
1006       break;
1007     }  
1008
1009     case GCFINISH: {
1010       processmsg_gcfinish_I();
1011       break;
1012     } 
1013
1014     case GCMARKCONFIRM: {
1015       // received a marked phase finish confirm request msg
1016       // all cores should do mark
1017       processmsg_gcmarkconfirm_I();
1018       break;
1019     } 
1020
1021     case GCMARKREPORT: {
1022       processmsg_gcmarkreport_I();
1023       break;
1024     } 
1025
1026     case GCMARKEDOBJ: {
1027       processmsg_gcmarkedobj_I();
1028       break;
1029     } 
1030
1031     case GCMOVESTART: {
1032       // received a start moving objs msg
1033       processmsg_gcmovestart_I();
1034       break;
1035     } 
1036
1037     case GCLOBJREQUEST: {
1038       // received a large objs info request msg
1039       transferMarkResults_I();
1040       break;
1041     } 
1042
1043     case GCREQBLOCK: {
1044       processmsg_reqblock_I();
1045       break;
1046     }
1047
1048     case GCGRANTBLOCK: {
1049       processmsg_grantblock_I();
1050       break;
1051     }
1052
1053     case GCLOBJINFO: {
1054       // received a large objs info response msg
1055       processmsg_gclobjinfo_I(msglength);
1056       break;
1057     } 
1058
1059 #ifdef GC_PROFILE
1060     case GCPROFILES: {
1061       // received a gcprofiles msg
1062       processmsg_gcprofiles_I();
1063       break;
1064     }
1065 #endif // GC_PROFILE
1066
1067 #ifdef GC_CACHE_ADAPT
1068     case GCSTARTCACHEPOLICY: {
1069       // received a gcstartcachepolicy msg
1070       processmsg_gcstartcachepolicy_I();
1071       break;
1072     }
1073
1074     case GCFINISHCACHEPOLICY: {
1075       // received a gcfinishcachepolicy msg
1076       processmsg_gcfinishcachepolicy_I();
1077       break;
1078     }
1079
1080     case GCSTARTPREF: {
1081       // received a gcstartpref msg
1082       processmsg_gcstartpref_I();
1083       break;
1084     }
1085
1086     case GCFINISHPREF: {
1087       // received a gcfinishpref msg
1088       processmsg_gcfinishpref_I();
1089       break;
1090     }
1091 #endif
1092 #endif 
1093
1094     default:
1095       break;
1096     }
1097
1098     if((msgdataindex != msgdatalast) || (msgdatafull)) {
1099       // still have available msg
1100       goto processmsg;
1101     }
1102
1103     // have new coming msg
1104     if(BAMBOO_MSG_AVAIL() != 0) {
1105       goto msg;
1106     } 
1107
1108     PROFILE_INTERRUPT_END();
1109     return (int)type;
1110   } else {
1111     // not a whole msg
1112     return -2;
1113   }
1114 }
1115 #endif // MULTICORE