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