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