Some code clean and make the cache adapt version compile
[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 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 #ifndef BAMBOO_MEMPROF
634   BAMBOO_PRINT(0xbbbbbbbb);
635 #endif
636 #endif // USEIO
637 }
638
639 INLINE void getprofiledata_I() {
640   //profile mode, send msgs to other cores to request pouring out progiling data
641 #ifdef PROFILE
642   // use numconfirm to check if all cores have finished output task profiling 
643   // information. This is safe as when the execution reaches this phase there 
644   // should have no other msgs except the PROFILEFINISH msg, there should be 
645   // no gc too.
646   numconfirm=NUMCORESACTIVE-1;
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);
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     if(numconfirm != 0) {
659       int halt = 100;
660       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
661       while(halt--) {
662       }
663     } else {
664       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
665       break;
666     }  
667   } 
668 #endif
669 }
670
671 INLINE void checkCoreStatus() {
672   int i = 0;
673   int sumsendobj = 0;
674   if((!waitconfirm) ||
675      (waitconfirm && (numconfirm == 0))) {
676     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
677     corestatus[BAMBOO_NUM_OF_CORE] = 0;
678     numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
679     numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
680     // check the status of all cores
681     for(i = 0; i < NUMCORESACTIVE; ++i) {
682       if(corestatus[i] != 0) {
683         break;
684       }
685     } 
686     if(i == NUMCORESACTIVE) {
687       // check if the sum of send objs and receive obj are the same
688       // yes->check if the info is the latest; no->go on executing
689       sumsendobj = 0;
690       for(i = 0; i < NUMCORESACTIVE; ++i) {
691         sumsendobj += numsendobjs[i];
692       } 
693       for(i = 0; i < NUMCORESACTIVE; ++i) {
694         sumsendobj -= numreceiveobjs[i];
695       }  
696       if(0 == sumsendobj) {
697         if(!waitconfirm) {
698           // the first time found all cores stall
699           // send out status confirm msg to all other cores
700           // reset the corestatus array too
701           corestatus[BAMBOO_NUM_OF_CORE] = 1;
702           waitconfirm = true;
703           numconfirm = NUMCORESACTIVE - 1;
704           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
705           for(i = 1; i < NUMCORESACTIVE; ++i) {
706             corestatus[i] = 1;
707             // send status confirm msg to core i
708             send_msg_1(i, STATUSCONFIRM);
709           }   
710           return;
711         } else {
712           // all the core status info are the latest
713           // terminate; for profiling mode, send request to all
714           // other cores to pour out profiling data
715           recordtotalexetime();
716           getprofiledata_I();
717           CACHEADAPT_DISABLE_TIMER();
718           GC_OUTPUT_PROFILE_DATA();
719           disruntimedata();
720           BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
721           terminate();  // All done.
722         }
723       } else {          
724         // still some objects on the fly on the network
725         // reset the waitconfirm and numconfirm
726         waitconfirm = false;
727         numconfirm = 0;
728       }  
729     } else {
730       // not all cores are stall, keep on waiting
731       waitconfirm = false;
732       numconfirm = 0;
733     }  
734     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
735   } 
736 }
737
738 // main function for each core
739 inline void run(int argc, char** argv) {
740   int i = 0;
741   bool sendStall = false;
742   bool isfirst = true;
743   bool tocontinue = false;
744
745   corenum = BAMBOO_GET_NUM_OF_CORE();
746
747   // initialize runtime data structures
748   initruntimedata();
749
750   // other architecture related initialization
751   initialization();
752   initCommunication();
753
754   CACHEADAPT_ENABLE_TIMER();
755
756   initializeexithandler();
757
758   // main process of the execution module
759   if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
760 #ifdef TASK
761     // non-executing cores, only processing communications
762     activetasks = NULL;
763 #endif
764     fakeExecution();
765   } else {
766 #ifdef TASK
767     /* Create queue of active tasks */
768     activetasks= genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
769         (int (*)(void *,void *)) &comparetpd);
770
771     /* Process task information */
772     processtasks();
773
774     if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
775       /* Create startup object */
776       createstartupobject(argc, argv);
777     }
778 #endif
779
780         if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
781 #ifdef TASK
782           // run the initStaticAndGlobal method to initialize the static blocks and
783           // global fields
784           initStaticAndGlobal();
785 #elif defined MGC
786           // run the main method in the specified mainclass
787           mgc_main(argc, argv);
788 #endif // TASK
789         }
790
791     while(true) {
792       GCCHECK(NULL);
793 #ifdef TASK
794       // check if there are new active tasks can be executed
795       executetasks();
796       if(busystatus) {
797         sendStall = false;
798       }
799 #ifndef INTERRUPT
800       while(receiveObject_I() != -1) {
801       }
802 #endif
803       // check if there are some pending objects,
804       // if yes, enqueue them and executetasks again
805       tocontinue = checkObjQueue();
806 #elif defined MGC
807       tocontinue = trystartthread();
808       if(tocontinue) {
809         sendStall = false;
810       }
811 #endif
812
813       if(!tocontinue) {
814         // check if stop
815         if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
816           if(isfirst) {
817             isfirst = false;
818           }
819           checkCoreStatus();
820         } else {
821           if(!sendStall) {
822 #ifdef PROFILE
823             if(!stall) {
824 #endif
825             if(isfirst) {
826               // wait for some time
827               int halt = 10000;
828               while(halt--) {
829               }
830               isfirst = false;
831             } else {
832               // send StallMsg to startup core
833               // send stall msg
834               send_msg_4(STARTUPCORE,TRANSTALL,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
835               sendStall = true;
836               isfirst = true;
837               busystatus = false;
838             }
839 #ifdef PROFILE
840             }
841 #endif
842           } else {
843             isfirst = true;
844             busystatus = false;
845           }
846         }
847       }
848     }
849   }
850
851
852 #endif // MULTICORE