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