9dfc6a010697a3fa77b4fc4c062dfbd200e4cf18
[IRC.git] / Robust / src / Runtime / bamboo / multicoregarbage.c
1 // TODO: DO NOT support tag!!!
2 #ifdef MULTICORE_GC
3 #include "runtime.h"
4 #include "multicoreruntime.h"
5 #include "multicoregarbage.h"
6 #include "multicoregcmark.h"
7 #include "gcqueue.h"
8 #include "multicoregccompact.h"
9 #include "multicoregcflush.h"
10 #include "multicoregcprofile.h"
11 #include "gcqueue.h"
12
13 #ifdef SMEMM
14 extern unsigned int gcmem_mixed_threshold;
15 extern unsigned int gcmem_mixed_usedmem;
16 #endif // SMEMM
17
18 volatile bool gcflag;
19 gc_status_t gc_status_info;
20
21 unsigned long long gc_output_cache_policy_time=0;
22
23 #ifdef GC_DEBUG
24 // dump whole mem in blocks
25 void dumpSMem() {
26   int block = 0;
27   int sblock = 0;
28   unsigned int j = 0;
29   void * i = 0;
30   int coren = 0;
31   int x = 0;
32   int y = 0;
33   printf("(%x,%x) Dump shared mem: \n",udn_tile_coord_x(),udn_tile_coord_y());
34   // reserved blocks for sblocktbl
35   printf("(%x,%x) ++++ reserved sblocks ++++ \n", udn_tile_coord_x(),
36          udn_tile_coord_y());
37   for(i=BAMBOO_BASE_VA; (unsinged int)i<(unsigned int)gcbaseva; i+= 4*16) {
38     printf("(%x,%x) 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
39         udn_tile_coord_x(), udn_tile_coord_y(),
40         *((int *)(i)), *((int *)(i + 4)),
41         *((int *)(i + 4*2)), *((int *)(i + 4*3)),
42         *((int *)(i + 4*4)), *((int *)(i + 4*5)),
43         *((int *)(i + 4*6)), *((int *)(i + 4*7)),
44         *((int *)(i + 4*8)), *((int *)(i + 4*9)),
45         *((int *)(i + 4*10)), *((int *)(i + 4*11)),
46         *((int *)(i + 4*12)), *((int *)(i + 4*13)),
47         *((int *)(i + 4*14)), *((int *)(i + 4*15)));
48   }
49   sblock = 0;
50   bool advanceblock = false;
51   // remaining memory
52   for(i=gcbaseva; (unsigned int)i<(unsigned int)(gcbaseva+BAMBOO_SHARED_MEM_SIZE); i+=4*16) {
53     advanceblock = false;
54     // computing sblock # and block #, core coordinate (x,y) also
55     if(j%((BAMBOO_SMEM_SIZE)/(4*16)) == 0) {
56       // finished a sblock
57       if(j < ((BAMBOO_LARGE_SMEM_BOUND)/(4*16))) {
58         if((j > 0) && (j%((BAMBOO_SMEM_SIZE_L)/(4*16)) == 0)) {
59           // finished a block
60           block++;
61           advanceblock = true;  
62         }
63       } else {
64         // finished a block
65         block++;
66         advanceblock = true;
67       }
68       // compute core #
69       if(advanceblock) {
70         coren = gc_block2core[block%(NUMCORES4GC*2)];
71       }
72       // compute core coordinate
73       x = BAMBOO_COORDS_X(coren);
74       y = BAMBOO_COORDS_Y(coren);
75       printf("(%x,%x) ==== %d, %d : core (%d,%d), saddr %x====\n",
76           udn_tile_coord_x(), udn_tile_coord_y(),block, sblock++, x, y,
77           (sblock-1)*(BAMBOO_SMEM_SIZE)+gcbaseva);
78     }
79     j++;
80     printf("(%x,%x) 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
81         udn_tile_coord_x(), udn_tile_coord_y(),
82         *((int *)(i)), *((int *)(i + 4)),
83         *((int *)(i + 4*2)), *((int *)(i + 4*3)),
84         *((int *)(i + 4*4)), *((int *)(i + 4*5)),
85         *((int *)(i + 4*6)), *((int *)(i + 4*7)),
86         *((int *)(i + 4*8)), *((int *)(i + 4*9)),
87         *((int *)(i + 4*10)), *((int *)(i + 4*11)),
88         *((int *)(i + 4*12)), *((int *)(i + 4*13)),
89         *((int *)(i + 4*14)), *((int *)(i + 4*15)));
90   }
91   printf("(%x,%x) \n", udn_tile_coord_x(), udn_tile_coord_y());
92 }
93 #endif
94
95 void initmulticoregcdata() {
96   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
97     // startup core to initialize corestatus[]
98     for(int i = 0; i < NUMCORESACTIVE; i++) {
99       gccorestatus[i] = 1;
100       gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
101       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
102     } 
103     for(int i = 0; i < NUMCORES4GC; i++) {
104       gcloads[i] = 0;
105       gcrequiredmems[i] = 0;
106       gcstopblock[i] = 0;
107       gcfilledblocks[i] = 0;
108     }
109   }
110
111   bamboo_smem_zero_top = NULL;
112   gcflag = false;
113   gc_status_info.gcprocessing = false;
114   gc_status_info.gcphase = FINISHPHASE;
115
116   gcprecheck = true;
117   gccurr_heaptop = 0;
118   gcself_numsendobjs = 0;
119   gcself_numreceiveobjs = 0;
120   gcmarkedptrbound = 0;
121   gcforwardobjtbl = allocateMGCHash_I(128);
122   gcheaptop = 0;
123   gctopcore = 0;
124   gctopblock = 0;
125   gcmovestartaddr = 0;
126   gctomove = false;
127   gcmovepending = 0;
128   gcblock2fill = 0;
129 #ifdef SMEMM
130   gcmem_mixed_threshold=(unsigned int)((BAMBOO_SHARED_MEM_SIZE-bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
131   gcmem_mixed_usedmem = 0;
132 #endif
133 #ifdef MGC_SPEC
134   gc_profile_flag = false;
135 #endif
136   gc_localheap_s = false;
137 #ifdef GC_CACHE_ADAPT
138   gccachestage = false;
139 #endif 
140
141   INIT_MULTICORE_GCPROFILE_DATA();
142 }
143
144 void dismulticoregcdata() {
145   freeMGCHash(gcforwardobjtbl);
146 }
147
148 void initGC() {
149   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
150     for(int i = 0; i < NUMCORES4GC; i++) {
151       gccorestatus[i] = 1;
152       gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
153       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
154       gcloads[i] = 0;
155       gcrequiredmems[i] = 0;
156       gcfilledblocks[i] = 0;
157       gcstopblock[i] = 0;
158     } 
159     for(int i = NUMCORES4GC; i < NUMCORESACTIVE; i++) {
160       gccorestatus[i] = 1;
161       gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
162       gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
163     }
164     gcheaptop = 0;
165     gctopcore = 0;
166     gctopblock = 0;
167     gcnumsrobjs_index = 0;
168   } 
169   gcself_numsendobjs = 0;
170   gcself_numreceiveobjs = 0;
171   gcmarkedptrbound = 0;
172   gcmovestartaddr = 0;
173   gctomove = false;
174   gcblock2fill = 0;
175   gcmovepending = 0;
176   gccurr_heaptop = 0;
177
178   gc_queueinit();
179
180   MGCHashreset(gcforwardobjtbl);
181
182   GCPROFILE_INIT();
183   gc_output_cache_policy_time=0;
184
185
186 bool gc_checkAllCoreStatus() {
187   BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
188   for(int i = 0; i < NUMCORESACTIVE; i++) {
189     if(gccorestatus[i] != 0) {
190       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
191       return false;
192     }  
193   }  
194   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
195   return true;
196 }
197
198 // NOTE: should be invoked with interrupts turned off
199 bool gc_checkAllCoreStatus_I() {
200   for(int i = 0; i < NUMCORESACTIVE; i++) {
201     if(gccorestatus[i] != 0) {
202       return false;
203     }  
204   }  
205   return true;
206 }
207
208 void checkMarkStatus_p2() {
209   // check if the sum of send objs and receive obj are the same
210   // yes->check if the info is the latest; no->go on executing
211   unsigned int sumsendobj = 0;
212   for(int i = 0; i < NUMCORESACTIVE; i++) {
213     sumsendobj += gcnumsendobjs[gcnumsrobjs_index][i];
214   } 
215   for(int i = 0; i < NUMCORESACTIVE; i++) {
216     sumsendobj -= gcnumreceiveobjs[gcnumsrobjs_index][i];
217   } 
218   if(0 == sumsendobj) {
219     // Check if there are changes of the numsendobjs or numreceiveobjs 
220     // on each core
221     int i = 0;
222     for(i = 0; i < NUMCORESACTIVE; i++) {
223       if((gcnumsendobjs[0][i]!=gcnumsendobjs[1][i])||(gcnumreceiveobjs[0][i]!=gcnumreceiveobjs[1][i]) ) {
224         break;
225       }
226     }  
227     if(i == NUMCORESACTIVE) {    
228       // all the core status info are the latest,stop mark phase
229       gc_status_info.gcphase = COMPACTPHASE;
230       // restore the gcstatus for all cores
231       for(int i = 0; i < NUMCORESACTIVE; i++) {
232         gccorestatus[i] = 1;
233       }  
234     } else {
235       // There were changes between phase 1 and phase 2, can not decide 
236       // whether the mark phase has been finished
237       waitconfirm = false;
238       // As it fails in phase 2, flip the entries
239       gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
240     } 
241   } else {
242     // There were changes between phase 1 and phase 2, can not decide 
243     // whether the mark phase has been finished
244     waitconfirm = false;
245     // As it fails in phase 2, flip the entries
246     gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
247   }
248 }
249
250 void checkMarkStatus() {
251   if((!waitconfirm)||(waitconfirm && (numconfirm == 0))) {
252     unsigned int entry_index = 0;
253     if(waitconfirm) {
254       // phase 2
255       entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
256     } else {
257       // phase 1
258       entry_index = gcnumsrobjs_index;
259     }
260     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
261     gccorestatus[BAMBOO_NUM_OF_CORE] = 0;  
262     gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
263     gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
264     // check the status of all cores
265     if (gc_checkAllCoreStatus_I()) {
266       // ask for confirm
267       if(!waitconfirm) {
268         // the first time found all cores stall
269         // send out status confirm msg to all other cores
270         // reset the corestatus array too    
271         waitconfirm = true;
272         numconfirm = NUMCORESACTIVE - 1;
273         BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
274         GC_SEND_MSG_1_TO_CLIENT(GCMARKCONFIRM);
275       } else {
276         // Phase 2
277         checkMarkStatus_p2(); 
278         BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
279       }
280     } else {
281       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
282     } 
283   } 
284
285
286 // compute load balance for all cores
287 int loadbalance(void ** heaptop, unsigned int * topblock, unsigned int * topcore) {
288   // compute load balance
289   // get the total loads
290   unsigned int tloads = 0;
291   for(int i = 0; i < NUMCORES4GC; i++) {
292     tloads += gcloads[i];
293   }
294   *heaptop = gcbaseva + tloads;
295
296   unsigned int topblockindex;
297   
298   BLOCKINDEX(topblockindex, *heaptop);
299   // num of blocks per core
300   unsigned int numbpc = (topblockindex+NUMCORES4GC-1)/NUMCORES4GC;
301   
302   *topblock = topblockindex;
303   RESIDECORE(*heaptop, *topcore);
304   return numbpc;
305 }
306
307
308 // update the bmmboo_smemtbl to record current shared mem usage
309 void updateSmemTbl(unsigned int coren, void * localtop) {
310   unsigned int ltopcore = 0;
311   unsigned int bound = BAMBOO_SMEM_SIZE_L;
312   BLOCKINDEX(ltopcore, localtop);
313   if((unsigned int)localtop>=(unsigned int)(gcbaseva+BAMBOO_LARGE_SMEM_BOUND)){
314     bound = BAMBOO_SMEM_SIZE;
315   }
316   unsigned int load = (unsigned INTPTR)(localtop-gcbaseva)%(unsigned int)bound;
317   unsigned int toset = 0;
318   for(int j=0; 1; j++) {
319     for(int i=0; i<2; i++) {
320       toset = gc_core2block[2*coren+i]+(unsigned int)(NUMCORES4GC*2)*j;
321       if(toset < ltopcore) {
322         bamboo_smemtbl[toset]=BLOCKSIZE(toset<NUMCORES4GC);
323 #ifdef SMEMM
324         gcmem_mixed_usedmem += bamboo_smemtbl[toset];
325 #endif
326       } else if(toset == ltopcore) {
327         bamboo_smemtbl[toset] = load;
328 #ifdef SMEMM
329         gcmem_mixed_usedmem += bamboo_smemtbl[toset];
330 #endif
331         return;
332       } else {
333         return;
334       }
335     }
336   }
337 }
338
339 void gc_collect(struct garbagelist * stackptr) {
340   gc_status_info.gcprocessing = true;
341   // inform the master that this core is at a gc safe point and is ready to 
342   // do gc
343   send_msg_4(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
344
345   // core collector routine
346   //wait for init phase
347   WAITFORGCPHASE(INITPHASE);
348
349   GC_PRINTF("Do initGC\n");
350   initGC();
351   CACHEADAPT_GC(true);
352   //send init finish msg to core coordinator
353   send_msg_2(STARTUPCORE,GCFINISHINIT,BAMBOO_NUM_OF_CORE);
354
355   //wait for mark phase
356   WAITFORGCPHASE(MARKPHASE);
357
358   GC_PRINTF("Start mark phase\n");
359   mark(true, stackptr);
360   GC_PRINTF("Finish mark phase, start compact phase\n");
361   compact();
362   GC_PRINTF("Finish compact phase\n");
363
364   WAITFORGCPHASE(UPDATEPHASE);
365
366   GC_PRINTF("Start flush phase\n");
367   GCPROFILE_INFO_2_MASTER();
368   update(stackptr);
369   GC_PRINTF("Finish flush phase\n");
370
371   CACHEADAPT_PHASE_CLIENT();
372
373   // invalidate all shared mem pointers
374   bamboo_cur_msp = NULL;
375   bamboo_smem_size = 0;
376   bamboo_smem_zero_top = NULL;
377   gcflag = false;
378
379   WAITFORGCPHASE(FINISHPHASE);
380
381   GC_PRINTF("Finish gc! \n");
382
383
384 void gc_nocollect(struct garbagelist * stackptr) {
385   gc_status_info.gcprocessing = true;
386   // inform the master that this core is at a gc safe point and is ready to 
387   // do gc
388   send_msg_4(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
389   
390   WAITFORGCPHASE(INITPHASE);
391
392   GC_PRINTF("Do initGC\n");
393   initGC();
394   CACHEADAPT_GC(true);
395   //send init finish msg to core coordinator
396   send_msg_2(STARTUPCORE,GCFINISHINIT,BAMBOO_NUM_OF_CORE);
397
398   WAITFORGCPHASE(MARKPHASE);
399
400   GC_PRINTF("Start mark phase\n"); 
401   mark(true, stackptr);
402   GC_PRINTF("Finish mark phase, wait for flush\n");
403
404   // non-gc core collector routine
405   WAITFORGCPHASE(UPDATEPHASE);
406
407   GC_PRINTF("Start flush phase\n");
408   GCPROFILE_INFO_2_MASTER();
409   update(stackptr);
410   GC_PRINTF("Finish flush phase\n"); 
411
412   CACHEADAPT_PHASE_CLIENT();
413
414   // invalidate all shared mem pointers
415   bamboo_cur_msp = NULL;
416   bamboo_smem_size = 0;
417   bamboo_smem_zero_top = NULL;
418
419   gcflag = false;
420   WAITFORGCPHASE(FINISHPHASE);
421
422   GC_PRINTF("Finish gc! \n");
423 }
424
425 void master_mark(struct garbagelist *stackptr) {
426   bool isfirst = true;
427
428   GC_PRINTF("Start mark phase \n");
429   GC_SEND_MSG_1_TO_CLIENT(GCSTART);
430   gc_status_info.gcphase = MARKPHASE;
431   // mark phase
432
433   while(MARKPHASE == gc_status_info.gcphase) {
434     mark(isfirst, stackptr);
435     isfirst=false;
436     // check gcstatus
437     checkMarkStatus();
438   }
439 }
440
441 void master_getlargeobjs() {
442   // send msgs to all cores requiring large objs info
443   // Note: only need to ask gc cores, non-gc cores do not host any objs
444   numconfirm = NUMCORES4GC - 1;
445   for(int i = 1; i < NUMCORES4GC; i++) {
446     send_msg_1(i,GCLOBJREQUEST);
447   }
448   gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
449   //spin until we have all responses
450   while(numconfirm!=0) ;
451
452   // check the heaptop
453   if(gcheaptop < gcmarkedptrbound) {
454     gcheaptop = gcmarkedptrbound;
455   }
456   GCPROFILE_ITEM();
457   GC_PRINTF("prepare to cache large objs \n");
458
459 }
460
461
462 void master_updaterefs(struct garbagelist * stackptr) {
463   gc_status_info.gcphase = UPDATEPHASE;
464   GC_SEND_MSG_1_TO_CLIENT(GCSTARTUPDATE);
465   GCPROFILE_ITEM();
466   GC_PRINTF("Start flush phase \n");
467   // flush phase
468   update(stackptr);
469   GC_CHECK_ALL_CORE_STATUS(UPDATEPHASE==gc_status_info.gcphase);
470   GC_PRINTF("Finish flush phase \n");
471 }
472
473 void master_finish() {
474   gc_status_info.gcphase = FINISHPHASE;
475   
476   // invalidate all shared mem pointers
477   // put it here as it takes time to inform all the other cores to
478   // finish gc and it might cause problem when some core resumes
479   // mutator earlier than the other cores
480   bamboo_cur_msp = NULL;
481   bamboo_smem_size = 0;
482   bamboo_smem_zero_top = NULL;
483   
484   GCPROFILE_END();
485   unsigned long long tmpt = BAMBOO_GET_EXE_TIME();
486   CACHEADAPT_OUTPUT_CACHE_POLICY();
487   gc_output_cache_policy_time += (BAMBOO_GET_EXE_TIME()-tmpt);
488   gcflag = false;
489   GC_SEND_MSG_1_TO_CLIENT(GCFINISH);
490   
491   gc_status_info.gcprocessing = false;
492   if(gcflag) {
493     // inform other cores to stop and wait for gc
494     gcprecheck = true;
495     for(int i = 0; i < NUMCORESACTIVE; i++) {
496       // reuse the gcnumsendobjs & gcnumreceiveobjs
497       gcnumsendobjs[0][i] = 0;
498       gcnumreceiveobjs[0][i] = 0;
499     }
500     GC_SEND_MSG_1_TO_CLIENT(GCSTARTPRE);
501   }
502 }
503
504 void gc_master(struct garbagelist * stackptr) {
505   tprintf("start GC !!!!!!!!!!!!! \n");
506   gc_status_info.gcprocessing = true;
507   gc_status_info.gcphase = INITPHASE;
508
509   waitconfirm = false;
510   numconfirm = 0;
511   initGC();
512   GC_SEND_MSG_1_TO_CLIENT(GCSTARTINIT);
513   CACHEADAPT_GC(true);
514   GC_PRINTF("Check core status \n");
515   GC_CHECK_ALL_CORE_STATUS(true);
516   GCPROFILE_ITEM();
517   unsigned long long tmpt = BAMBOO_GET_EXE_TIME();
518   CACHEADAPT_OUTPUT_CACHE_SAMPLING();
519   gc_output_cache_policy_time += (BAMBOO_GET_EXE_TIME()-tmpt);
520
521   // do mark phase
522   master_mark(stackptr);
523
524   // get large objects from all cores
525   master_getlargeobjs();
526
527   // compact the heap
528   master_compact();
529   
530   // update the references
531   master_updaterefs(stackptr);
532
533   // do cache adaptation
534   CACHEADAPT_PHASE_MASTER();
535
536   // do finish up stuff
537   master_finish();
538
539   GC_PRINTF("gc finished   \n");
540   tprintf("finish GC ! %d \n",gcflag);
541
542
543 void pregccheck() {
544   while(true) {
545     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
546     gcnumsendobjs[0][BAMBOO_NUM_OF_CORE] = self_numsendobjs;
547     gcnumreceiveobjs[0][BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
548     int sumsendobj = 0;
549     for(int i = 0; i < NUMCORESACTIVE; i++) {
550       sumsendobj += gcnumsendobjs[0][i];
551     }  
552     for(int i = 0; i < NUMCORESACTIVE; i++) {
553       sumsendobj -= gcnumreceiveobjs[0][i];
554     } 
555     if(0 != sumsendobj) {
556       // there were still some msgs on the fly, wait until there 
557       // are some update pregc information coming and check it again
558       gcprecheck = false;
559       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
560
561       while(!gcprecheck) ;
562     } else {
563       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
564       return;
565     }
566   }
567 }
568
569 void pregcprocessing() {
570 #if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
571   // disable the timer interrupt
572   bamboo_mask_timer_intr();
573 #endif
574   // Zero out the remaining memory here because for the GC_CACHE_ADAPT version,
575   // we need to make sure during the gcinit phase the shared heap is not 
576   // touched. Otherwise, there would be problem when adapt the cache strategy.
577   BAMBOO_CLOSE_CUR_MSP();
578 #if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
579   // get the sampling data 
580   bamboo_output_dtlb_sampling();
581 #endif
582 }
583
584 void postgcprocessing() {
585 #if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
586   // enable the timer interrupt
587   bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING); 
588   bamboo_unmask_timer_intr();
589 #endif
590 }
591
592 bool gc(struct garbagelist * stackptr) {
593   // check if do gc
594   if(!gcflag) {
595     gc_status_info.gcprocessing = false;
596     return false;
597   }
598
599   // core coordinator routine
600   if(0 == BAMBOO_NUM_OF_CORE) {
601     GC_PRINTF("Check if we can do gc or not\n");
602     gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
603     if(!gc_checkAllCoreStatus()) {
604       // some of the cores are still executing the mutator and did not reach
605       // some gc safe point, therefore it is not ready to do gc
606       gcflag = true;
607       return false;
608     } else {
609       GCPROFILE_START();
610       pregccheck();
611     }
612     GC_PRINTF("start gc! \n");
613     pregcprocessing();
614     gc_master(stackptr);
615   } else if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
616     pregcprocessing();
617     gc_collect(stackptr);
618   } else {
619     pregcprocessing();
620     gc_nocollect(stackptr);
621   }
622   postgcprocessing();
623
624   return true;
625
626
627 #endif