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