changes for reading input files
[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 CALL00(___System______milliGcTime____) {
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 #ifdef D___Scanner______next____ 
433 struct ArrayObject * CALL01(___Scanner______next____, struct ___Scanner___ * ___this___) {
434   int pos = VAR(___this___)->___currentpos___;
435 #if defined(MULTICORE_GC)||defined(PMC_GC)
436   struct ArrayObject * result= allocate_newarray(NULL, CHARARRAYTYPE, 10);
437 #else
438   struct ArrayObject * result=allocate_newarray(CHARARRAYTYPE, 10);
439 #endif
440   int i = 0;
441   while(true) { //(VAR(___this___)->___sourcename___[pos]==' ')||(VAR(___this___)->___sourcename___[pos]=='\n')){
442           pos++;
443   }
444   do {
445           ((short *)(((char *)&result->___length___)+sizeof(int)))[i++]='\0';//(short)VAR(___this___)->___sourcename___[pos++]; // TODO
446   }while(true);//(VAR(___this___)->___sourcename___[pos]!=' ')&&(VAR(___this___)->___sourcename___[pos]!='\n'));
447   VAR(___this___)->___currentpos___ = pos;
448   return result;
449 }
450 #endif
451
452 /* Object allocation function */
453
454 #if defined(MULTICORE_GC)||defined(PMC_GC)
455 void * allocate_new(void * ptr, 
456                     int type) {
457   struct ___Object___ * v=
458     (struct ___Object___*)FREEMALLOC((struct garbagelist*) ptr,classsize[type]);
459   v->type=type;
460 #ifdef TASK
461   v->version = 0;
462   v->lock = NULL;
463   v->lockcount = 0;
464 #endif
465   initlock(v);
466   return v;
467 }
468
469 /* Array allocation function */
470
471 struct ArrayObject * allocate_newarray(void * ptr, 
472                                        int type, 
473                                        int length) {
474   struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC(
475       (struct garbagelist*)ptr,
476       sizeof(struct ArrayObject)+length*classsize[type]);
477   v->type=type;
478 #ifdef TASK
479   v->version = 0;
480   v->lock = NULL;
481 #endif
482   if (length<0) {
483     return NULL;
484   }
485   v->___length___=length;
486   initlock((struct ___Object___ *)v);
487   return v;
488 }
489
490 #else
491 void * allocate_new(int type) {
492   struct ___Object___ * v=FREEMALLOC(classsize[type]);
493   v->type=type;
494 #ifdef TASK
495   v->version = 0;
496   v->lock = NULL;
497 #endif
498   initlock(v);
499   return v;
500 }
501
502 /* Array allocation function */
503
504 struct ArrayObject * allocate_newarray(int type, 
505                                        int length) {
506   struct ArrayObject * v=FREEMALLOC(
507       sizeof(struct ArrayObject)+length*classsize[type]);
508   v->type=type;
509 #ifdef TASK
510   v->version = 0;
511   v->lock = NULL;
512 #endif
513   v->___length___=length;
514   initlock((struct ___Object___ *) v);
515   return v;
516 }
517 #endif
518
519 /* Converts C character arrays into Java strings */
520 #if defined(MULTICORE_GC)||defined(PMC_GC)
521 __attribute__((malloc)) struct ___String___ * NewStringShort(void * ptr, 
522                                                              const short *str,
523                                                              int length) {
524 #else
525 __attribute__((malloc)) struct ___String___ * NewStringShort(const short *str,
526                                                              int length) {
527 #endif
528   int i;
529 #if defined(MULTICORE_GC)||defined(PMC_GC)
530   struct ArrayObject * chararray=
531     allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
532   INTPTR ptrarray[]={1, (INTPTR) ptr, (INTPTR) chararray};
533   struct ___String___ * strobj=
534     allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
535   chararray=(struct ArrayObject *) ptrarray[2];
536 #else
537   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
538   struct ___String___ * strobj=allocate_new(STRINGTYPE);
539 #endif
540   strobj->___value___=chararray;
541   strobj->___count___=length;
542   strobj->___offset___=0;
543
544   for(i=0; i<length; i++) {
545     ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=str[i];
546   }
547   return strobj;
548 }
549
550 /* Converts C character arrays into Java strings */
551 #if defined(MULTICORE_GC)||defined(PMC_GC)
552 struct ___String___ * NewString(void * ptr, 
553                                 const char *str,
554                                 int length) {
555 #else
556 struct ___String___ * NewString(const char *str,
557                                 int length) {
558 #endif
559   int i;
560 #if defined(MULTICORE_GC)||defined(PMC_GC)
561   struct ArrayObject * chararray=
562     allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
563   int ptrarray[]={1, (int) ptr, (int) chararray};
564   struct ___String___ * strobj=
565     allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
566   chararray=(struct ArrayObject *) ptrarray[2];
567 #else
568   struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
569   struct ___String___ * strobj=allocate_new(STRINGTYPE);
570 #endif
571   strobj->___value___=chararray;
572   strobj->___count___=length;
573   strobj->___offset___=0;
574
575   for(i=0; i<length; i++) {
576     ((short*)(((char*)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
577   }
578   return strobj;
579 }
580
581 /* Generated code calls this if we fail a bounds check */
582
583  void failedboundschk(int num, int index, struct ArrayObject * ao) {
584 #ifndef TASK
585   printf("Array out of bounds at line %u with index %u of object %x with lengt\
586 h %u\n", num, index, ao, ao->___length___);
587 #ifdef THREADS
588   threadexit();
589 #elif defined MGC
590   BAMBOO_EXIT();
591 #else
592   exit(-1);
593 #endif
594 #else
595 #ifndef MULTICORE
596   printf("Array out of bounds\n");
597   longjmp(error_handler,2);
598 #else
599   BAMBOO_EXIT();
600 #endif
601 #endif
602 }
603
604 /* Generated code calls this if we fail null ptr chk */
605 void failednullptr(void * ptr) {
606 #if defined(MULTICORE_GC)||defined(PMC_GC)
607 #ifndef RAW
608   //print out current stack
609   int i,j;
610   j = 0;
611   struct garbagelist * stackptr = (struct garbagelist *)ptr;
612   while(stackptr!=NULL) {
613     tprintf("Stack %d: \n\t", j);
614     for(i=0; i<stackptr->size; i++) {
615       if(stackptr->array[i] != NULL) {
616         tprintf("%x, ", stackptr->array[i]);
617       } else {
618         tprintf("NULL, ");
619       }
620     }
621     tprintf("\n");
622     stackptr=stackptr->next;
623   }
624 #endif
625 #endif
626 #ifndef TASK
627   printf("NULL ptr\n");
628 #ifdef THREADS
629   threadexit();
630 #elif defined MGC
631   BAMBOO_EXIT();
632 #else
633   exit(-1);
634 #endif
635 #else
636 #ifndef MULTICORE
637   printf("NULL ptr\n");
638   longjmp(error_handler,2);
639 #else
640   BAMBOO_EXIT();
641 #endif
642 #endif
643 }
644
645 /* Abort task call */
646 void abort_task() {
647 #ifdef TASK
648 #ifndef MULTICORE
649   printf("Aborting\n");
650   longjmp(error_handler,4);
651 #endif
652 #else
653   printf("Aborting\n");
654   exit(-1);
655 #endif
656 }
657
658 void initruntimedata() {
659   // initialize the arrays
660   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
661     // startup core to initialize corestatus[]
662     for(int i = 0; i < NUMCORESACTIVE; ++i) {
663       corestatus[i] = 1;
664       numsendobjs[i] = 0;
665       numreceiveobjs[i] = 0;
666     } 
667     numconfirm = 0;
668     waitconfirm = false;
669   }
670
671   busystatus = true;
672   self_numsendobjs = 0;
673   self_numreceiveobjs = 0;
674
675   for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
676     msgdata[i] = -1;
677   }
678   msgdataindex = 0;
679   msgdatalast = 0;
680   //msglength = BAMBOO_MSG_BUF_LENGTH;
681   msgdatafull = false;
682   for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
683     outmsgdata[i] = -1;
684   }
685   outmsgindex = 0;
686   outmsglast = 0;
687   outmsgleft = 0;
688   isMsgHanging = false;
689   
690   smemflag = true;
691   bamboo_cur_msp = NULL;
692   bamboo_smem_size = 0;
693 #ifndef INTERRUPT
694   reside = false;
695 #endif
696
697   INITMULTICOREGCDATA();
698
699 #ifdef MGC
700   initializethreads();
701   bamboo_current_thread = NULL;
702 #endif // MGC
703
704   INITTASKDATA();
705 }
706
707 void disruntimedata() {
708   DISMULTICOREGCDATA();
709   DISTASKDATA();
710   BAMBOO_LOCAL_MEM_CLOSE();
711   BAMBOO_SHARE_MEM_CLOSE();
712 }
713
714 void recordtotalexetime() {
715 #ifdef USEIO
716   totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
717 #else // USEIO
718   unsigned long long timediff=BAMBOO_GET_EXE_TIME()-bamboo_start_time;
719   BAMBOO_PRINT(timediff);
720 #ifndef BAMBOO_MEMPROF
721   BAMBOO_PRINT(0xbbbbbbbb);
722 #endif
723 #endif // USEIO
724 }
725
726 void getprofiledata_I() {
727   //profile mode, send msgs to other cores to request pouring out progiling data
728 #ifdef PROFILE
729   // use numconfirm to check if all cores have finished output task profiling 
730   // information. This is safe as when the execution reaches this phase there 
731   // should have no other msgs except the PROFILEFINISH msg, there should be 
732   // no gc too.
733   numconfirm=NUMCORESACTIVE-1;
734   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
735   for(i = 1; i < NUMCORESACTIVE; ++i) {
736     // send profile request msg to core i
737     send_msg_2(i, PROFILEOUTPUT, totalexetime);
738   } 
739 #ifndef RT_TEST
740   // pour profiling data on startup core
741   outputProfileData();
742 #endif
743   while(true) {
744     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
745     if(numconfirm != 0) {
746       int halt = 100;
747       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
748       while(halt--) {
749       }
750     } else {
751       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
752       break;
753     }  
754   } 
755 #endif
756 }
757
758 void checkCoreStatus() {
759   int i = 0;
760   int sumsendobj = 0;
761   if((!waitconfirm) ||
762      (waitconfirm && (numconfirm == 0))) {
763     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
764     corestatus[BAMBOO_NUM_OF_CORE] = 0;
765     numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
766     numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
767     // check the status of all cores
768     for(i = 0; i < NUMCORESACTIVE; ++i) {
769       if(corestatus[i] != 0) {
770         break;
771       }
772     } 
773     if(i == NUMCORESACTIVE) {
774       // check if the sum of send objs and receive obj are the same
775       // yes->check if the info is the latest; no->go on executing
776       sumsendobj = 0;
777       for(i = 0; i < NUMCORESACTIVE; ++i) {
778         sumsendobj += numsendobjs[i];
779       } 
780       for(i = 0; i < NUMCORESACTIVE; ++i) {
781         sumsendobj -= numreceiveobjs[i];
782       }  
783       if(0 == sumsendobj) {
784         if(!waitconfirm) {
785           // the first time found all cores stall
786           // send out status confirm msg to all other cores
787           // reset the corestatus array too
788           corestatus[BAMBOO_NUM_OF_CORE] = 1;
789           waitconfirm = true;
790           numconfirm = NUMCORESACTIVE - 1;
791           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
792           for(i = 1; i < NUMCORESACTIVE; ++i) {
793             corestatus[i] = 1;
794             // send status confirm msg to core i
795             send_msg_1(i, STATUSCONFIRM);
796           }   
797           return;
798         } else {
799           // all the core status info are the latest
800           // terminate; for profiling mode, send request to all
801           // other cores to pour out profiling data
802           recordtotalexetime();
803           getprofiledata_I();
804           CACHEADAPT_DISABLE_TIMER();
805           GC_OUTPUT_PROFILE_DATA();
806 #ifdef PERFCOUNT
807           print_statistics();
808 #endif
809           gc_outputProfileDataReadable();
810           disruntimedata();
811           tprintf("FINISH_EXECUTION\n");
812           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
813           terminate();  // All done.
814         }
815       } else {          
816         // still some objects on the fly on the network
817         // reset the waitconfirm and numconfirm
818         waitconfirm = false;
819         numconfirm = 0;
820       }  
821     } else {
822       // not all cores are stall, keep on waiting
823       waitconfirm = false;
824       numconfirm = 0;
825     }  
826     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
827   } 
828 }
829
830 // main function for each core
831 void run(int argc, char** argv) {
832   bool sendStall = false;
833   bool isfirst = true;
834   bool tocontinue = false;
835   startflag = false;
836   corenum = BAMBOO_GET_NUM_OF_CORE();
837   // initialize runtime data structures
838   initruntimedata();
839   initCommunication();
840 #ifdef PMC_GC
841   pmc_onceInit();
842 #endif
843 #ifdef PERFCOUNT
844   if (BAMBOO_NUM_OF_CORE==STARTUPCORE)
845     profile_init(_LOCAL_DRD_CNT,_LOCAL_WR_CNT, _REMOTE_DRD_CNT, _REMOTE_WR_CNT);
846   else {
847     int offcore=4*(BAMBOO_NUM_OF_CORE-1);
848     profile_init(validevents[(offcore)%87], validevents[(offcore+1)%87], validevents[(offcore+2)%87], validevents[(offcore+3)%87]);
849   }
850 #endif
851   if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
852     numconfirm=NUMCORES-1;
853     for(int i=0;i<NUMCORES;i++) {
854       if (i!=STARTUPCORE) {
855         send_msg_1(i,REQNOTIFYSTART);
856       }
857     }
858     while(numconfirm!=0)
859       ;
860     tprintf("START_EXECUTION\n");
861     bamboo_start_time = BAMBOO_GET_EXE_TIME();
862   } else {
863     while(!startflag)
864       ;
865   }
866 #ifdef PERFCOUNT
867   bme_performance_counter_start();
868 #endif
869
870   CACHEADAPT_ENABLE_TIMER();
871
872   initializeexithandler();
873
874   // main process of the execution module
875   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
876 #ifdef TASK
877     // non-executing cores, only processing communications
878     activetasks = NULL;
879 #endif
880     fakeExecution();
881   } else {
882 #ifdef TASK
883     /* Create queue of active tasks */
884     activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
885                                       (int (*)(void *,void *)) &comparetpd);
886     
887     /* Process task information */
888     processtasks();
889     
890     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
891       /* Create startup object */
892       createstartupobject(argc, argv);
893     }
894 #endif
895     
896 #ifdef PERFCOUNT
897       profile_start(APP_REGION);
898 #endif
899     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
900 #ifdef TASK
901       // run the initStaticAndGlobal method to initialize the static blocks and
902       // global fields
903       initStaticAndGlobal();
904 #elif defined MGC
905       // run the main method in the specified mainclass
906       mgc_main(argc, argv);
907 #endif // TASK
908     }
909     
910     while(true) {
911       GCCHECK(NULL);
912 #ifdef TASK
913       // check if there are new active tasks can be executed
914       executetasks();
915       if(busystatus) {
916         sendStall = false;
917       }
918 #ifndef INTERRUPT
919       while(receiveObject_I() != -1) {
920       }
921 #endif
922       // check if there are some pending objects,
923       // if yes, enqueue them and executetasks again
924       tocontinue = checkObjQueue();
925 #elif defined MGC
926       tocontinue = trystartthread();
927       if(tocontinue) {
928         sendStall = false;
929       }
930 #endif
931       
932       if(!tocontinue) {
933         // check if stop
934         if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
935           if(isfirst) {
936             isfirst = false;
937           }
938           checkCoreStatus();
939         } else {
940           if(!sendStall) {
941 #ifdef PROFILE
942             if(!stall) {
943 #endif
944               if(isfirst) {
945                 // wait for some time
946                 int halt = 10000;
947                 while(halt--) {
948                 }
949                 isfirst = false;
950               } else {
951                 // send StallMsg to startup core
952                 // send stall msg
953                 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
954                 sendStall = true;
955                 isfirst = true;
956                 busystatus = false;
957               }
958 #ifdef PROFILE
959             }
960 #endif
961           } else {
962             isfirst = true;
963             busystatus = false;
964           }
965         }
966       }
967     }
968   }
969 }
970  
971 #endif // MULTICORE