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