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