4d8e5f0e59d9037d4a991d69ed26784e2c51deb0
[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, int index, struct ArrayObject * ao) {
508 #ifndef TASK
509   printf("Array out of bounds at line %u with index %u of object %x with lengt\
510 h %u\n", num, index, ao, ao->___length___);
511 #ifdef THREADS
512   threadexit();
513 #elif defined MGC
514   BAMBOO_EXIT();
515 #else
516   exit(-1);
517 #endif
518 #else
519 #ifndef MULTICORE
520   printf("Array out of bounds\n");
521   longjmp(error_handler,2);
522 #else
523   BAMBOO_EXIT();
524 #endif
525 #endif
526 }
527
528 /* Generated code calls this if we fail null ptr chk */
529 void failednullptr(void * ptr) {
530 #ifdef MULTICORE_GC
531 #ifndef RAW
532   //print out current stack
533   int i,j;
534   j = 0;
535   struct garbagelist * stackptr = (struct garbagelist *)ptr;
536   while(stackptr!=NULL) {
537     tprintf("Stack %d: \n\t", j);
538     for(i=0; i<stackptr->size; i++) {
539       if(stackptr->array[i] != NULL) {
540         tprintf("%x, ", stackptr->array[i]);
541       } else {
542         tprintf("NULL, ");
543       }
544     }
545     tprintf("\n");
546     stackptr=stackptr->next;
547   }
548 #endif
549 #endif
550 #ifndef TASK
551   printf("NULL ptr\n");
552 #ifdef THREADS
553   threadexit();
554 #elif defined MGC
555   BAMBOO_EXIT();
556 #else
557   exit(-1);
558 #endif
559 #else
560 #ifndef MULTICORE
561   printf("NULL ptr\n");
562   longjmp(error_handler,2);
563 #else
564   BAMBOO_EXIT();
565 #endif
566 #endif
567 }
568
569 /* Abort task call */
570 void abort_task() {
571 #ifdef TASK
572 #ifndef MULTICORE
573   printf("Aborting\n");
574   longjmp(error_handler,4);
575 #endif
576 #else
577   printf("Aborting\n");
578   exit(-1);
579 #endif
580 }
581
582 INLINE void initruntimedata() {
583   // initialize the arrays
584   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
585     // startup core to initialize corestatus[]
586     for(int i = 0; i < NUMCORESACTIVE; ++i) {
587       corestatus[i] = 1;
588       numsendobjs[i] = 0;
589       numreceiveobjs[i] = 0;
590     } 
591     numconfirm = 0;
592     waitconfirm = false;
593   }
594
595   busystatus = true;
596   self_numsendobjs = 0;
597   self_numreceiveobjs = 0;
598
599   for(int i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
600     msgdata[i] = -1;
601   }
602   msgdataindex = 0;
603   msgdatalast = 0;
604   //msglength = BAMBOO_MSG_BUF_LENGTH;
605   msgdatafull = false;
606   for(int i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
607     outmsgdata[i] = -1;
608   }
609   outmsgindex = 0;
610   outmsglast = 0;
611   outmsgleft = 0;
612   isMsgHanging = false;
613   
614
615
616
617   smemflag = true;
618   bamboo_cur_msp = NULL;
619   bamboo_smem_size = 0;
620 #ifndef INTERRUPT
621   reside = false;
622 #endif
623
624   INITMULTICOREGCDATA();
625
626 #ifdef MGC
627   initializethreads();
628   bamboo_current_thread = NULL;
629 #endif // MGC
630
631   INITTASKDATA();
632 }
633
634 INLINE void disruntimedata() {
635   DISMULTICOREGCDATA();
636   DISTASKDATA();
637   BAMBOO_LOCAL_MEM_CLOSE();
638   BAMBOO_SHARE_MEM_CLOSE();
639 }
640
641 INLINE void recordtotalexetime() {
642 #ifdef USEIO
643   totalexetime = BAMBOO_GET_EXE_TIME()-bamboo_start_time;
644 #else // USEIO
645   BAMBOO_PRINT(BAMBOO_GET_EXE_TIME()-bamboo_start_time);
646 #ifndef BAMBOO_MEMPROF
647   BAMBOO_PRINT(0xbbbbbbbb);
648 #endif
649 #endif // USEIO
650 }
651
652 INLINE void getprofiledata_I() {
653   //profile mode, send msgs to other cores to request pouring out progiling data
654 #ifdef PROFILE
655   // use numconfirm to check if all cores have finished output task profiling 
656   // information. This is safe as when the execution reaches this phase there 
657   // should have no other msgs except the PROFILEFINISH msg, there should be 
658   // no gc too.
659   numconfirm=NUMCORESACTIVE-1;
660   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
661   for(i = 1; i < NUMCORESACTIVE; ++i) {
662     // send profile request msg to core i
663     send_msg_2(i, PROFILEOUTPUT, totalexetime);
664   } 
665 #ifndef RT_TEST
666   // pour profiling data on startup core
667   outputProfileData();
668 #endif
669   while(true) {
670     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
671     if(numconfirm != 0) {
672       int halt = 100;
673       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
674       while(halt--) {
675       }
676     } else {
677       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
678       break;
679     }  
680   } 
681 #endif
682 }
683
684 INLINE void checkCoreStatus() {
685   int i = 0;
686   int sumsendobj = 0;
687   if((!waitconfirm) ||
688      (waitconfirm && (numconfirm == 0))) {
689     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
690     corestatus[BAMBOO_NUM_OF_CORE] = 0;
691     numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
692     numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
693     // check the status of all cores
694     for(i = 0; i < NUMCORESACTIVE; ++i) {
695       if(corestatus[i] != 0) {
696         break;
697       }
698     } 
699     if(i == NUMCORESACTIVE) {
700       // check if the sum of send objs and receive obj are the same
701       // yes->check if the info is the latest; no->go on executing
702       sumsendobj = 0;
703       for(i = 0; i < NUMCORESACTIVE; ++i) {
704         sumsendobj += numsendobjs[i];
705       } 
706       for(i = 0; i < NUMCORESACTIVE; ++i) {
707         sumsendobj -= numreceiveobjs[i];
708       }  
709       if(0 == sumsendobj) {
710         if(!waitconfirm) {
711           // the first time found all cores stall
712           // send out status confirm msg to all other cores
713           // reset the corestatus array too
714           corestatus[BAMBOO_NUM_OF_CORE] = 1;
715           waitconfirm = true;
716           numconfirm = NUMCORESACTIVE - 1;
717           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
718           for(i = 1; i < NUMCORESACTIVE; ++i) {
719             corestatus[i] = 1;
720             // send status confirm msg to core i
721             send_msg_1(i, STATUSCONFIRM);
722           }   
723           return;
724         } else {
725           // all the core status info are the latest
726           // terminate; for profiling mode, send request to all
727           // other cores to pour out profiling data
728           recordtotalexetime();
729           getprofiledata_I();
730           CACHEADAPT_DISABLE_TIMER();
731           GC_OUTPUT_PROFILE_DATA();
732           disruntimedata();
733           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
734           terminate();  // All done.
735         }
736       } else {          
737         // still some objects on the fly on the network
738         // reset the waitconfirm and numconfirm
739         waitconfirm = false;
740         numconfirm = 0;
741       }  
742     } else {
743       // not all cores are stall, keep on waiting
744       waitconfirm = false;
745       numconfirm = 0;
746     }  
747     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
748   } 
749 }
750
751 // main function for each core
752 inline void run(int argc, char** argv) {
753   bool sendStall = false;
754   bool isfirst = true;
755   bool tocontinue = false;
756
757   corenum = BAMBOO_GET_NUM_OF_CORE();
758
759   // initialize runtime data structures
760   initruntimedata();
761   initCommunication();
762
763   CACHEADAPT_ENABLE_TIMER();
764
765   initializeexithandler();
766
767   // main process of the execution module
768   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
769 #ifdef TASK
770     // non-executing cores, only processing communications
771     activetasks = NULL;
772 #endif
773     fakeExecution();
774   } else {
775 #ifdef TASK
776     /* Create queue of active tasks */
777     activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
778                                       (int (*)(void *,void *)) &comparetpd);
779     
780     /* Process task information */
781     processtasks();
782     
783     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
784       /* Create startup object */
785       createstartupobject(argc, argv);
786     }
787 #endif
788     
789     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
790 #ifdef TASK
791       // run the initStaticAndGlobal method to initialize the static blocks and
792       // global fields
793       initStaticAndGlobal();
794 #elif defined MGC
795       // run the main method in the specified mainclass
796       mgc_main(argc, argv);
797 #endif // TASK
798     }
799     
800     while(true) {
801       GCCHECK(NULL);
802 #ifdef TASK
803       // check if there are new active tasks can be executed
804       executetasks();
805       if(busystatus) {
806         sendStall = false;
807       }
808 #ifndef INTERRUPT
809       while(receiveObject_I() != -1) {
810       }
811 #endif
812       // check if there are some pending objects,
813       // if yes, enqueue them and executetasks again
814       tocontinue = checkObjQueue();
815 #elif defined MGC
816       tocontinue = trystartthread();
817       if(tocontinue) {
818         sendStall = false;
819       }
820 #endif
821       
822       if(!tocontinue) {
823         // check if stop
824         if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
825           if(isfirst) {
826             isfirst = false;
827           }
828           checkCoreStatus();
829         } else {
830           if(!sendStall) {
831 #ifdef PROFILE
832             if(!stall) {
833 #endif
834               if(isfirst) {
835                 // wait for some time
836                 int halt = 10000;
837                 while(halt--) {
838                 }
839                 isfirst = false;
840               } else {
841                 // send StallMsg to startup core
842                 // send stall msg
843                 send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
844                 sendStall = true;
845                 isfirst = true;
846                 busystatus = false;
847               }
848 #ifdef PROFILE
849             }
850 #endif
851           } else {
852             isfirst = true;
853             busystatus = false;
854           }
855         }
856       }
857     }
858   }
859 }
860  
861 #endif // MULTICORE