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