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