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