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