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