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