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