-// TODO: DO NOT support tag!!!
#ifdef MULTICORE_GC
#include "runtime.h"
#include "multicoreruntime.h"
#include "multicoregarbage.h"
#include "multicoregcmark.h"
-#include "gcqueue.h"
#include "multicoregccompact.h"
#include "multicoregcflush.h"
#include "multicoregcprofile.h"
#include "gcqueue.h"
-
-#ifdef SMEMM
-extern unsigned int gcmem_mixed_threshold;
-extern unsigned int gcmem_mixed_usedmem;
-#endif // SMEMM
+#include "multicoremem_helper.h"
+#include "bambooalign.h"
+#ifdef PERFCOUNT
+#include "bme_perf_counter.h"
+#endif
volatile bool gcflag;
gc_status_t gc_status_info;
int block = 0;
int sblock = 0;
unsigned int j = 0;
- void * i = 0;
+ unsigned int i = 0;
int coren = 0;
int x = 0;
int y = 0;
// reserved blocks for sblocktbl
printf("(%x,%x) ++++ reserved sblocks ++++ \n", udn_tile_coord_x(),
udn_tile_coord_y());
- for(i=BAMBOO_BASE_VA; (unsinged int)i<(unsigned int)gcbaseva; i+= 4*16) {
+ for(i=BAMBOO_BASE_VA; i<gcbaseva; i+= 4*16) {
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",
udn_tile_coord_x(), udn_tile_coord_y(),
*((int *)(i)), *((int *)(i + 4)),
}
#endif
-void initmulticoregcdata() {
- if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
- // startup core to initialize corestatus[]
- for(int i = 0; i < NUMCORESACTIVE; i++) {
- gccorestatus[i] = 1;
- gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
- gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
- }
- for(int i = 0; i < NUMCORES4GC; i++) {
- gcloads[i] = 0;
- gcrequiredmems[i] = 0;
- gcstopblock[i] = 0;
- gcfilledblocks[i] = 0;
+bool gc_checkCoreStatus() {
+ for(int i = 0; i < NUMCORES4GC; i++) {
+ if(gccorestatus[i]) {
+ return false;
}
}
+ return true;
+}
+
+void gc_resetCoreStatus() {
+ for(int i = 0; i < NUMCORES4GC; i++) {
+ gccorestatus[i] = 1;
+ }
+}
+
+void initmulticoregcdata() {
bamboo_smem_zero_top = NULL;
gcflag = false;
gc_status_info.gcprocessing = false;
gc_status_info.gcphase = FINISHPHASE;
gcprecheck = true;
- gccurr_heaptop = 0;
- gcself_numsendobjs = 0;
- gcself_numreceiveobjs = 0;
- gcmarkedptrbound = 0;
gcforwardobjtbl = allocateMGCHash_I(128);
- gcnumlobjs = 0;
- gcheaptop = 0;
- gctopcore = 0;
- gctopblock = 0;
- gcmovestartaddr = 0;
- gctomove = false;
- gcmovepending = 0;
- gcblock2fill = 0;
-#ifdef SMEMM
- gcmem_mixed_threshold=(unsigned int)((BAMBOO_SHARED_MEM_SIZE-bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
- gcmem_mixed_usedmem = 0;
-#endif
#ifdef MGC_SPEC
gc_profile_flag = false;
#endif
- gc_localheap_s = false;
-#ifdef GC_CACHE_ADAPT
- gccachestage = false;
-#endif
+
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+ allocationinfo.blocktable=RUNMALLOC(sizeof(struct blockrecord)*GCNUMBLOCK);
+ for(int i=0; i<GCNUMBLOCK;i++) {
+ if (1==NUMCORES4GC)
+ allocationinfo.blocktable[i].corenum=0;
+ else
+ allocationinfo.blocktable[i].corenum=gc_block2core[(i%(NUMCORES4GC*2))];
+ allocationinfo.blocktable[i].status=BS_FREE;
+ allocationinfo.blocktable[i].usedspace=0;
+ allocationinfo.blocktable[i].freespace=GLOBALBLOCKSIZE(i);
+ }
+ buildCore2Test();
+ }
+
+ //initialize update structures
+ origarraycount=0;
+ for(int i=0;i<NUMCORES4GC;i++) {
+ origblockarray[i]=NULL;
+ }
INIT_MULTICORE_GCPROFILE_DATA();
}
gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
gcloads[i] = 0;
gcrequiredmems[i] = 0;
- gcfilledblocks[i] = 0;
- gcstopblock[i] = 0;
}
for(int i = NUMCORES4GC; i < NUMCORESACTIVE; i++) {
gccorestatus[i] = 1;
gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
}
- gcheaptop = 0;
- gctopcore = 0;
- gctopblock = 0;
gcnumsrobjs_index = 0;
}
gcself_numsendobjs = 0;
gcself_numreceiveobjs = 0;
- gcmarkedptrbound = 0;
- gcnumlobjs = 0;
gcmovestartaddr = 0;
gctomove = false;
gcblock2fill = 0;
gcmovepending = 0;
gccurr_heaptop = 0;
-
+ update_origblockptr=NULL;
gc_queueinit();
MGCHashreset(gcforwardobjtbl);
gc_output_cache_policy_time=0;
}
-bool gc_checkAllCoreStatus() {
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- for(int i = 0; i < NUMCORESACTIVE; i++) {
- if(gccorestatus[i] != 0) {
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- return false;
- }
- }
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- return true;
-}
-
-// NOTE: should be invoked with interrupts turned off
-bool gc_checkAllCoreStatus_I() {
- for(int i = 0; i < NUMCORESACTIVE; i++) {
- if(gccorestatus[i] != 0) {
- return false;
- }
- }
- return true;
-}
-
void checkMarkStatus_p2() {
+ // tprintf("Check mark status 2\n");
// check if the sum of send objs and receive obj are the same
// yes->check if the info is the latest; no->go on executing
unsigned int sumsendobj = 0;
}
}
if(i == NUMCORESACTIVE) {
+ //tprintf("Mark terminated\n");
// all the core status info are the latest,stop mark phase
gc_status_info.gcphase = COMPACTPHASE;
// restore the gcstatus for all cores
}
void checkMarkStatus() {
+ // tprintf("Check mark status\n");
if((!waitconfirm)||(waitconfirm && (numconfirm == 0))) {
unsigned int entry_index = 0;
if(waitconfirm) {
entry_index = gcnumsrobjs_index;
}
BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
- gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
- gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
// check the status of all cores
- if (gc_checkAllCoreStatus_I()) {
+ if (gc_checkCoreStatus()) {
// ask for confirm
if(!waitconfirm) {
// the first time found all cores stall
}
// compute load balance for all cores
-int loadbalance(void ** heaptop, unsigned int * topblock, unsigned int * topcore) {
+int loadbalance() {
// compute load balance
// get the total loads
+ void * heaptop;
unsigned int tloads = 0;
for(int i = 0; i < NUMCORES4GC; i++) {
tloads += gcloads[i];
+ //tprintf("load: %d %d \n", gcloads[i], i);
}
- *heaptop = gcbaseva + tloads;
+ heaptop = gcbaseva + tloads;
unsigned int topblockindex;
- BLOCKINDEX(topblockindex, *heaptop);
+ BLOCKINDEX(topblockindex, heaptop);
// num of blocks per core
unsigned int numbpc = (topblockindex+NUMCORES4GC-1)/NUMCORES4GC;
- *topblock = topblockindex;
- RESIDECORE(*heaptop, *topcore);
return numbpc;
}
-
-// update the bmmboo_smemtbl to record current shared mem usage
-void updateSmemTbl(unsigned int coren, void * localtop) {
- unsigned int ltopcore = 0;
- unsigned int bound = BAMBOO_SMEM_SIZE_L;
- BLOCKINDEX(ltopcore, localtop);
- if((unsigned int)localtop>=(unsigned int)(gcbaseva+BAMBOO_LARGE_SMEM_BOUND)){
- bound = BAMBOO_SMEM_SIZE;
- }
- unsigned int load = (unsigned INTPTR)(localtop-gcbaseva)%(unsigned int)bound;
- unsigned int toset = 0;
- for(int j=0; 1; j++) {
- for(int i=0; i<2; i++) {
- toset = gc_core2block[2*coren+i]+(unsigned int)(NUMCORES4GC*2)*j;
- if(toset < ltopcore) {
- bamboo_smemtbl[toset]=BLOCKSIZE(toset<NUMCORES4GC);
-#ifdef SMEMM
- gcmem_mixed_usedmem += bamboo_smemtbl[toset];
-#endif
- } else if(toset == ltopcore) {
- bamboo_smemtbl[toset] = load;
-#ifdef SMEMM
- gcmem_mixed_usedmem += bamboo_smemtbl[toset];
-#endif
- return;
- } else {
- return;
- }
- }
- }
-}
-
void gc_collect(struct garbagelist * stackptr) {
gc_status_info.gcprocessing = true;
// inform the master that this core is at a gc safe point and is ready to
// do gc
send_msg_4(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
+ // invalidate all shared mem pointers
+ bamboo_cur_msp = NULL;
+ bamboo_smem_size = 0;
+ bamboo_smem_zero_top = NULL;
+ gcflag = false;
+
+
// core collector routine
//wait for init phase
WAITFORGCPHASE(INITPHASE);
WAITFORGCPHASE(MARKPHASE);
GC_PRINTF("Start mark phase\n");
- mark(true, stackptr);
+ mark(stackptr);
GC_PRINTF("Finish mark phase, start compact phase\n");
compact();
GC_PRINTF("Finish compact phase\n");
WAITFORGCPHASE(UPDATEPHASE);
- GC_PRINTF("Start flush phase\n");
+ GC_PRINTF("Start update phase\n");
GCPROFILE_INFO_2_MASTER();
- flush(stackptr);
- GC_PRINTF("Finish flush phase\n");
+ update(stackptr);
+ GC_PRINTF("Finish update phase\n");
CACHEADAPT_PHASE_CLIENT();
- // invalidate all shared mem pointers
- bamboo_cur_msp = NULL;
- bamboo_smem_size = 0;
- bamboo_smem_zero_top = NULL;
- gcflag = false;
-
WAITFORGCPHASE(FINISHPHASE);
GC_PRINTF("Finish gc! \n");
// inform the master that this core is at a gc safe point and is ready to
// do gc
send_msg_4(STARTUPCORE,GCFINISHPRE,BAMBOO_NUM_OF_CORE,self_numsendobjs,self_numreceiveobjs);
+
+ // invalidate all shared mem pointers
+ bamboo_cur_msp = NULL;
+ bamboo_smem_size = 0;
+ bamboo_smem_zero_top = NULL;
+ gcflag = false;
WAITFORGCPHASE(INITPHASE);
GC_PRINTF("Do initGC\n");
initGC();
CACHEADAPT_GC(true);
+
//send init finish msg to core coordinator
send_msg_2(STARTUPCORE,GCFINISHINIT,BAMBOO_NUM_OF_CORE);
+
WAITFORGCPHASE(MARKPHASE);
GC_PRINTF("Start mark phase\n");
- mark(true, stackptr);
- GC_PRINTF("Finish mark phase, wait for flush\n");
+ mark(stackptr);
+ GC_PRINTF("Finish mark phase, wait for update\n");
// non-gc core collector routine
WAITFORGCPHASE(UPDATEPHASE);
- GC_PRINTF("Start flush phase\n");
+ GC_PRINTF("Start update phase\n");
GCPROFILE_INFO_2_MASTER();
- flush(stackptr);
- GC_PRINTF("Finish flush phase\n");
+ update(stackptr);
+ GC_PRINTF("Finish update phase\n");
CACHEADAPT_PHASE_CLIENT();
- // invalidate all shared mem pointers
- bamboo_cur_msp = NULL;
- bamboo_smem_size = 0;
- bamboo_smem_zero_top = NULL;
-
- gcflag = false;
WAITFORGCPHASE(FINISHPHASE);
GC_PRINTF("Finish gc! \n");
}
void master_mark(struct garbagelist *stackptr) {
- bool isfirst = true;
GC_PRINTF("Start mark phase \n");
- GC_SEND_MSG_1_TO_CLIENT(GCSTART);
gc_status_info.gcphase = MARKPHASE;
+ GC_SEND_MSG_1_TO_CLIENT(GCSTART);
// mark phase
- while(MARKPHASE == gc_status_info.gcphase) {
- mark(isfirst, stackptr);
- isfirst=false;
- // check gcstatus
- checkMarkStatus();
- }
+ mark(stackptr);
}
void master_getlargeobjs() {
//spin until we have all responses
while(numconfirm!=0) ;
- // check the heaptop
- if(gcheaptop < gcmarkedptrbound) {
- gcheaptop = gcmarkedptrbound;
- }
- GCPROFILE_ITEM();
+ GCPROFILE_ITEM_MASTER();
GC_PRINTF("prepare to cache large objs \n");
}
void master_updaterefs(struct garbagelist * stackptr) {
gc_status_info.gcphase = UPDATEPHASE;
GC_SEND_MSG_1_TO_CLIENT(GCSTARTUPDATE);
- GCPROFILE_ITEM();
- GC_PRINTF("Start flush phase \n");
- // flush phase
- flush(stackptr);
- GC_CHECK_ALL_CORE_STATUS(UPDATEPHASE==gc_status_info.gcphase);
- GC_PRINTF("Finish flush phase \n");
+ GC_PRINTF("Start update phase \n");
+ // update phase
+ update(stackptr);
+ GC_CHECK_ALL_CORE_STATUS();
+ GC_PRINTF("Finish update phase \n");
}
void master_finish() {
bamboo_smem_size = 0;
bamboo_smem_zero_top = NULL;
- GCPROFILE_END();
+ GCPROFILE_END_MASTER();
unsigned long long tmpt = BAMBOO_GET_EXE_TIME();
CACHEADAPT_OUTPUT_CACHE_POLICY();
gc_output_cache_policy_time += (BAMBOO_GET_EXE_TIME()-tmpt);
gcflag = false;
+
GC_SEND_MSG_1_TO_CLIENT(GCFINISH);
-
- gc_status_info.gcprocessing = false;
+ gc_status_info.gcprocessing = false;
+
if(gcflag) {
// inform other cores to stop and wait for gc
+ GC_PRINTF("Back to Back gc case\n");
gcprecheck = true;
for(int i = 0; i < NUMCORESACTIVE; i++) {
// reuse the gcnumsendobjs & gcnumreceiveobjs
}
void gc_master(struct garbagelist * stackptr) {
- tprintf("start GC !!!!!!!!!!!!! \n");
+ tprintf("start GC!\n");
gc_status_info.gcprocessing = true;
gc_status_info.gcphase = INITPHASE;
+ GC_SEND_MSG_1_TO_CLIENT(GCSTARTINIT);
waitconfirm = false;
numconfirm = 0;
initGC();
- GC_SEND_MSG_1_TO_CLIENT(GCSTARTINIT);
CACHEADAPT_GC(true);
- GC_PRINTF("Check core status \n");
- GC_CHECK_ALL_CORE_STATUS(true);
- GCPROFILE_ITEM();
+ //tprintf("Check core status \n");
+ GC_CHECK_ALL_CORE_STATUS();
unsigned long long tmpt = BAMBOO_GET_EXE_TIME();
CACHEADAPT_OUTPUT_CACHE_SAMPLING();
gc_output_cache_policy_time += (BAMBOO_GET_EXE_TIME()-tmpt);
-
+ //tprintf("start mark phase\n");
// do mark phase
+ GCPROFILE_ITEM_MASTER();
master_mark(stackptr);
-
+ GCPROFILE_ITEM_MASTER();
+ //tprintf("finish mark phase\n");
// get large objects from all cores
master_getlargeobjs();
-
+ //tprintf("start compact phase\n");
// compact the heap
master_compact();
-
+ //tprintf("start update phase\n");
// update the references
master_updaterefs(stackptr);
-
+ //tprintf("gc master finished update \n");
// do cache adaptation
CACHEADAPT_PHASE_MASTER();
-
+ //tprintf("finish cachdapt phase\n");
// do finish up stuff
+#ifdef GC_DEBUG
+ for(int i=0;i<GCNUMBLOCK;i++) {
+ struct blockrecord *record=&allocationinfo.blocktable[i];
+ tprintf("%u. used=%u free=%u corenum=%u status=%u, base=%x, ptr=%x\n", i, record->usedspace, record->freespace, record->corenum, record->status, gcbaseva+OFFSET2BASEVA(i), (gcbaseva+OFFSET2BASEVA(i)+record->usedspace));
+ }
+#endif
+
master_finish();
- GC_PRINTF("gc finished \n");
- tprintf("finish GC ! %d \n",gcflag);
+ //tprintf("finish GC ! %d \n",gcflag);
}
void pregccheck() {
}
void pregcprocessing() {
-#if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
+#if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)&&(defined(GC_CACHE_ADAPT_POLICY4)||defined(GC_CACHE_ADAPT_POLICY3))
// disable the timer interrupt
bamboo_mask_timer_intr();
-#endif
- // Zero out the remaining memory here because for the GC_CACHE_ADAPT version,
- // we need to make sure during the gcinit phase the shared heap is not
- // touched. Otherwise, there would be problem when adapt the cache strategy.
- BAMBOO_CLOSE_CUR_MSP();
-#if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
// get the sampling data
bamboo_output_dtlb_sampling();
#endif
}
void postgcprocessing() {
-#if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)
+#if defined(GC_CACHE_ADAPT)&&defined(GC_CACHE_SAMPLING)&&(defined(GC_CACHE_ADAPT_POLICY4)||defined(GC_CACHE_ADAPT_POLICY3))
// enable the timer interrupt
bamboo_tile_timer_set_next_event(GC_TILE_TIMER_EVENT_SETTING);
bamboo_unmask_timer_intr();
+ //turn on sampling again
+ bamboo_dtlb_sampling_init();
#endif
}
gc_status_info.gcprocessing = false;
return false;
}
+#ifdef PERFCOUNT
+ profile_start(GC_REGION);
+#endif
// core coordinator routine
if(0 == BAMBOO_NUM_OF_CORE) {
+ GC_PRINTF("start gc! \n");
+ GCPROFILE_START_MASTER();
+
GC_PRINTF("Check if we can do gc or not\n");
gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
- if(!gc_checkAllCoreStatus()) {
- // some of the cores are still executing the mutator and did not reach
- // some gc safe point, therefore it is not ready to do gc
- gcflag = true;
- return false;
- } else {
- GCPROFILE_START();
- pregccheck();
- }
- GC_PRINTF("start gc! \n");
pregcprocessing();
+
+ //wait for other cores to catch up
+ while(!gc_checkCoreStatus())
+ ;
+
+ //pregccheck();
gc_master(stackptr);
} else if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
+ GC_PRINTF("Core reporting for gc.\n");
pregcprocessing();
gc_collect(stackptr);
} else {
gc_nocollect(stackptr);
}
postgcprocessing();
-
+#ifdef PERFCOUNT
+ profile_start(APP_REGION);
+#endif
return true;
}