Add the runtime for multicore gc version w/o tasks. Now can start multiple threads...
[IRC.git] / Robust / src / Runtime / bamboo / multicoreruntime.c
1 #ifdef MULTICORE
2
3 #include "runtime.h"
4 #include "multicoreruntime.h"
5 #include "runtime_arch.h"
6 #include "GenericHashtable.h"
7 #include "structdefs.h"
8 #include "mem.h"
9 #ifndef RAW
10 #include <stdio.h>
11 #endif
12
13 #ifndef INLINE
14 #define INLINE    inline __attribute__((always_inline))
15 #endif // #ifndef INLINE
16
17 extern int classsize[];
18 extern int typearray[];
19 extern int typearray2[];
20
21 #ifdef TASK
22 extern struct genhashtable * activetasks;
23 #endif
24 #ifdef MULTICORE_GC
25 #ifdef SMEMM
26 extern unsigned int gcmem_mixed_threshold;
27 extern unsigned int gcmem_mixed_usedmem;
28 #endif // SMEMM
29 #endif // MULTICORE_GC
30
31 int debugtask=0;
32 #ifdef MGC
33 int corenum = 0;
34 #endif
35
36 int instanceof(struct ___Object___ *ptr, int type) {
37   int i=ptr->type;
38   do {
39     if (i==type)
40       return 1;
41     i=typearray[i];
42   } while(i!=-1);
43   i=ptr->type;
44   if (i>NUMCLASSES) {
45     do {
46       if (i==type)
47         return 1;
48       i=typearray2[i-NUMCLASSES];
49     } while(i!=-1);
50   }
51   return 0;
52 }
53
54 void initializeexithandler() {
55 }
56
57 /* This function inject failures */
58
59 void injectinstructionfailure() {
60   // not supported in MULTICORE version
61   return;
62 }
63
64 #ifdef D___Double______nativeparsedouble____L___String___
65 double CALL01(___Double______nativeparsedouble____L___String___,struct ___String___ * ___str___) {
66   int length=VAR(___str___)->___count___;
67   int maxlength=(length>60) ? 60 : length;
68   char str[maxlength+1];
69   struct ArrayObject * chararray=VAR(___str___)->___value___;
70   int i;
71   int offset=VAR(___str___)->___offset___;
72   for(i=0; i<maxlength; i++) {
73     str[i]=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
74   }
75   str[i]=0;
76   double d=atof(str);
77   return d;
78 }
79 #endif
80
81 #ifdef D___String______convertdoubletochar____D__AR_C
82 int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
83   int length=VAR(___chararray___)->___length___;
84   char str[length];
85   int i;
86   int num=snprintf(str, length, "%f",___val___);
87   if (num>=length)
88     num=length-1;
89   for(i=0; i<length; i++) {
90     ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=(short)str[i];
91   }
92   return num;
93 }
94 #else
95 int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
96   return 0;
97 }
98 #endif
99
100 void CALL11(___System______exit____I,int ___status___, int ___status___) {
101   BAMBOO_EXIT(___status___);
102 }
103
104 void CALL23(___Vector______removeElement_____AR_L___Object____I_I, int ___index___, int ___size___, struct ArrayObject * ___array___, int ___index___, int ___size___) {
105   char* offset=((char *)(&VAR(___array___)->___length___))+sizeof(unsigned int)+sizeof(void *)*___index___;
106   memmove(offset, offset+sizeof(void *),(___size___-___index___-1)*sizeof(void *));
107 }
108
109 void CALL11(___System______printI____I,int ___status___, int ___status___) {
110   BAMBOO_DEBUGPRINT(0x1111);
111   BAMBOO_DEBUGPRINT_REG(___status___);
112 }
113
114 long CALL00(___System______currentTimeMillis____) {
115   // not supported in MULTICORE version
116   return -1;
117 }
118
119 void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
120 #ifdef MGC
121 #ifdef TILERA_BME
122   struct ArrayObject * chararray=VAR(___s___)->___value___;
123   int i;
124   int offset=VAR(___s___)->___offset___;
125   tprintf("");
126   for(i=0; i<VAR(___s___)->___count___; i++) {
127         short sc=
128           ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
129     printf("%c", sc);
130   }
131   printf("\n");
132 #endif // TILERA_BME
133 #endif // MGC
134 }
135
136 /* Object allocation function */
137
138 #ifdef MULTICORE_GC
139 void * allocate_new(void * ptr, int type) {
140   struct ___Object___ * v=
141         (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
142   v->type=type;
143 #ifdef TASK
144   v->version = 0;
145   v->lock = NULL;
146   v->lockcount = 0;
147 #endif
148   initlock(v);
149 #ifdef GC_PROFILE
150   extern unsigned int gc_num_obj;
151   gc_num_obj++;
152 #endif
153   return v;
154 }
155
156 /* Array allocation function */
157
158 struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
159   struct ArrayObject * v=(struct ArrayObject *)
160         FREEMALLOC((struct garbagelist*)ptr,
161                 sizeof(struct ArrayObject)+length*classsize[type]);
162   v->type=type;
163 #ifdef TASK
164   v->version = 0;
165   v->lock = NULL;
166 #endif
167   if (length<0) {
168     return NULL;
169   }
170   v->___length___=length;
171   initlock(v);
172 #ifdef GC_PROFILE
173   extern unsigned int gc_num_obj;
174   gc_num_obj++;
175 #endif
176   return v;
177 }
178
179 #else
180 void * allocate_new(int type) {
181   struct ___Object___ * v=FREEMALLOC(classsize[type]);
182   v->type=type;
183 #ifdef TASK
184   v->version = 0;
185   v->lock = NULL;
186 #endif
187   initlock(v);
188   return v;
189 }
190
191 /* Array allocation function */
192
193 struct ArrayObject * allocate_newarray(int type, int length) {
194   struct ArrayObject * v=
195         FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
196   v->type=type;
197 #ifdef TASK
198   v->version = 0;
199   v->lock = NULL;
200 #endif
201   v->___length___=length;
202   initlock(v);
203   return v;
204 }
205 #endif
206
207
208 /* Converts C character arrays into Java strings */
209 #ifdef MULTICORE_GC
210 struct ___String___ * NewString(void * ptr, const char *str,int length) {
211 #else
212 struct ___String___ * NewString(const char *str,int length) {
213 #endif
214   int i;
215 #ifdef MULTICORE_GC
216   struct ArrayObject * chararray=
217         allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
218   int ptrarray[]={1, (int) ptr, (int) chararray};
219   struct ___String___ * strobj=
220         allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
221   chararray=(struct ArrayObject *) ptrarray[2];
222 #else
223   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
224   struct ___String___ * strobj=allocate_new(STRINGTYPE);
225 #endif
226   strobj->___value___=chararray;
227   strobj->___count___=length;
228   strobj->___offset___=0;
229
230   for(i=0; i<length; i++) {
231     ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
232   }
233   return strobj;
234 }
235
236 /* Generated code calls this if we fail a bounds check */
237
238 void failedboundschk() {
239 #ifndef TASK
240   printf("Array out of bounds\n");
241 #ifdef THREADS
242   threadexit();
243 #else
244   exit(-1);
245 #endif
246 #else
247 #ifndef MULTICORE
248   printf("Array out of bounds\n");
249   longjmp(error_handler,2);
250 #else
251   BAMBOO_EXIT(0xa002);
252 #endif
253 #endif
254 }
255
256 /* Abort task call */
257 void abort_task() {
258 #ifdef TASK
259 #ifndef MULTICORE
260   printf("Aborting\n");
261   longjmp(error_handler,4);
262 #endif
263 #else
264   printf("Aborting\n");
265   exit(-1);
266 #endif
267 }
268
269 INLINE void initruntimedata() {
270   int i;
271   // initialize the arrays
272   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
273     // startup core to initialize corestatus[]
274     for(i = 0; i < NUMCORESACTIVE; ++i) {
275       corestatus[i] = 1;
276       numsendobjs[i] = 0;
277       numreceiveobjs[i] = 0;
278 #ifdef MULTICORE_GC
279       gccorestatus[i] = 1;
280       gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
281       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
282 #endif
283     } // for(i = 0; i < NUMCORESACTIVE; ++i)
284 #ifdef MULTICORE_GC
285     for(i = 0; i < NUMCORES4GC; ++i) {
286       gcloads[i] = 0;
287       gcrequiredmems[i] = 0;
288       gcstopblock[i] = 0;
289       gcfilledblocks[i] = 0;
290     } // for(i = 0; i < NUMCORES4GC; ++i)
291 #ifdef GC_PROFILE
292     gc_infoIndex = 0;
293     gc_infoOverflow = false;
294         gc_num_livespace = 0;
295         gc_num_freespace = 0;
296 #endif
297 #endif
298     numconfirm = 0;
299     waitconfirm = false;
300   }
301
302   busystatus = true;
303   self_numsendobjs = 0;
304   self_numreceiveobjs = 0;
305
306   for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
307     msgdata[i] = -1;
308   }
309   msgdataindex = 0;
310   msgdatalast = 0;
311   msglength = BAMBOO_MSG_BUF_LENGTH;
312   msgdatafull = false;
313   for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
314     outmsgdata[i] = -1;
315   }
316   outmsgindex = 0;
317   outmsglast = 0;
318   outmsgleft = 0;
319   isMsgHanging = false;
320
321   smemflag = true;
322   bamboo_cur_msp = NULL;
323   bamboo_smem_size = 0;
324
325 #ifdef MULTICORE_GC
326   bamboo_smem_zero_top = NULL;
327   gcflag = false;
328   gcprocessing = false;
329   gcphase = FINISHPHASE;
330   gcprecheck = true;
331   gccurr_heaptop = 0;
332   gcself_numsendobjs = 0;
333   gcself_numreceiveobjs = 0;
334   gcmarkedptrbound = 0;
335 #ifdef LOCALHASHTBL_TEST
336   gcpointertbl = allocateRuntimeHash_I(20);
337 #else
338   gcpointertbl = mgchashCreate_I(2000, 0.75);
339 #endif
340   gcforwardobjtbl = allocateMGCHash_I(20, 3);
341   gcobj2map = 0;
342   gcmappedobj = 0;
343   gcnumlobjs = 0;
344   gcheaptop = 0;
345   gctopcore = 0;
346   gctopblock = 0;
347   gcmovestartaddr = 0;
348   gctomove = false;
349   gcmovepending = 0;
350   gcblock2fill = 0;
351   gcsbstarttbl = BAMBOO_BASE_VA;
352   bamboo_smemtbl = (void *)gcsbstarttbl
353                + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
354   if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
355         int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
356                 -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
357         int kk = 0;
358         unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
359         while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
360           t_size = t_size << 1;
361           kk++;
362         }
363         t_size = tmp_k >> kk;
364         gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);
365   } else {
366         gcsharedptbl = NULL;
367   }
368   BAMBOO_MEMSET_WH(gcrpointertbls, 0, 
369           sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
370 #ifdef SMEMM
371   gcmem_mixed_threshold = (unsigned int)((BAMBOO_SHARED_MEM_SIZE
372                 -bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
373   gcmem_mixed_usedmem = 0;
374 #endif
375 #ifdef GC_PROFILE
376   gc_num_obj = 0;
377   gc_num_liveobj = 0;
378   gc_num_forwardobj = 0;
379   gc_num_profiles = NUMCORESACTIVE - 1;
380 #endif
381 #ifdef GC_FLUSH_DTLB
382   gc_num_flush_dtlb = 0;
383 #endif
384   gc_localheap_s = false;
385 #ifdef GC_CACHE_ADAPT
386   gccachestage = false;
387 #endif // GC_CACHE_ADAPT
388 #endif // MULTICORE_GC
389 #ifndef INTERRUPT
390   reside = false;
391 #endif
392
393 #ifdef MGC
394   initializethreads();
395   bamboo_current_thread = NULL;
396 #endif // MGC
397
398 #ifdef TASK
399   inittaskdata();
400 #endif
401 }
402
403 INLINE void disruntimedata() {
404 #ifdef MULTICORE_GC
405 #ifdef LOCALHASHTBL_TEST
406   freeRuntimeHash(gcpointertbl);
407 #else
408   mgchashDelete(gcpointertbl);
409 #endif
410   freeMGCHash(gcforwardobjtbl);
411 #endif // MULTICORE_GC
412 #ifdef TASK
413   distaskdata()
414 #endif // TASK
415   BAMBOO_LOCAL_MEM_CLOSE();
416   BAMBOO_SHARE_MEM_CLOSE();
417 }
418
419 INLINE void checkCoreStatus() {
420   bool allStall = false;
421   int i = 0;
422   int sumsendobj = 0;
423   if((!waitconfirm) ||
424      (waitconfirm && (numconfirm == 0))) {
425     BAMBOO_DEBUGPRINT(0xee04);
426     BAMBOO_DEBUGPRINT_REG(waitconfirm);
427     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
428     BAMBOO_DEBUGPRINT(0xf001);
429     corestatus[BAMBOO_NUM_OF_CORE] = 0;
430     numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
431     numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
432     // check the status of all cores
433     allStall = true;
434     BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
435     for(i = 0; i < NUMCORESACTIVE; ++i) {
436       BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
437       if(corestatus[i] != 0) {
438                 allStall = false;
439                 break;
440       }
441     }  // for(i = 0; i < NUMCORESACTIVE; ++i)
442     if(allStall) {
443       // check if the sum of send objs and receive obj are the same
444       // yes->check if the info is the latest; no->go on executing
445       sumsendobj = 0;
446       for(i = 0; i < NUMCORESACTIVE; ++i) {
447                 sumsendobj += numsendobjs[i];
448                 BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
449       }  // for(i = 0; i < NUMCORESACTIVE; ++i)
450       for(i = 0; i < NUMCORESACTIVE; ++i) {
451                 sumsendobj -= numreceiveobjs[i];
452                 BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
453       }  // for(i = 0; i < NUMCORESACTIVE; ++i)
454       if(0 == sumsendobj) {
455                 if(!waitconfirm) {
456                   // the first time found all cores stall
457                   // send out status confirm msg to all other cores
458                   // reset the corestatus array too
459                   BAMBOO_DEBUGPRINT(0xee05);
460                   corestatus[BAMBOO_NUM_OF_CORE] = 1;
461                   waitconfirm = true;
462                   numconfirm = NUMCORESACTIVE - 1;
463                   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
464                   for(i = 1; i < NUMCORESACTIVE; ++i) {
465                         corestatus[i] = 1;
466                         // send status confirm msg to core i
467                         send_msg_1(i, STATUSCONFIRM, false);
468                   }   // for(i = 1; i < NUMCORESACTIVE; ++i)
469                   return;
470                 } else {
471                   // all the core status info are the latest
472                   // terminate; for profiling mode, send request to all
473                   // other cores to pour out profiling data
474                   BAMBOO_DEBUGPRINT(0xee06);
475
476 #ifdef USEIO
477                   totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
478 #else
479
480                   BAMBOO_PRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
481                   //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
482 #ifdef GC_FLUSH_DTLB
483                   BAMBOO_PRINT_REG(gc_num_flush_dtlb);
484 #endif
485 #ifndef BAMBOO_MEMPROF
486                   BAMBOO_PRINT(0xbbbbbbbb);
487 #endif
488 #endif
489                   // profile mode, send msgs to other cores to request pouring
490                   // out progiling data
491 #ifdef PROFILE
492                   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
493                   BAMBOO_DEBUGPRINT(0xf000);
494                   for(i = 1; i < NUMCORESACTIVE; ++i) {
495                         // send profile request msg to core i
496                         send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
497                   } // for(i = 1; i < NUMCORESACTIVE; ++i)
498 #ifndef RT_TEST
499                   // pour profiling data on startup core
500                   outputProfileData();
501 #endif
502                   while(true) {
503                         BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
504                         BAMBOO_DEBUGPRINT(0xf001);
505                         profilestatus[BAMBOO_NUM_OF_CORE] = 0;
506                         // check the status of all cores
507                         allStall = true;
508                         BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
509                         for(i = 0; i < NUMCORESACTIVE; ++i) {
510                           BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
511                           if(profilestatus[i] != 0) {
512                                 allStall = false;
513                                 break;
514                           }
515                         }  // for(i = 0; i < NUMCORESACTIVE; ++i)
516                         if(!allStall) {
517                           int halt = 100;
518                           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
519                           BAMBOO_DEBUGPRINT(0xf000);
520                           while(halt--) {
521                           }
522                         } else {
523                           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
524                           break;
525                         }  // if(!allStall)
526                   }  // while(true)
527 #endif
528
529                   // gc_profile mode, output gc prfiling data
530 #ifdef MULTICORE_GC
531 #ifdef GC_CACHE_ADAPT
532                   bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
533 #endif // GC_CACHE_ADAPT
534 #ifdef GC_PROFILE
535                   gc_outputProfileData();
536 #endif // #ifdef GC_PROFILE
537 #endif // #ifdef MULTICORE_GC
538                   disruntimedata();
539                   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
540                   terminate();  // All done.
541                 }  // if(!waitconfirm)
542       } else {
543                 // still some objects on the fly on the network
544                 // reset the waitconfirm and numconfirm
545                 BAMBOO_DEBUGPRINT(0xee07);
546                 waitconfirm = false;
547                 numconfirm = 0;
548           }  //  if(0 == sumsendobj)
549     } else {
550       // not all cores are stall, keep on waiting
551       BAMBOO_DEBUGPRINT(0xee08);
552       waitconfirm = false;
553       numconfirm = 0;
554     }  //  if(allStall)
555     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
556     BAMBOO_DEBUGPRINT(0xf000);
557   }  // if((!waitconfirm) ||
558 }
559
560 // main function for each core
561 inline void run(int argc, char** argv) {
562   int i = 0;
563   bool sendStall = false;
564   bool isfirst = true;
565   bool tocontinue = false;
566
567   corenum = BAMBOO_GET_NUM_OF_CORE();
568   BAMBOO_DEBUGPRINT(0xeeee);
569   BAMBOO_DEBUGPRINT_REG(corenum);
570   BAMBOO_DEBUGPRINT(STARTUPCORE);
571
572   // initialize runtime data structures
573   initruntimedata();
574
575   // other architecture related initialization
576   initialization();
577   initCommunication();
578
579 #ifdef GC_CACHE_ADAPT
580 // enable the timer interrupt
581 #ifdef GC_CACHE_SAMPLING
582   bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING); // TODO
583   bamboo_unmask_timer_intr();
584   bamboo_dtlb_sampling_process();
585 #endif // GC_CACHE_SAMPLING
586 #endif // GC_CACHE_ADAPT
587
588   initializeexithandler();
589
590   // main process of the execution module
591   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
592 #ifdef TASK
593     // non-executing cores, only processing communications
594     activetasks = NULL;
595 #endif
596     fakeExecution();
597   } else {
598 #ifdef TASK
599     /* Create queue of active tasks */
600     activetasks=
601       genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
602                            (int (*)(void *,void *)) &comparetpd);
603
604     /* Process task information */
605     processtasks();
606
607     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
608       /* Create startup object */
609       createstartupobject(argc, argv);
610     }
611
612     BAMBOO_DEBUGPRINT(0xee00);
613 #endif
614
615 #ifdef MGC
616         if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
617           // run the main method in the specified mainclass
618           mgc_main(argc, argv);
619         }
620 #endif
621
622     while(true) {
623
624 #ifdef MULTICORE_GC
625       // check if need to do GC
626       if(gcflag) {
627                 gc(NULL);
628           }
629 #endif // MULTICORE_GC
630
631 #ifdef TASK
632       // check if there are new active tasks can be executed
633       executetasks();
634       if(busystatus) {
635                 sendStall = false;
636       }
637
638 #ifndef INTERRUPT
639       while(receiveObject() != -1) {
640       }
641 #endif
642
643       BAMBOO_DEBUGPRINT(0xee01);
644
645       // check if there are some pending objects,
646       // if yes, enqueue them and executetasks again
647       tocontinue = checkObjQueue();
648 #elif defined MGC
649           trystartthread();
650           tocontinue = false;
651 #endif
652
653       if(!tocontinue) {
654                 // check if stop
655                 if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
656                   if(isfirst) {
657                         BAMBOO_DEBUGPRINT(0xee03);
658                         isfirst = false;
659                   }
660                   checkCoreStatus();
661                 } else {
662                   if(!sendStall) {
663                         BAMBOO_DEBUGPRINT(0xee09);
664 #ifdef PROFILE
665                         if(!stall) {
666 #endif
667                         if(isfirst) {
668                           // wait for some time
669                           int halt = 10000;
670                           BAMBOO_DEBUGPRINT(0xee0a);
671                           while(halt--) {
672                           }
673                           isfirst = false;
674                         } else {
675                           // send StallMsg to startup core
676                           BAMBOO_DEBUGPRINT(0xee0b);
677                           // send stall msg
678                           send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
679                                                  self_numsendobjs, self_numreceiveobjs, false);
680                           sendStall = true;
681                           isfirst = true;
682                           busystatus = false;
683                         }
684 #ifdef PROFILE
685                   }
686 #endif
687                   } else {
688                         isfirst = true;
689                         busystatus = false;
690                         BAMBOO_DEBUGPRINT(0xee0c);
691                   }   // if(!sendStall)
692                 }   // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
693       }  // if(!tocontinue)
694     }  // while(true)
695   } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
696
697 } // run()
698
699 INLINE int checkMsgLength_I(int size) {
700 #ifndef CLOSE_PRINT
701   BAMBOO_DEBUGPRINT(0xcccc);
702 #endif
703   int type = msgdata[msgdataindex];
704   switch(type) {
705   case STATUSCONFIRM:
706   case TERMINATE:
707 #ifdef MULTICORE_GC
708   case GCSTARTPRE:
709   case GCSTARTINIT:
710   case GCSTART:
711   case GCSTARTMAPINFO:
712   case GCSTARTFLUSH:
713   case GCFINISH:
714   case GCMARKCONFIRM:
715   case GCLOBJREQUEST:
716 #ifdef GC_CACHE_ADAPT
717   case GCSTARTPREF:
718 #endif // GC_CACHE_ADAPT
719 #endif // MULTICORE_GC
720   {
721         msglength = 1;
722         break;
723   }
724
725 #ifdef TASK
726   case PROFILEOUTPUT:
727   case PROFILEFINISH:
728 #endif
729 #ifdef MULTICORE_GC
730   case GCSTARTCOMPACT:
731   case GCMARKEDOBJ:
732   case GCFINISHINIT:
733   case GCFINISHMAPINFO:
734   case GCFINISHFLUSH:
735 #ifdef GC_CACHE_ADAPT
736   case GCFINISHPREF:
737 #endif // GC_CACHE_ADAPT
738 #endif // MULTICORE_GC
739   {
740         msglength = 2;
741         break;
742   }
743
744   case MEMREQUEST:
745   case MEMRESPONSE:
746 #ifdef MULTICORE_GC
747   case GCMAPREQUEST:
748   case GCMAPINFO:
749   case GCMAPTBL:
750   case GCLOBJMAPPING:
751 #endif
752   {
753         msglength = 3;
754         break;
755   }
756
757   case TRANSTALL:
758 #ifdef TASK
759   case LOCKGROUNT:
760   case LOCKDENY:
761   case LOCKRELEASE:
762   case REDIRECTGROUNT:
763   case REDIRECTDENY:
764   case REDIRECTRELEASE:
765 #endif
766 #ifdef MULTICORE_GC
767   case GCFINISHPRE:
768   case GCFINISHMARK:
769   case GCMOVESTART:
770 #ifdef GC_PROFILE
771   case GCPROFILES:
772 #endif
773 #endif
774   {
775         msglength = 4;
776         break;
777   }
778
779 #ifdef TASK
780   case LOCKREQUEST:
781 #endif
782   case STATUSREPORT:
783 #ifdef MULTICORE_GC
784   case GCFINISHCOMPACT:
785   case GCMARKREPORT:
786 #endif
787   {
788         msglength = 5;
789         break;
790   }
791
792 #ifdef TASK
793   case REDIRECTLOCK:
794   {
795     msglength = 6;
796     break;
797   }
798 #endif
799
800 #ifdef TASK
801   case TRANSOBJ:   // nonfixed size
802 #endif
803 #ifdef MULTICORE_GC
804   case GCLOBJINFO:
805 #endif
806   {  // nonfixed size
807         if(size > 1) {
808           msglength = msgdata[(msgdataindex+1)&(BAMBOO_MSG_BUF_MASK)];
809         } else {
810           return -1;
811         }
812         break;
813   }
814
815   default:
816   {
817     BAMBOO_DEBUGPRINT_REG(type);
818         BAMBOO_DEBUGPRINT_REG(size);
819     BAMBOO_DEBUGPRINT_REG(msgdataindex);
820         BAMBOO_DEBUGPRINT_REG(msgdatalast);
821         BAMBOO_DEBUGPRINT_REG(msgdatafull);
822     int i = 6;
823     while(i-- > 0) {
824       BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
825     }
826     BAMBOO_EXIT(0xe004);
827     break;
828   }
829   }
830 #ifndef CLOSE_PRINT
831   BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
832   BAMBOO_DEBUGPRINT(0xffff);
833 #endif
834   return msglength;
835 }
836
837 INLINE void processmsg_transtall_I() {
838   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
839     // non startup core can not receive stall msg
840 #ifndef CLOSE_PRINT
841     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
842 #endif
843     BAMBOO_EXIT(0xe006);
844   }
845   int num_core = msgdata[msgdataindex]; //[1]
846   MSG_INDEXINC_I();
847   int data2 = msgdata[msgdataindex]; //[2];
848   MSG_INDEXINC_I();
849   int data3 = msgdata[msgdataindex]; //[3];
850   MSG_INDEXINC_I();
851   if(num_core < NUMCORESACTIVE) {
852 #ifndef CLOSE_PRINT
853     BAMBOO_DEBUGPRINT(0xe881);
854 #endif
855     corestatus[num_core] = 0;
856     numsendobjs[num_core] = data2; //[2];
857     numreceiveobjs[num_core] = data3; //[3];
858   }
859 }
860
861 INLINE void processmsg_statusconfirm_I() {
862   if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
863      || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
864     // wrong core to receive such msg
865     BAMBOO_EXIT(0xe011);
866   } else {
867     // send response msg
868 #ifndef CLOSE_PRINT
869     BAMBOO_DEBUGPRINT(0xe887);
870 #endif
871     // cache the msg first
872     if(BAMBOO_CHECK_SEND_MODE()) {
873           cache_msg_5(STARTUPCORE, STATUSREPORT,
874                                   busystatus ? 1 : 0, BAMBOO_NUM_OF_CORE,
875                                   self_numsendobjs, self_numreceiveobjs);
876     } else {
877           send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
878                                  BAMBOO_NUM_OF_CORE, self_numsendobjs,
879                                  self_numreceiveobjs, true);
880     }
881   }
882 }
883
884 INLINE void processmsg_statusreport_I() {
885   int data1 = msgdata[msgdataindex];
886   MSG_INDEXINC_I();
887   int data2 = msgdata[msgdataindex];
888   MSG_INDEXINC_I();
889   int data3 = msgdata[msgdataindex];
890   MSG_INDEXINC_I();
891   int data4 = msgdata[msgdataindex];
892   MSG_INDEXINC_I();
893   // receive a status confirm info
894   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
895     // wrong core to receive such msg
896 #ifndef CLOSE_PRINT
897     BAMBOO_DEBUGPRINT_REG(data2);
898 #endif
899     BAMBOO_EXIT(0xe012);
900   } else {
901 #ifndef CLOSE_PRINT
902     BAMBOO_DEBUGPRINT(0xe888);
903 #endif
904     if(waitconfirm) {
905       numconfirm--;
906     }
907     corestatus[data2] = data1;
908     numsendobjs[data2] = data3;
909     numreceiveobjs[data2] = data4;
910   }
911 }
912
913 INLINE void processmsg_terminate_I() {
914 #ifndef CLOSE_PRINT
915   BAMBOO_DEBUGPRINT(0xe889);
916 #endif
917   disruntimedata();
918 #ifdef MULTICORE_GC
919 #ifdef GC_CACHE_ADAPT
920   bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
921 #endif // GC_CACHE_ADAPT
922 #endif // MULTICORE_GC
923   BAMBOO_EXIT_APP(0);
924 }
925
926 INLINE void processmsg_memrequest_I() {
927   int data1 = msgdata[msgdataindex];
928   MSG_INDEXINC_I();
929   int data2 = msgdata[msgdataindex];
930   MSG_INDEXINC_I();
931   // receive a shared memory request msg
932   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
933     // wrong core to receive such msg
934 #ifndef CLOSE_PRINT
935     BAMBOO_DEBUGPRINT_REG(data2);
936 #endif
937     BAMBOO_EXIT(0xe013);
938   } else {
939 #ifndef CLOSE_PRINT
940     BAMBOO_DEBUGPRINT(0xe88a);
941 #endif
942     int allocsize = 0;
943     void * mem = NULL;
944 #ifdef MULTICORE_GC
945     if(gcprocessing) {
946       // is currently doing gc, dump this msg
947       if(INITPHASE == gcphase) {
948                 // if still in the initphase of gc, send a startinit msg again,
949                 // cache the msg first
950                 if(BAMBOO_CHECK_SEND_MODE()) {
951                   cache_msg_1(data2, GCSTARTINIT);
952                 } else {
953                   send_msg_1(data2, GCSTARTINIT, true);
954                 }
955       }
956     } else {
957 #endif
958     mem = smemalloc_I(data2, data1, &allocsize);
959     if(mem != NULL) {
960       // send the start_va to request core, cache the msg first
961       if(BAMBOO_CHECK_SEND_MODE()) {
962                 cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
963       } else {
964                 send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
965           }
966     } //else 
967           // if mem == NULL, the gcflag of the startup core has been set
968           // and all the other cores have been informed to start gc
969 #ifdef MULTICORE_GC
970   }
971 #endif
972   }
973 }
974
975 INLINE void processmsg_memresponse_I() {
976   int data1 = msgdata[msgdataindex];
977   MSG_INDEXINC_I();
978   int data2 = msgdata[msgdataindex];
979   MSG_INDEXINC_I();
980   // receive a shared memory response msg
981 #ifndef CLOSE_PRINT
982   BAMBOO_DEBUGPRINT(0xe88b);
983 #endif
984 #ifdef MULTICORE_GC
985   // if is currently doing gc, dump this msg
986   if(!gcprocessing) {
987 #endif
988   if(data2 == 0) {
989     bamboo_smem_size = 0;
990     bamboo_cur_msp = 0;
991 #ifdef MULTICORE_GC
992         bamboo_smem_zero_top = 0;
993 #endif
994   } else {
995 #ifdef MULTICORE_GC
996     // fill header to store the size of this mem block
997     BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE); 
998     (*((int*)data1)) = data2;
999     bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
1000     bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
1001         bamboo_smem_zero_top = bamboo_cur_msp;
1002 #else
1003     bamboo_smem_size = data2;
1004     bamboo_cur_msp =(void*)(data1);
1005 #endif
1006   }
1007   smemflag = true;
1008 #ifdef MULTICORE_GC
1009 }
1010 #endif
1011 }
1012
1013 #ifdef MULTICORE_GC
1014 INLINE void processmsg_gcstartpre_I() {
1015   if(gcprocessing) {
1016         // already stall for gc
1017         // send a update pregc information msg to the master core
1018         if(BAMBOO_CHECK_SEND_MODE()) {
1019           cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, 
1020                   self_numsendobjs, self_numreceiveobjs);
1021         } else {
1022           send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, 
1023                   self_numsendobjs, self_numreceiveobjs, true);
1024         }
1025   } else {
1026         // the first time to be informed to start gc
1027         gcflag = true;
1028         if(!smemflag) {
1029           // is waiting for response of mem request
1030           // let it return NULL and start gc
1031           bamboo_smem_size = 0;
1032           bamboo_cur_msp = NULL;
1033           smemflag = true;
1034           bamboo_smem_zero_top = NULL;
1035         }
1036   }
1037 }
1038
1039 INLINE void processmsg_gcstartinit_I() {
1040   gcphase = INITPHASE;
1041 }
1042
1043 INLINE void processmsg_gcstart_I() {
1044 #ifndef CLOSE_PRINT
1045   BAMBOO_DEBUGPRINT(0xe88c);
1046 #endif
1047   // set the GC flag
1048   gcphase = MARKPHASE;
1049 }
1050
1051 INLINE void processmsg_gcstartcompact_I() {
1052   gcblock2fill = msgdata[msgdataindex];
1053   MSG_INDEXINC_I();  //msgdata[1];
1054   gcphase = COMPACTPHASE;
1055 }
1056
1057 INLINE void processmsg_gcstartmapinfo_I() {
1058   gcphase = MAPPHASE;
1059 }
1060
1061 INLINE void processmsg_gcstartflush_I() {
1062   gcphase = FLUSHPHASE;
1063 }
1064
1065 INLINE void processmsg_gcfinishpre_I() {
1066   int data1 = msgdata[msgdataindex];
1067   MSG_INDEXINC_I();
1068   int data2 = msgdata[msgdataindex];
1069   MSG_INDEXINC_I();
1070   int data3 = msgdata[msgdataindex];
1071   MSG_INDEXINC_I();
1072   // received a init phase finish msg
1073   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1074     // non startup core can not receive this msg
1075 #ifndef CLOSE_PRINT
1076     BAMBOO_DEBUGPRINT_REG(data1);
1077 #endif
1078     BAMBOO_EXIT(0xe014);
1079   }
1080   // All cores should do init GC
1081   if(!gcprecheck) {
1082         gcprecheck = true;
1083   }
1084   gccorestatus[data1] = 0;
1085   gcnumsendobjs[0][data1] = data2;
1086   gcnumreceiveobjs[0][data1] = data3;
1087 }
1088
1089 INLINE void processmsg_gcfinishinit_I() {
1090   int data1 = msgdata[msgdataindex];
1091   MSG_INDEXINC_I();
1092   // received a init phase finish msg
1093   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1094     // non startup core can not receive this msg
1095 #ifndef CLOSE_PRINT
1096     BAMBOO_DEBUGPRINT_REG(data1);
1097 #endif
1098     BAMBOO_EXIT(0xe015);
1099   }
1100 #ifndef CLOSE_PRINT
1101   BAMBOO_DEBUGPRINT(0xe88c);
1102   BAMBOO_DEBUGPRINT_REG(data1);
1103 #endif
1104   // All cores should do init GC
1105   if(data1 < NUMCORESACTIVE) {
1106     gccorestatus[data1] = 0;
1107   }
1108 }
1109
1110 INLINE void processmsg_gcfinishmark_I() {
1111   int data1 = msgdata[msgdataindex];
1112   MSG_INDEXINC_I();
1113   int data2 = msgdata[msgdataindex];
1114   MSG_INDEXINC_I();
1115   int data3 = msgdata[msgdataindex];
1116   MSG_INDEXINC_I();
1117   // received a mark phase finish msg
1118   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1119     // non startup core can not receive this msg
1120 #ifndef CLOSE_PRINT
1121     BAMBOO_DEBUGPRINT_REG(data1);
1122 #endif
1123     BAMBOO_EXIT(0xe016);
1124   }
1125   // all cores should do mark
1126   if(data1 < NUMCORESACTIVE) {
1127     gccorestatus[data1] = 0;
1128         int entry_index = 0;
1129         if(waitconfirm)  {
1130           // phase 2
1131           entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
1132         } else {
1133           // phase 1
1134           entry_index = gcnumsrobjs_index;
1135         }
1136     gcnumsendobjs[entry_index][data1] = data2;
1137     gcnumreceiveobjs[entry_index][data1] = data3;
1138   }
1139 }
1140
1141 INLINE void processmsg_gcfinishcompact_I() {
1142   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1143     // non startup core can not receive this msg
1144     // return -1
1145 #ifndef CLOSE_PRINT
1146     BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
1147 #endif
1148     BAMBOO_EXIT(0xe017);
1149   }
1150   int cnum = msgdata[msgdataindex];
1151   MSG_INDEXINC_I();       //msgdata[1];
1152   int filledblocks = msgdata[msgdataindex];
1153   MSG_INDEXINC_I();       //msgdata[2];
1154   int heaptop = msgdata[msgdataindex];
1155   MSG_INDEXINC_I();       //msgdata[3];
1156   int data4 = msgdata[msgdataindex];
1157   MSG_INDEXINC_I();       //msgdata[4];
1158   // only gc cores need to do compact
1159   if(cnum < NUMCORES4GC) {
1160     if(COMPACTPHASE == gcphase) {
1161       gcfilledblocks[cnum] = filledblocks;
1162       gcloads[cnum] = heaptop;
1163     }
1164     if(data4 > 0) {
1165       // ask for more mem
1166       int startaddr = 0;
1167       int tomove = 0;
1168       int dstcore = 0;
1169       if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
1170                 // cache the msg first
1171                 if(BAMBOO_CHECK_SEND_MODE()) {
1172                   cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
1173                 } else {
1174                   send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
1175                 }
1176       }
1177     } else {
1178       gccorestatus[cnum] = 0;
1179     }  // if(data4>0)
1180   }  // if(cnum < NUMCORES4GC)
1181 }
1182
1183 INLINE void processmsg_gcfinishmapinfo_I() {
1184   int data1 = msgdata[msgdataindex];
1185   MSG_INDEXINC_I();
1186   // received a map phase finish msg
1187   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1188     // non startup core can not receive this msg
1189 #ifndef CLOSE_PRINT
1190     BAMBOO_DEBUGPRINT_REG(data1);
1191 #endif
1192     BAMBOO_EXIT(0xe018);
1193   }
1194   // all cores should do flush
1195   if(data1 < NUMCORES4GC) {
1196     gccorestatus[data1] = 0;
1197   }
1198 }
1199
1200
1201 INLINE void processmsg_gcfinishflush_I() {
1202   int data1 = msgdata[msgdataindex];
1203   MSG_INDEXINC_I();
1204   // received a flush phase finish msg
1205   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1206     // non startup core can not receive this msg
1207 #ifndef CLOSE_PRINT
1208     BAMBOO_DEBUGPRINT_REG(data1);
1209 #endif
1210     BAMBOO_EXIT(0xe019);
1211   }
1212   // all cores should do flush
1213   if(data1 < NUMCORESACTIVE) {
1214     gccorestatus[data1] = 0;
1215   }
1216 }
1217
1218 INLINE void processmsg_gcmarkconfirm_I() {
1219   if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
1220      || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
1221     // wrong core to receive such msg
1222     BAMBOO_EXIT(0xe01a);
1223   } else {
1224     // send response msg, cahce the msg first
1225     if(BAMBOO_CHECK_SEND_MODE()) {
1226           cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
1227                                   gcbusystatus, gcself_numsendobjs,
1228                                   gcself_numreceiveobjs);
1229     } else {
1230           send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
1231                                  gcbusystatus, gcself_numsendobjs,
1232                                  gcself_numreceiveobjs, true);
1233     }
1234   }
1235 }
1236
1237 INLINE void processmsg_gcmarkreport_I() {
1238   int data1 = msgdata[msgdataindex];
1239   MSG_INDEXINC_I();
1240   int data2 = msgdata[msgdataindex];
1241   MSG_INDEXINC_I();
1242   int data3 = msgdata[msgdataindex];
1243   MSG_INDEXINC_I();
1244   int data4 = msgdata[msgdataindex];
1245   MSG_INDEXINC_I();
1246   // received a marked phase finish confirm response msg
1247   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1248     // wrong core to receive such msg
1249 #ifndef CLOSE_PRINT
1250     BAMBOO_DEBUGPRINT_REG(data2);
1251 #endif
1252     BAMBOO_EXIT(0xe01b);
1253   } else {
1254         int entry_index = 0;
1255     if(waitconfirm) {
1256           // phse 2
1257       numconfirm--;
1258           entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
1259     } else {
1260           // can never reach here
1261           // phase 1
1262           entry_index = gcnumsrobjs_index;
1263         }
1264     gccorestatus[data1] = data2;
1265     gcnumsendobjs[entry_index][data1] = data3;
1266     gcnumreceiveobjs[entry_index][data1] = data4;
1267   }
1268 }
1269
1270 INLINE void processmsg_gcmarkedobj_I() {
1271   int data1 = msgdata[msgdataindex];
1272   MSG_INDEXINC_I();
1273   // received a markedObj msg
1274   if(((int *)data1)[6] == INIT) {
1275     // this is the first time that this object is discovered,
1276     // set the flag as DISCOVERED
1277     ((int *)data1)[6] = DISCOVERED;
1278     gc_enqueue_I(data1);
1279   } 
1280   // set the remote flag
1281   ((int *)data1)[6] |= REMOTEM;
1282   gcself_numreceiveobjs++;
1283   gcbusystatus = true;
1284 }
1285
1286 INLINE void processmsg_gcmovestart_I() {
1287   gctomove = true;
1288   gcdstcore = msgdata[msgdataindex];
1289   MSG_INDEXINC_I();       //msgdata[1];
1290   gcmovestartaddr = msgdata[msgdataindex];
1291   MSG_INDEXINC_I();       //msgdata[2];
1292   gcblock2fill = msgdata[msgdataindex];
1293   MSG_INDEXINC_I();       //msgdata[3];
1294 }
1295
1296 INLINE void processmsg_gcmaprequest_I() {
1297   void * dstptr = NULL;
1298   int data1 = msgdata[msgdataindex];
1299   MSG_INDEXINC_I();
1300   int data2 = msgdata[msgdataindex];
1301   MSG_INDEXINC_I();
1302 #ifdef LOCALHASHTBL_TEST
1303   RuntimeHashget(gcpointertbl, data1, &dstptr);
1304 #else
1305   dstptr = mgchashSearch(gcpointertbl, data1);
1306 #endif
1307   if(NULL == dstptr) {
1308     // no such pointer in this core, something is wrong
1309 #ifndef CLOSE_PRINT
1310     BAMBOO_DEBUGPRINT_REG(data1);
1311     BAMBOO_DEBUGPRINT_REG(data2);
1312 #endif
1313     BAMBOO_EXIT(0xe01c);
1314   } else {
1315     // send back the mapping info, cache the msg first
1316     if(BAMBOO_CHECK_SEND_MODE()) {
1317           cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
1318     } else {
1319           send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
1320     }
1321   }
1322 }
1323
1324 INLINE void processmsg_gcmapinfo_I() {
1325   int data1 = msgdata[msgdataindex];
1326   MSG_INDEXINC_I();
1327   gcmappedobj = msgdata[msgdataindex];  // [2]
1328   MSG_INDEXINC_I();
1329 #ifdef LOCALHASHTBL_TEST
1330   RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
1331 #else
1332   mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
1333 #endif
1334   if(data1 == gcobj2map) {
1335         gcismapped = true;
1336   }
1337 }
1338
1339 INLINE void processmsg_gcmaptbl_I() {
1340   int data1 = msgdata[msgdataindex];
1341   MSG_INDEXINC_I();
1342   int data2 = msgdata[msgdataindex];
1343   MSG_INDEXINC_I();
1344   gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; 
1345 }
1346
1347 INLINE void processmsg_gclobjinfo_I() {
1348   numconfirm--;
1349
1350   int data1 = msgdata[msgdataindex];
1351   MSG_INDEXINC_I();
1352   int data2 = msgdata[msgdataindex];
1353   MSG_INDEXINC_I();
1354   if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
1355 #ifndef CLOSE_PRINT
1356     BAMBOO_DEBUGPRINT_REG(data2);
1357 #endif
1358     BAMBOO_EXIT(0xe01d);
1359   }
1360   // store the mark result info
1361   int cnum = data2;
1362   gcloads[cnum] = msgdata[msgdataindex];
1363   MSG_INDEXINC_I();       // msgdata[3];
1364   int data4 = msgdata[msgdataindex];
1365   MSG_INDEXINC_I();
1366   if(gcheaptop < data4) {
1367     gcheaptop = data4;
1368   }
1369   // large obj info here
1370   for(int k = 5; k < data1; k+=2) {
1371     int lobj = msgdata[msgdataindex];
1372     MSG_INDEXINC_I();   //msgdata[k++];
1373     int length = msgdata[msgdataindex];
1374     MSG_INDEXINC_I();   //msgdata[k++];
1375     gc_lobjenqueue_I(lobj, length, cnum);
1376     gcnumlobjs++;
1377   }  // for(int k = 5; k < msgdata[1];)
1378 }
1379
1380 INLINE void processmsg_gclobjmapping_I() {
1381   int data1 = msgdata[msgdataindex];
1382   MSG_INDEXINC_I();
1383   int data2 = msgdata[msgdataindex];
1384   MSG_INDEXINC_I();
1385 #ifdef LOCALHASHTBL_TEST
1386   RuntimeHashadd_I(gcpointertbl, data1, data2);
1387 #else
1388   mgchashInsert_I(gcpointertbl, data1, data2);
1389 #endif
1390   mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
1391 }
1392
1393 #ifdef GC_PROFILE
1394 INLINE void processmsg_gcprofiles_I() {
1395   int data1 = msgdata[msgdataindex];
1396   MSG_INDEXINC_I();
1397   int data2 = msgdata[msgdataindex];
1398   MSG_INDEXINC_I();
1399   int data3 = msgdata[msgdataindex];
1400   MSG_INDEXINC_I();
1401   gc_num_obj += data1;
1402   gc_num_liveobj += data2;
1403   gc_num_forwardobj += data3;
1404   gc_num_profiles--;
1405 }
1406 #endif // GC_PROFILE
1407
1408 #ifdef GC_CACHE_ADAPT
1409 INLINE void processmsg_gcstartpref_I() {
1410   gcphase = PREFINISHPHASE;
1411 }
1412
1413 INLINE void processmsg_gcfinishpref_I() {
1414   int data1 = msgdata[msgdataindex];
1415   MSG_INDEXINC_I();
1416   // received a flush phase finish msg
1417   if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
1418     // non startup core can not receive this msg
1419 #ifndef CLOSE_PRINT
1420     BAMBOO_DEBUGPRINT_REG(data1);
1421 #endif
1422     BAMBOO_EXIT(0xe01e);
1423   }
1424   // all cores should do flush
1425   if(data1 < NUMCORESACTIVE) {
1426     gccorestatus[data1] = 0;
1427   }
1428 }
1429 #endif // GC_CACHE_ADAPT
1430 #endif // #ifdef MULTICORE_GC
1431
1432 // receive object transferred from other cores
1433 // or the terminate message from other cores
1434 // Should be invoked in critical sections!!
1435 // NOTICE: following format is for threadsimulate version only
1436 //         RAW version please see previous description
1437 // format: type + object
1438 // type: -1--stall msg
1439 //      !-1--object
1440 // return value: 0--received an object
1441 //               1--received nothing
1442 //               2--received a Stall Msg
1443 //               3--received a lock Msg
1444 //               RAW version: -1 -- received nothing
1445 //                            otherwise -- received msg type
1446 int receiveObject(int send_port_pending) {
1447 #ifdef TASK
1448 #ifdef PROFILE_INTERRUPT
1449   if(!interruptInfoOverflow) {
1450     InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
1451     interruptInfoArray[interruptInfoIndex] = intInfo;
1452     intInfo->startTime = BAMBOO_GET_EXE_TIME();
1453     intInfo->endTime = -1;
1454   }
1455 #endif // PROFILE_INTERRUPT
1456 #endif // TASK
1457 msg:
1458   // get the incoming msgs
1459   if(receiveMsg(send_port_pending) == -1) {
1460     return -1;
1461   }
1462 processmsg:
1463   // processing received msgs
1464   int size = 0;
1465   MSG_REMAINSIZE_I(&size);
1466   if((size == 0) || (checkMsgLength_I(size) == -1)) {
1467     // not a whole msg
1468     // have new coming msg
1469     if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
1470       goto msg;
1471     } else {
1472       return -1;
1473     }
1474   }
1475
1476   if(msglength <= size) {
1477     // have some whole msg
1478     MSGTYPE type;
1479     type = msgdata[msgdataindex]; //[0]
1480     MSG_INDEXINC_I();
1481     msgdatafull = false;
1482     switch(type) {
1483 #ifdef TASK
1484     case TRANSOBJ: {
1485       // receive a object transfer msg
1486       processmsg_transobj_I();
1487       break;
1488     }   // case TRANSOBJ
1489 #endif // TASK
1490
1491     case TRANSTALL: {
1492       // receive a stall msg
1493       processmsg_transtall_I();
1494       break;
1495     }   // case TRANSTALL
1496
1497 #ifdef TASK
1498 // GC version have no lock msgs
1499 #ifndef MULTICORE_GC
1500     case LOCKREQUEST: {
1501       // receive lock request msg, handle it right now
1502       processmsg_lockrequest_I();
1503       break;
1504     }   // case LOCKREQUEST
1505
1506     case LOCKGROUNT: {
1507       // receive lock grount msg
1508       processmsg_lockgrount_I();
1509       break;
1510     }   // case LOCKGROUNT
1511
1512     case LOCKDENY: {
1513       // receive lock deny msg
1514       processmsg_lockdeny_I();
1515       break;
1516     }   // case LOCKDENY
1517
1518     case LOCKRELEASE: {
1519       processmsg_lockrelease_I();
1520       break;
1521     }   // case LOCKRELEASE
1522 #endif // #ifndef MULTICORE_GC
1523
1524 #ifdef PROFILE
1525     case PROFILEOUTPUT: {
1526       // receive an output profile data request msg
1527       processmsg_profileoutput_I();
1528       break;
1529     }   // case PROFILEOUTPUT
1530
1531     case PROFILEFINISH: {
1532       // receive a profile output finish msg
1533       processmsg_profilefinish_I();
1534       break;
1535     }   // case PROFILEFINISH
1536 #endif // #ifdef PROFILE
1537
1538 // GC version has no lock msgs
1539 #ifndef MULTICORE_GC
1540     case REDIRECTLOCK: {
1541       // receive a redirect lock request msg, handle it right now
1542       processmsg_redirectlock_I();
1543       break;
1544     }   // case REDIRECTLOCK
1545
1546     case REDIRECTGROUNT: {
1547       // receive a lock grant msg with redirect info
1548       processmsg_redirectgrount_I();
1549       break;
1550     }   // case REDIRECTGROUNT
1551
1552     case REDIRECTDENY: {
1553       // receive a lock deny msg with redirect info
1554       processmsg_redirectdeny_I();
1555       break;
1556     }   // case REDIRECTDENY
1557
1558     case REDIRECTRELEASE: {
1559       // receive a lock release msg with redirect info
1560       processmsg_redirectrelease_I();
1561       break;
1562     }   // case REDIRECTRELEASE
1563 #endif // #ifndef MULTICORE_GC
1564 #endif // TASK
1565
1566     case STATUSCONFIRM: {
1567       // receive a status confirm info
1568       processmsg_statusconfirm_I();
1569       break;
1570     }   // case STATUSCONFIRM
1571
1572     case STATUSREPORT: {
1573       processmsg_statusreport_I();
1574       break;
1575     }   // case STATUSREPORT
1576
1577     case TERMINATE: {
1578       // receive a terminate msg
1579       processmsg_terminate_I();
1580       break;
1581     }   // case TERMINATE
1582
1583     case MEMREQUEST: {
1584       processmsg_memrequest_I();
1585       break;
1586     }   // case MEMREQUEST
1587
1588     case MEMRESPONSE: {
1589       processmsg_memresponse_I();
1590       break;
1591     }   // case MEMRESPONSE
1592
1593 #ifdef MULTICORE_GC
1594     // GC msgs
1595     case GCSTARTPRE: {
1596       processmsg_gcstartpre_I();
1597       break;
1598     }   // case GCSTARTPRE
1599         
1600         case GCSTARTINIT: {
1601       processmsg_gcstartinit_I();
1602       break;
1603     }   // case GCSTARTINIT
1604
1605     case GCSTART: {
1606       // receive a start GC msg
1607       processmsg_gcstart_I();
1608       break;
1609     }   // case GCSTART
1610
1611     case GCSTARTCOMPACT: {
1612       // a compact phase start msg
1613       processmsg_gcstartcompact_I();
1614       break;
1615     }   // case GCSTARTCOMPACT
1616
1617         case GCSTARTMAPINFO: {
1618       // received a flush phase start msg
1619       processmsg_gcstartmapinfo_I();
1620       break;
1621     }   // case GCSTARTFLUSH
1622
1623     case GCSTARTFLUSH: {
1624       // received a flush phase start msg
1625       processmsg_gcstartflush_I();
1626       break;
1627     }   // case GCSTARTFLUSH
1628
1629     case GCFINISHPRE: {
1630       processmsg_gcfinishpre_I();
1631       break;
1632     }   // case GCFINISHPRE
1633         
1634         case GCFINISHINIT: {
1635       processmsg_gcfinishinit_I();
1636       break;
1637     }   // case GCFINISHINIT
1638
1639     case GCFINISHMARK: {
1640       processmsg_gcfinishmark_I();
1641       break;
1642     }   // case GCFINISHMARK
1643
1644     case GCFINISHCOMPACT: {
1645       // received a compact phase finish msg
1646       processmsg_gcfinishcompact_I();
1647       break;
1648     }   // case GCFINISHCOMPACT
1649
1650         case GCFINISHMAPINFO: {
1651       processmsg_gcfinishmapinfo_I();
1652       break;
1653     }   // case GCFINISHMAPINFO
1654
1655     case GCFINISHFLUSH: {
1656       processmsg_gcfinishflush_I();
1657       break;
1658     }   // case GCFINISHFLUSH
1659
1660     case GCFINISH: {
1661       // received a GC finish msg
1662       gcphase = FINISHPHASE;
1663       break;
1664     }   // case GCFINISH
1665
1666     case GCMARKCONFIRM: {
1667       // received a marked phase finish confirm request msg
1668       // all cores should do mark
1669       processmsg_gcmarkconfirm_I();
1670       break;
1671     }   // case GCMARKCONFIRM
1672
1673     case GCMARKREPORT: {
1674       processmsg_gcmarkreport_I();
1675       break;
1676     }   // case GCMARKREPORT
1677
1678     case GCMARKEDOBJ: {
1679       processmsg_gcmarkedobj_I();
1680       break;
1681     }   // case GCMARKEDOBJ
1682
1683     case GCMOVESTART: {
1684       // received a start moving objs msg
1685       processmsg_gcmovestart_I();
1686       break;
1687     }   // case GCMOVESTART
1688
1689     case GCMAPREQUEST: {
1690       // received a mapping info request msg
1691       processmsg_gcmaprequest_I();
1692       break;
1693     }   // case GCMAPREQUEST
1694
1695     case GCMAPINFO: {
1696       // received a mapping info response msg
1697       processmsg_gcmapinfo_I();
1698       break;
1699     }   // case GCMAPINFO
1700
1701     case GCMAPTBL: {
1702       // received a mapping tbl response msg
1703       processmsg_gcmaptbl_I();
1704       break;
1705     }   // case GCMAPTBL
1706         
1707         case GCLOBJREQUEST: {
1708       // received a large objs info request msg
1709       transferMarkResults_I();
1710       break;
1711     }   // case GCLOBJREQUEST
1712
1713     case GCLOBJINFO: {
1714       // received a large objs info response msg
1715       processmsg_gclobjinfo_I();
1716       break;
1717     }   // case GCLOBJINFO
1718
1719     case GCLOBJMAPPING: {
1720       // received a large obj mapping info msg
1721       processmsg_gclobjmapping_I();
1722       break;
1723     }  // case GCLOBJMAPPING
1724
1725 #ifdef GC_PROFILE
1726         case GCPROFILES: {
1727       // received a gcprofiles msg
1728       processmsg_gcprofiles_I();
1729       break;
1730     }
1731 #endif // GC_PROFILE
1732
1733 #ifdef GC_CACHE_ADAPT
1734         case GCSTARTPREF: {
1735       // received a gcstartpref msg
1736       processmsg_gcstartpref_I();
1737       break;
1738     }
1739
1740         case GCFINISHPREF: {
1741       // received a gcfinishpref msg
1742       processmsg_gcfinishpref_I();
1743       break;
1744     }
1745 #endif // GC_CACHE_ADAPT
1746 #endif // #ifdef MULTICORE_GC
1747
1748     default:
1749       break;
1750     }  // switch(type)
1751     msglength = BAMBOO_MSG_BUF_LENGTH;
1752
1753     if((msgdataindex != msgdatalast) || (msgdatafull)) {
1754       // still have available msg
1755       goto processmsg;
1756     }
1757 #ifndef CLOSE_PRINT
1758     BAMBOO_DEBUGPRINT(0xe88d);
1759 #endif
1760
1761     // have new coming msg
1762     if(BAMBOO_MSG_AVAIL() != 0) {
1763       goto msg;
1764     } // TODO
1765
1766 #ifdef TASK
1767 #ifdef PROFILE_INTERRUPT
1768   if(!interruptInfoOverflow) {
1769     interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
1770     interruptInfoIndex++;
1771     if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
1772       interruptInfoOverflow = true;
1773     }
1774   }
1775 #endif
1776 #endif // TASK
1777     return (int)type;
1778   } else {
1779     // not a whole msg
1780 #ifndef CLOSE_PRINT
1781     BAMBOO_DEBUGPRINT(0xe88e);
1782 #endif
1783     return -2;
1784   }
1785 }
1786
1787 #endif // MULTICORE