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