Add gcprofile to PMC garbage collector and compute the size of allocated obj instead...
[IRC.git] / Robust / src / Runtime / bamboo / multicoreruntime.c
1 #ifdef MULTICORE
2 #include "runtime.h"
3 #include "multicoreruntime.h"
4 #include "methodheaders.h"
5 #include "multicoregarbage.h"
6 #ifdef PMC_GC
7 #include "multicoregcprofile.h"
8 #include "multicoregc.h"
9 #include "pmc_garbage.h"
10 #endif
11 #include "multicore_arch.h"
12 #include <stdio.h>
13 #ifdef PERFCOUNT
14 #include "bme_perf_counter.h"
15 #endif
16
17 extern int classsize[];
18 extern int typearray[];
19 extern int typearray2[];
20 extern int* supertypes[];
21
22 #ifdef TASK
23 extern struct genhashtable * activetasks;
24 #endif
25
26 #ifdef MGC
27 int corenum = 0;
28 #endif
29
30 int instanceofif(int otype, int type) {
31   if(otype == type) {
32     return 1;
33   }
34   if(otype == -1) {
35     return 0;
36   }
37   int num = supertypes[otype][0];
38   for(int i = 1; i < num + 1; i++) {
39     int t = supertypes[otype][i];
40     if(instanceofif(t, type) == 1) {
41       return 1;
42     }
43   }
44   return 0;
45 }
46
47 int instanceof(struct ___Object___ *ptr, int type) {
48   if(ptr == NULL) {
49     return 0;
50   }
51   int i=ptr->type;
52   if(instanceofif(i, type) == 1) {
53     return 1;
54   }
55   if (i>NUMCLASSES) {
56     do {
57       if (i==type)
58         return 1;
59       i=typearray2[i-NUMCLASSES];
60     } while(i!=-1);
61   }
62   return 0;
63 }
64
65 void initializeexithandler() {
66 }
67
68 /* This function inject failures */
69 void injectinstructionfailure() {
70   // not supported in MULTICORE version
71   return;
72 }
73
74 #ifdef D___Double______nativeparsedouble____L___String___
75 double CALL01(___Double______nativeparsedouble____L___String___,
76               struct ___String___ * ___str___) {
77   int length=VAR(___str___)->___count___;
78   int maxlength=(length>60) ? 60 : length;
79   char str[maxlength+1];
80   struct ArrayObject * chararray=VAR(___str___)->___value___;
81   int i;
82   int offset=VAR(___str___)->___offset___;
83   for(i=0; i<maxlength; i++) {
84     str[i]=
85       ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
86   }
87   str[i]=0;
88   double d=0.0; //atof(str); TODO Unimplemented nativeparsedoulbe
89   return d;
90 }
91 #endif
92
93 #ifdef D___Double______nativeparsedouble_____AR_B_I_I 
94 double CALL23(___Double______nativeparsedouble_____AR_B_I_I, 
95               int start, 
96               int length,
97               int start,
98               int length,
99               struct ArrayObject * ___str___) {
100   int maxlength=(length>60)?60:length;
101   char str[maxlength+1];
102   struct ArrayObject * bytearray=VAR(___str___);
103   int i;
104   for(i=0; i<maxlength; i++) {
105     str[i]=(((char *)&bytearray->___length___)+sizeof(int))[i+start];
106   }
107   str[i]=0;
108   double d=0.0; //atof(str); TODO Unimplemented nativeparsedouble
109   return d;
110 }
111 #endif
112
113 typedef union jvalue {
114   bool z;
115   char    c;
116   short   s;
117   int     i;
118   long long    j;
119   float   f;
120   double  d;
121 } jvalue;
122
123 #ifdef D___Double______doubleToRawLongBits____D 
124 long long CALL11(___Double______doubleToRawLongBits____D, 
125                  double ___value___, 
126                  double ___value___) {
127   jvalue val;
128   val.d = ___value___;
129
130 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
131   /* On little endian ARM processors when using FPA, word order of
132      doubles is still big endian. So take that into account here. When
133      using VFP, word order of doubles follows byte order. */
134 #define SWAP_DOUBLE(a)    (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
135   val.j = SWAP_DOUBLE(val.j);
136 #endif
137
138   return val.j;
139 }
140 #endif
141
142 #ifdef D___Double______longBitsToDouble____J 
143 double CALL11(___Double______longBitsToDouble____J, 
144               long long ___bits___, 
145               long long ___bits___) {
146   jvalue val;
147   val.j = ___bits___;
148
149 #if defined(__IEEE_BYTES_LITTLE_ENDIAN)
150 #ifndef SWAP_DOUBLE
151 #define SWAP_DOUBLE(a)    (((a) << 32) | (((a) >> 32) & 0x00000000ffffffff))
152 #endif
153   val.j = SWAP_DOUBLE(val.j);
154 #endif
155
156   return val.d;
157 }
158 #endif
159
160 #ifdef D___String______convertdoubletochar____D__AR_C
161 int CALL12(___String______convertdoubletochar____D__AR_C, 
162            double ___val___, 
163            double ___val___, 
164            struct ArrayObject * ___chararray___) {
165   int length=VAR(___chararray___)->___length___;
166   char str[length];
167   int i;
168   int num=snprintf(str, length, "%f",___val___);
169   if (num>=length)
170     num=length-1;
171   for(i=0; i<length; i++) {
172     ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=
173       (short)str[i];
174   }
175   return num;
176 }
177 #endif
178
179 #ifdef D___System______deepArrayCopy____L___Object____L___Object___
180 void deepArrayCopy(struct ___Object___ * dst, 
181                    struct ___Object___ * src) {
182   int dsttype=((int *)dst)[0];
183   int srctype=((int *)src)[0];
184   if (dsttype<NUMCLASSES||srctype<NUMCLASSES||srctype!=dsttype)
185     return;
186   struct ArrayObject *aodst=(struct ArrayObject *)dst;
187   struct ArrayObject *aosrc=(struct ArrayObject *)src;
188   int dstlength=aodst->___length___;
189   int srclength=aosrc->___length___;
190   if (dstlength!=srclength)
191     return;
192   unsigned INTPTR *pointer=pointerarray[srctype];
193   if (pointer==0) {
194     int elementsize=classsize[srctype];
195     int size=srclength*elementsize;
196     //primitives
197     memcpy(((char *)&aodst->___length___)+sizeof(int) , 
198         ((char *)&aosrc->___length___)+sizeof(int), size);
199   } else {
200     //objects
201     int i;
202     for(i=0;i<srclength;i++) {
203       struct ___Object___ * ptr=
204         ((struct ___Object___**)(((char*)&aosrc->___length___)+sizeof(int)))[i];
205       int ptrtype=((int *)ptr)[0];
206       if (ptrtype>=NUMCLASSES) {
207         struct ___Object___ * dstptr=((struct ___Object___**)
208             (((char*)&aodst->___length___)+sizeof(int)))[i];
209         deepArrayCopy(dstptr,ptr);
210       } else {
211         //hit an object
212         ((struct ___Object___ **)
213          (((char*) &aodst->___length___)+sizeof(int)))[i]=ptr;
214       }
215     }
216   }
217 }
218
219 void CALL02(___System______deepArrayCopy____L___Object____L___Object___, 
220             struct ___Object___ * ___dst___, 
221             struct ___Object___ * ___src___) {
222   deepArrayCopy(VAR(___dst___), VAR(___src___));
223 }
224 #endif
225
226 #ifdef D___System______arraycopy____L___Object____I_L___Object____I_I
227 void arraycopy(struct ___Object___ *src, 
228                int srcPos, 
229                struct ___Object___ *dst, 
230                int destPos, 
231                int length) {
232   int dsttype=((int *)dst)[0];
233   int srctype=((int *)src)[0];
234
235   //not an array or type mismatch
236   if (dsttype<NUMCLASSES||srctype<NUMCLASSES/*||srctype!=dsttype*/)
237     return;
238
239   struct ArrayObject *aodst=(struct ArrayObject *)dst;
240   struct ArrayObject *aosrc=(struct ArrayObject *)src;
241   int dstlength=aodst->___length___;
242   int srclength=aosrc->___length___;
243
244   if (length<=0)
245     return;
246   if (srcPos+length>srclength)
247     return;
248   if (destPos+length>dstlength)
249     return;
250
251   unsigned INTPTR *pointer=pointerarray[srctype];
252   if (pointer==0) {
253     int elementsize=classsize[srctype];
254     int size=length*elementsize;
255     //primitives
256     memcpy(((char *)&aodst->___length___)+sizeof(int)+destPos*elementsize, 
257         ((char *)&aosrc->___length___)+sizeof(int)+srcPos*elementsize, size);
258   } else {
259     //objects
260     int i;
261     for(i=0;i<length;i++) {
262       struct ___Object___ * ptr=((struct ___Object___**)
263           (((char*)&aosrc->___length___)+sizeof(int)))[i+srcPos];
264       int ptrtype=((int *)ptr)[0];
265       //hit an object
266       ((struct ___Object___ **)
267        (((char*) &aodst->___length___)+sizeof(int)))[i+destPos]=ptr;
268     }
269   }
270 }
271
272 void CALL35(___System______arraycopy____L___Object____I_L___Object____I_I, 
273             int ___srcPos___, 
274             int ___destPos___, 
275             int ___length___, 
276             struct ___Object___ * ___src___, 
277             int ___srcPos___, 
278             struct ___Object___ * ___dst___, 
279             int  ___destPos___, 
280             int ___length___) {
281   arraycopy(VAR(___src___), ___srcPos___, VAR(___dst___), ___destPos___, 
282       ___length___);
283 }
284 #endif
285
286 #ifdef D___System______exit____I
287 void CALL11(___System______exit____I,
288             int ___status___, 
289             int ___status___) {
290 // gc_profile mode, output gc prfiling data
291 #if defined(MULTICORE_GC)||defined(PMC_GC)
292   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
293     BAMBOO_PRINT(BAMBOO_GET_EXE_TIME());
294     BAMBOO_PRINT(0xbbbbbbbb);
295     CACHEADAPT_DISABLE_TIMER();
296     GC_OUTPUT_PROFILE_DATA();
297 #ifdef PERFCOUNT
298     print_statistics();
299 #endif
300     gc_outputProfileDataReadable();
301     tprintf("FINISH_EXECUTION\n");
302   }
303 #endif 
304   BAMBOO_EXIT_APP(___status___);
305 }
306 #endif
307
308 #ifdef D___Vector______removeElement_____AR_L___Object____I_I
309 void CALL23(___Vector______removeElement_____AR_L___Object____I_I, 
310             int ___index___, 
311             int ___size___, 
312             struct ArrayObject * ___array___, 
313             int ___index___, 
314             int ___size___) {
315   char* offset=((char *)(&VAR(___array___)->___length___))
316     +sizeof(unsigned int)+sizeof(void *)*___index___;
317   memmove(offset, offset+sizeof(void *),
318       (___size___-___index___-1)*sizeof(void *));
319 }
320 #endif
321
322 #ifdef D___System______printI____I
323 void CALL11(___System______printI____I,
324             int ___status___, 
325             int ___status___) {
326   BAMBOO_PRINT(0x1111);
327   BAMBOO_PRINT_REG(___status___);
328 }
329 #endif
330
331 #ifdef D___System______currentTimeMillis____
332 long long CALL00(___System______currentTimeMillis____) {
333   //TilePro64 is 700mHz
334   return ((unsigned long long)BAMBOO_GET_EXE_TIME())/700000;
335 }
336 #endif
337
338 #ifdef D___System______setgcprofileflag____
339 void CALL00(___System______setgcprofileflag____) {
340 #ifdef GC_PROFILE
341 #ifdef MGC_SPEC
342   extern volatile bool gc_profile_flag;
343   gc_profile_flag = true;
344 #endif
345 #endif
346 }
347 #endif
348
349 #ifdef D___System______resetgcprofileflag____
350 void CALL00(___System______resetgcprofileflag____) {
351 #ifdef GC_PROFILE
352 #ifdef MGC_SPEC
353   extern volatile bool gc_profile_flag;
354   gc_profile_flag = false;
355 #endif
356 #endif
357 }
358 #endif
359
360 #ifdef D___System______gc____
361 void CALL00(___System______gc____) {
362 #ifdef MULTICORE_GC
363   if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
364     if(!gc_status_info.gcprocessing && !gcflag) {
365       gcflag = true;
366       gcprecheck = true;
367       for(int i = 0; i < NUMCORESACTIVE; i++) {
368         // reuse the gcnumsendobjs & gcnumreceiveobjs
369         gcnumsendobjs[0][i] = 0;
370         gcnumreceiveobjs[0][i] = 0;
371       }
372       for(int i = 0; i < NUMCORES4GC; i++) {
373         if(i != STARTUPCORE) {
374           send_msg_1_I(i,GCSTARTPRE);
375         }
376       }
377     }
378   } else {
379     // send msg to the startup core to start gc
380     send_msg_1(STARTUPCORE, GCINVOKE);
381   }
382 #endif
383 }
384 #endif
385
386 #ifdef D___System______printString____L___String___
387 void CALL01(___System______printString____L___String___, struct ___String___ * ___s___) {
388 #if defined(MGC)&&defined(TILERA_BME)
389   struct ArrayObject * chararray=VAR(___s___)->___value___;
390   int i;
391   int offset=VAR(___s___)->___offset___;
392   tprintf("");
393   for(i=0; i<VAR(___s___)->___count___; i++) {
394     short sc=
395       ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
396     printf("%c", sc);
397   }
398 #endif // MGC
399 }
400 #endif
401
402 /* Object allocation function */
403
404 #if defined(MULTICORE_GC)||defined(PMC_GC)
405 void * allocate_new(void * ptr, 
406                     int type) {
407   struct ___Object___ * v=
408     (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
409   v->type=type;
410 #ifdef TASK
411   v->version = 0;
412   v->lock = NULL;
413   v->lockcount = 0;
414 #endif
415   initlock(v);
416   return v;
417 }
418
419 /* Array allocation function */
420
421 struct ArrayObject * allocate_newarray(void * ptr, 
422                                        int type, 
423                                        int length) {
424   struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC(
425       (struct garbagelist*)ptr,
426       sizeof(struct ArrayObject)+length*classsize[type]);
427   v->type=type;
428 #ifdef TASK
429   v->version = 0;
430   v->lock = NULL;
431 #endif
432   if (length<0) {
433     return NULL;
434   }
435   v->___length___=length;
436   initlock((struct ___Object___ *)v);
437   return v;
438 }
439
440 #else
441 void * allocate_new(int type) {
442   struct ___Object___ * v=FREEMALLOC(classsize[type]);
443   v->type=type;
444 #ifdef TASK
445   v->version = 0;
446   v->lock = NULL;
447 #endif
448   initlock(v);
449   return v;
450 }
451
452 /* Array allocation function */
453
454 struct ArrayObject * allocate_newarray(int type, 
455                                        int length) {
456   struct ArrayObject * v=FREEMALLOC(
457       sizeof(struct ArrayObject)+length*classsize[type]);
458   v->type=type;
459 #ifdef TASK
460   v->version = 0;
461   v->lock = NULL;
462 #endif
463   v->___length___=length;
464   initlock((struct ___Object___ *) v);
465   return v;
466 }
467 #endif
468
469 /* Converts C character arrays into Java strings */
470 #if defined(MULTICORE_GC)||defined(PMC_GC)
471 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr, 
472                                                              const short *str,
473                                                              int length) {
474 #else
475 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,
476                                                              int length) {
477 #endif
478   int i;
479 #if defined(MULTICORE_GC)||defined(PMC_GC)
480   struct ArrayObject * chararray=
481     allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
482   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
483   struct ___String___ * strobj=
484     allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
485   chararray=(struct ArrayObject *) ptrarray[2];
486 #else
487   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
488   struct ___String___ * strobj=allocate_new(STRINGTYPE);
489 #endif
490   strobj->___value___=chararray;
491   strobj->___count___=length;
492   strobj->___offset___=0;
493
494   for(i=0; i<length; i++) {
495     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
496   }
497   return strobj;
498 }
499
500 /* Converts C character arrays into Java strings */
501 #if defined(MULTICORE_GC)||defined(PMC_GC)
502 struct ___String___ * NewString(void * ptr, 
503                                 const char *str,
504                                 int length) {
505 #else
506 struct ___String___ * NewString(const char *str,
507                                 int length) {
508 #endif
509   int i;
510 #if defined(MULTICORE_GC)||defined(PMC_GC)
511   struct ArrayObject * chararray=
512     allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
513   int ptrarray[]={1, (int) ptr, (int) chararray};
514   struct ___String___ * strobj=
515     allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
516   chararray=(struct ArrayObject *) ptrarray[2];
517 #else
518   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
519   struct ___String___ * strobj=allocate_new(STRINGTYPE);
520 #endif
521   strobj->___value___=chararray;
522   strobj->___count___=length;
523   strobj->___offset___=0;
524
525   for(i=0; i<length; i++) {
526     ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
527   }
528   return strobj;
529 }
530
531 /* Generated code calls this if we fail a bounds check */
532
533  void failedboundschk(int num, int index, struct ArrayObject * ao) {
534 #ifndef TASK
535   printf("Array out of bounds at line %u with index %u of object %x with lengt\
536 h %u\n", num, index, ao, ao->___length___);
537 #ifdef THREADS
538   threadexit();
539 #elif defined MGC
540   BAMBOO_EXIT();
541 #else
542   exit(-1);
543 #endif
544 #else
545 #ifndef MULTICORE
546   printf("Array out of bounds\n");
547   longjmp(error_handler,2);
548 #else
549   BAMBOO_EXIT();
550 #endif
551 #endif
552 }
553
554 /* Generated code calls this if we fail null ptr chk */
555 void failednullptr(void * ptr) {
556 #if defined(MULTICORE_GC)||defined(PMC_GC)
557 #ifndef RAW
558   //print out current stack
559   int i,j;
560   j = 0;
561   struct garbagelist * stackptr = (struct garbagelist *)ptr;
562   while(stackptr!=NULL) {
563     tprintf("Stack %d: \n\t", j);
564     for(i=0; i<stackptr->size; i++) {
565       if(stackptr->array[i] != NULL) {
566         tprintf("%x, ", stackptr->array[i]);
567       } else {
568         tprintf("NULL, ");
569       }
570     }
571     tprintf("\n");
572     stackptr=stackptr->next;
573   }
574 #endif
575 #endif
576 #ifndef TASK
577   printf("NULL ptr\n");
578 #ifdef THREADS
579   threadexit();
580 #elif defined MGC
581   BAMBOO_EXIT();
582 #else
583   exit(-1);
584 #endif
585 #else
586 #ifndef MULTICORE
587   printf("NULL ptr\n");
588   longjmp(error_handler,2);
589 #else
590   BAMBOO_EXIT();
591 #endif
592 #endif
593 }
594
595 /* Abort task call */
596 void abort_task() {
597 #ifdef TASK
598 #ifndef MULTICORE
599   printf("Aborting\n");
600   longjmp(error_handler,4);
601 #endif
602 #else
603   printf("Aborting\n");
604   exit(-1);
605 #endif
606 }
607
608 void initruntimedata() {
609   // initialize the arrays
610   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
611     // startup core to initialize corestatus[]
612     for(int i = 0; i < NUMCORESACTIVE; ++i) {
613       corestatus[i] = 1;
614       numsendobjs[i] = 0;
615       numreceiveobjs[i] = 0;
616     } 
617     numconfirm = 0;
618     waitconfirm = false;
619   }
620
621   busystatus = true;
622   self_numsendobjs = 0;
623   self_numreceiveobjs = 0;
624
625   for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
626     msgdata[i] = -1;
627   }
628   msgdataindex = 0;
629   msgdatalast = 0;
630   //msglength = BAMBOO_MSG_BUF_LENGTH;
631   msgdatafull = false;
632   for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
633     outmsgdata[i] = -1;
634   }
635   outmsgindex = 0;
636   outmsglast = 0;
637   outmsgleft = 0;
638   isMsgHanging = false;
639   
640   smemflag = true;
641   bamboo_cur_msp = NULL;
642   bamboo_smem_size = 0;
643 #ifndef INTERRUPT
644   reside = false;
645 #endif
646
647   INITMULTICOREGCDATA();
648
649 #ifdef MGC
650   initializethreads();
651   bamboo_current_thread = NULL;
652 #endif // MGC
653
654   INITTASKDATA();
655 }
656
657 void disruntimedata() {
658   DISMULTICOREGCDATA();
659   DISTASKDATA();
660   BAMBOO_LOCAL_MEM_CLOSE();
661   BAMBOO_SHARE_MEM_CLOSE();
662 }
663
664 void recordtotalexetime() {
665 #ifdef USEIO
666   totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
667 #else // USEIO
668   unsigned long long timediff=BAMBOO_GET_EXE_TIME()-bamboo_start_time;
669   BAMBOO_PRINT(timediff);
670 #ifndef BAMBOO_MEMPROF
671   BAMBOO_PRINT(0xbbbbbbbb);
672 #endif
673 #endif // USEIO
674 }
675
676 void getprofiledata_I() {
677   //profile mode, send msgs to other cores to request pouring out progiling data
678 #ifdef PROFILE
679   // use numconfirm to check if all cores have finished output task profiling 
680   // information. This is safe as when the execution reaches this phase there 
681   // should have no other msgs except the PROFILEFINISH msg, there should be 
682   // no gc too.
683   numconfirm=NUMCORESACTIVE-1;
684   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
685   for(i = 1; i < NUMCORESACTIVE; ++i) {
686     // send profile request msg to core i
687     send_msg_2(i, PROFILEOUTPUT, totalexetime);
688   } 
689 #ifndef RT_TEST
690   // pour profiling data on startup core
691   outputProfileData();
692 #endif
693   while(true) {
694     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
695     if(numconfirm != 0) {
696       int halt = 100;
697       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
698       while(halt--) {
699       }
700     } else {
701       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
702       break;
703     }  
704   } 
705 #endif
706 }
707
708 void checkCoreStatus() {
709   int i = 0;
710   int sumsendobj = 0;
711   if((!waitconfirm) ||
712      (waitconfirm && (numconfirm == 0))) {
713     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
714     corestatus[BAMBOO_NUM_OF_CORE] = 0;
715     numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
716     numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
717     // check the status of all cores
718     for(i = 0; i < NUMCORESACTIVE; ++i) {
719       if(corestatus[i] != 0) {
720         break;
721       }
722     } 
723     if(i == NUMCORESACTIVE) {
724       // check if the sum of send objs and receive obj are the same
725       // yes->check if the info is the latest; no->go on executing
726       sumsendobj = 0;
727       for(i = 0; i < NUMCORESACTIVE; ++i) {
728         sumsendobj += numsendobjs[i];
729       } 
730       for(i = 0; i < NUMCORESACTIVE; ++i) {
731         sumsendobj -= numreceiveobjs[i];
732       }  
733       if(0 == sumsendobj) {
734         if(!waitconfirm) {
735           // the first time found all cores stall
736           // send out status confirm msg to all other cores
737           // reset the corestatus array too
738           corestatus[BAMBOO_NUM_OF_CORE] = 1;
739           waitconfirm = true;
740           numconfirm = NUMCORESACTIVE - 1;
741           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
742           for(i = 1; i < NUMCORESACTIVE; ++i) {
743             corestatus[i] = 1;
744             // send status confirm msg to core i
745             send_msg_1(i, STATUSCONFIRM);
746           }   
747           return;
748         } else {
749           // all the core status info are the latest
750           // terminate; for profiling mode, send request to all
751           // other cores to pour out profiling data
752           recordtotalexetime();
753           getprofiledata_I();
754           CACHEADAPT_DISABLE_TIMER();
755           GC_OUTPUT_PROFILE_DATA();
756 #ifdef PERFCOUNT
757           print_statistics();
758 #endif
759           gc_outputProfileDataReadable();
760           disruntimedata();
761           tprintf("FINISH_EXECUTION\n");
762           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
763           terminate();  // All done.
764         }
765       } else {          
766         // still some objects on the fly on the network
767         // reset the waitconfirm and numconfirm
768         waitconfirm = false;
769         numconfirm = 0;
770       }  
771     } else {
772       // not all cores are stall, keep on waiting
773       waitconfirm = false;
774       numconfirm = 0;
775     }  
776     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
777   } 
778 }
779
780 // main function for each core
781 void run(int argc, char** argv) {
782   bool sendStall = false;
783   bool isfirst = true;
784   bool tocontinue = false;
785   startflag = false;
786   corenum = BAMBOO_GET_NUM_OF_CORE();
787   // initialize runtime data structures
788   initruntimedata();
789   initCommunication();
790 #ifdef PMC_GC
791   pmc_onceInit();
792 #endif
793 #ifdef PERFCOUNT
794   if (BAMBOO_NUM_OF_CORE==STARTUPCORE)
795     profile_init(_LOCAL_DRD_CNT,_LOCAL_WR_CNT, _REMOTE_DRD_CNT, _REMOTE_WR_CNT);
796   else {
797     int offcore=4*(BAMBOO_NUM_OF_CORE-1);
798     profile_init(validevents[(offcore)%87], validevents[(offcore+1)%87], validevents[(offcore+2)%87], validevents[(offcore+3)%87]);
799   }
800 #endif
801   if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
802     numconfirm=NUMCORES-1;
803     for(int i=0;i<NUMCORES;i++) {
804       if (i!=STARTUPCORE) {
805         send_msg_1(i,REQNOTIFYSTART);
806       }
807     }
808     while(numconfirm!=0)
809       ;
810     tprintf("START_EXECUTION\n");
811     bamboo_start_time = BAMBOO_GET_EXE_TIME();
812   } else {
813     while(!startflag)
814       ;
815   }
816 #ifdef PERFCOUNT
817   bme_performance_counter_start();
818 #endif
819
820   CACHEADAPT_ENABLE_TIMER();
821
822   initializeexithandler();
823
824   // main process of the execution module
825   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
826 #ifdef TASK
827     // non-executing cores, only processing communications
828     activetasks = NULL;
829 #endif
830     fakeExecution();
831   } else {
832 #ifdef TASK
833     /* Create queue of active tasks */
834     activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
835                                       (int (*)(void *,void *)) &comparetpd);
836     
837     /* Process task information */
838     processtasks();
839     
840     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
841       /* Create startup object */
842       createstartupobject(argc, argv);
843     }
844 #endif
845     
846 #ifdef PERFCOUNT
847       profile_start(APP_REGION);
848 #endif
849     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
850 #ifdef TASK
851       // run the initStaticAndGlobal method to initialize the static blocks and
852       // global fields
853       initStaticAndGlobal();
854 #elif defined MGC
855       // run the main method in the specified mainclass
856       mgc_main(argc, argv);
857 #endif // TASK
858     }
859     
860     while(true) {
861       GCCHECK(NULL);
862 #ifdef TASK
863       // check if there are new active tasks can be executed
864       executetasks();
865       if(busystatus) {
866         sendStall = false;
867       }
868 #ifndef INTERRUPT
869       while(receiveObject_I() != -1) {
870       }
871 #endif
872       // check if there are some pending objects,
873       // if yes, enqueue them and executetasks again
874       tocontinue = checkObjQueue();
875 #elif defined MGC
876       tocontinue = trystartthread();
877       if(tocontinue) {
878         sendStall = false;
879       }
880 #endif
881       
882       if(!tocontinue) {
883         // check if stop
884         if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
885           if(isfirst) {
886             isfirst = false;
887           }
888           checkCoreStatus();
889         } else {
890           if(!sendStall) {
891 #ifdef PROFILE
892             if(!stall) {
893 #endif
894               if(isfirst) {
895                 // wait for some time
896                 int halt = 10000;
897                 while(halt--) {
898                 }
899                 isfirst = false;
900               } else {
901                 // send StallMsg to startup core
902                 // send stall msg
903                 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
904                 sendStall = true;
905                 isfirst = true;
906                 busystatus = false;
907               }
908 #ifdef PROFILE
909             }
910 #endif
911           } else {
912             isfirst = true;
913             busystatus = false;
914           }
915         }
916       }
917     }
918   }
919 }
920  
921 #endif // MULTICORE