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