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