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