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