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