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