void * p = NULL;
//int isize = 2*BAMBOO_CACHE_LINE_SIZE-4+(size-1)&(~BAMBOO_CACHE_LINE_MASK);
int isize = (size & (~(BAMBOO_CACHE_LINE_MASK))) + (BAMBOO_CACHE_LINE_SIZE);
- bool hasgc = false;
+ int hasgc = 0;
memalloc:
BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
#ifdef DEBUG
if(p == NULL) {
// no more global shared memory
BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- if(!hasgc) {
- // start gc
- gc(stackptr);
- hasgc = true;
+ if(hasgc < 5) {
+ // start gc
+ if(gc(stackptr)) {
+ hasgc++;
+ }
} else {
// no more global shared memory
+ //BAMBOO_DEBUGPRINT_REG(isize);
BAMBOO_EXIT(0xc002);
}
BAMBOO_DEBUGPRINT(0xee0a);
#endif
} // void checkMarkStatue()
-
+/*
inline bool preGC() {
// preparation for gc
// make sure to clear all incoming msgs espacially transfer obj msgs
corestatus[i] = 1;
// send status confirm msg to core i
send_msg_1(i, STATUSCONFIRM, false);
- } // for(i = 1; i < NUMCORESACTIVE; ++i)
+ } // for(i = 1; i < NUMCORESACTIVE; ++i)
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xec02);
if(numconfirm == 0) {
break;
}
- } // wait for confirmations
+ } // wait for confirmations
waitconfirm = false;
numconfirm = 0;
#ifdef DEBUG
} else {
// still have some transfer obj msgs on-the-fly, can not start gc
return false;
- } // if(0 == sumsendobj)
+ } // if(0 == sumsendobj)
} else {
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xec07);
// confirmations yet, can not start gc
return false;
} // if((!waitconfirm) ||
-} // bool preGC()
+} // bool preGC()*/
inline void initGC() {
int i;
}
} while(true);
+ // TODO
+ /*unsigned long long gc_num_livespace = 0;
+ for(int tmpi = 0; tmpi < gcnumblock; tmpi++) {
+ gc_num_livespace += bamboo_smemtbl[tmpi];
+ }
+ BAMBOO_DEBUGPRINT_REG(gc_num_livespace);
+ BAMBOO_DEBUGPRINT_REG(bamboo_free_block);*/
+
#ifdef GC_PROFILE
// check how many live space there are
gc_num_livespace = 0;
} // flush()
inline void gc_collect(struct garbagelist * stackptr) {
+ //BAMBOO_DEBUGPRINT(0xcccc); // TODO
+ // 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, false);
+
// core collector routine
while(true) {
if(INITPHASE == gcphase) {
} // void gc_collect(struct garbagelist * stackptr)
inline void gc_nocollect(struct garbagelist * stackptr) {
+ //BAMBOO_DEBUGPRINT(0xcccc); // TODO
+ // 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, false);
+
while(true) {
if(INITPHASE == gcphase) {
break;
#endif
} // void gc_collect(struct garbagelist * stackptr)
-inline void gc(struct garbagelist * stackptr) {
+inline bool gc(struct garbagelist * stackptr) {
// check if do gc
if(!gcflag) {
gcprocessing = false;
- return;
+ return false;
}
// core coordinator routine
printf("(%x,%X) Check if can do gc or not\n", udn_tile_coord_x(),
udn_tile_coord_y());
#endif
- if(!preGC()) {
- // not ready to do gc
- gcflag = true;
- return;
- }
-
+ //if(gcnumpre != 0) {
+ bool isallstall = true;
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ int ti = 0;
+ for(ti = 0; ti < NUMCORESACTIVE; ++ti) {
+ if(gccorestatus[ti] != 0) {
+ isallstall = false;
+ break;
+ }
+ }
+ if(!isallstall) {
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ // 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
+ // in case that there are some pregc information msg lost, send a confirm
+ // msg to the 'busy' core
+ send_msg_1(ti, GCSTARTPRE, false);
+ gcflag = true;
+ return false;
+ } else {
+ // TODO
#ifdef GC_PROFILE
gc_profileStart();
#endif
-
+ //BAMBOO_DEBUGPRINT(0x1111); // TODO
+pregccheck:
+ //BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ gcnumsendobjs[0][BAMBOO_NUM_OF_CORE] = self_numsendobjs;
+ gcnumreceiveobjs[0][BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
+ int sumsendobj = 0;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec04);
+#endif
+ for(int i = 0; i < NUMCORESACTIVE; ++i) {
+ sumsendobj += gcnumsendobjs[0][i];
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000 + gcnumsendobjs[0][i]);
+#endif
+ } // for(i = 1; i < NUMCORESACTIVE; ++i)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec05);
+ BAMBOO_DEBUGPRINT_REG(sumsendobj);
+#endif
+ for(int i = 0; i < NUMCORESACTIVE; ++i) {
+ sumsendobj -= gcnumreceiveobjs[0][i];
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000 + gcnumreceiveobjs[i]);
+#endif
+ } // for(i = 1; i < NUMCORESACTIVE; ++i)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec06);
+ BAMBOO_DEBUGPRINT_REG(sumsendobj);
+#endif
+ if(0 != sumsendobj) {
+ // there were still some msgs on the fly, wait until there
+ // are some update pregc information coming and check it again
+ gcprecheck = false;
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ //BAMBOO_DEBUGPRINT(0x2222); // TODO
+ while(true) {
+ if(gcprecheck) {
+ break;
+ }
+ }
+ goto pregccheck;
+ } else {
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ }
+ }
+/*
+#ifdef GC_PROFILE
+ gc_profileStart();
+#endif
+*/
#ifdef RAWPATH // TODO GC_DEBUG
printf("(%x,%x) start gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
//dumpSMem();
gcflag = false;
gcprocessing = false;
}
+ //if(STARTUPCORE == BAMBOO_NUM_OF_CORE) BAMBOO_DEBUGPRINT(0xeeee); // TODO
+ return true;
} // void gc(struct garbagelist * stackptr)
#ifdef GC_PROFILE
volatile bool gcprocessing;
volatile GCPHASETYPE gcphase; // indicating GC phase
+volatile bool gcpreinform; // counter for stopped cores
+volatile bool gcprecheck; // indicates if there are updated pregc information
+
int gccurr_heaptop;
struct MGCHash * gcforwardobjtbl; // cache forwarded objs in mark phase
// for mark phase termination
// the next core in the top of the heap
#define NEXTTOPCORE(b) (gc_block2core[((b)+1)%(NUMCORES4GC*2)])
-inline void gc(struct garbagelist * stackptr); // core coordinator routine
+inline bool gc(struct garbagelist * stackptr); // core coordinator routine
inline void gc_collect(struct garbagelist* stackptr); //core collector routine
inline void gc_nocollect(struct garbagelist* stackptr); //non-gc core collector routine
inline void transferMarkResults_I();
MEMREQUEST, // 0xE0
MEMRESPONSE, // 0xE1
#ifdef MULTICORE_GC
- GCSTARTINIT, // 0xE2
- GCSTART, // 0xE3
- GCSTARTCOMPACT, // 0xE4
- GCSTARTMAPINFO, // 0xE5
- GCSTARTFLUSH, // 0xE6
- GCFINISHINIT, // 0xE7
- GCFINISHMARK, // 0xE8
- GCFINISHCOMPACT, // 0xE9
- GCFINISHMAPINFO, // 0xEa
- GCFINISHFLUSH, // 0xEb
- GCFINISH, // 0xEc
- GCMARKCONFIRM, // 0xEd
- GCMARKREPORT, // 0xEe
- GCMARKEDOBJ, // 0xEf
- GCMOVESTART, // 0xF0
- GCMAPREQUEST, // 0xF1
- GCMAPINFO, // 0xF2
- GCMAPTBL, // 0xF3
- GCLOBJREQUEST, // 0xF4
- GCLOBJINFO, // 0xF5
- GCLOBJMAPPING, // 0xF6
-#ifdef GC_PROFILE//_S
- GCPROFILES, // 0xF7
+ GCSTARTPRE, // 0xE2
+ GCSTARTINIT, // 0xE3
+ GCSTART, // 0xE4
+ GCSTARTCOMPACT, // 0xE5
+ GCSTARTMAPINFO, // 0xE6
+ GCSTARTFLUSH, // 0xE7
+ GCFINISHPRE, // 0xE8
+ GCFINISHINIT, // 0xE9
+ GCFINISHMARK, // 0xEa
+ GCFINISHCOMPACT, // 0xEb
+ GCFINISHMAPINFO, // 0xEc
+ GCFINISHFLUSH, // 0xEd
+ GCFINISH, // 0xEe
+ GCMARKCONFIRM, // 0xEf
+ GCMARKREPORT, // 0xF0
+ GCMARKEDOBJ, // 0xF1
+ GCMOVESTART, // 0xF2
+ GCMAPREQUEST, // 0xF3
+ GCMAPINFO, // 0xF4
+ GCMAPTBL, // 0xF5
+ GCLOBJREQUEST, // 0xF6
+ GCLOBJINFO, // 0xF7
+ GCLOBJMAPPING, // 0xF8
+#ifdef GC_PROFILE
+ GCPROFILES, // 0xF9
#endif
#endif
MSGEND
gcflag = false;
gcprocessing = false;
gcphase = FINISHPHASE;
+ //gcnumpre = 0;
+ gcprecheck = true;
gccurr_heaptop = 0;
gcself_numsendobjs = 0;
gcself_numreceiveobjs = 0;
while(true) {
#ifdef MULTICORE_GC
// check if need to do GC
- gc(NULL);
+ if(gcflag) {
+ gc(NULL);
+ }
#endif
// check if there are new active tasks can be executed
// no enough shared global memory
*allocsize = 0;
#ifdef MULTICORE_GC
- gcflag = true;
+ //gcflag = true;
+ if(!gcflag) {
+ gcflag = true;
+ // inform other cores to stop and wait for gc
+ gcprecheck = true;
+ for(int i = 0; i < NUMCORESACTIVE; i++) {
+ // reuse the gcnumsendobjs & gcnumreceiveobjs
+ gccorestatus[i] = 1;
+ gcnumsendobjs[0][i] = 0;
+ gcnumreceiveobjs[0][i] = 0;
+ }
+ for(int i = 0; i < NUMCORESACTIVE; i++) {
+ if(i != BAMBOO_NUM_OF_CORE) {
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_1(i, GCSTARTPRE);
+ } else {
+ send_msg_1(i, GCSTARTPRE, true);
+ }
+ }
+ }
+ }
return NULL;
#else
BAMBOO_DEBUGPRINT(0xa001);
case STATUSCONFIRM:
case TERMINATE:
#ifdef MULTICORE_GC
+ case GCSTARTPRE:
case GCSTARTINIT:
case GCSTART:
case GCSTARTMAPINFO:
case REDIRECTDENY:
case REDIRECTRELEASE:
#ifdef MULTICORE_GC
+ case GCFINISHPRE:
case GCFINISHMARK:
case GCMOVESTART:
#ifdef GC_PROFILE//_S
addNewItem_I(&objqueue, (void *)transObj);
}
++(self_numreceiveobjs);
+#ifdef MULTICORE_GC
+ if(gcprocessing) {
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+ // set the gcprecheck to enable checking again
+ gcprecheck = true;
+ } else {
+ // send a update pregc information msg to the master core
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
+ self_numsendobjs, self_numreceiveobjs);
+ } else {
+ send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
+ self_numsendobjs, self_numreceiveobjs, true);
+ }
+ }
+ }
+#endif
}
INLINE void processmsg_transtall_I() {
BAMBOO_DEBUGPRINT(0xe887);
#endif
#endif
+ //BAMBOO_DEBUGPRINT(0xffff); // TODO
// cache the msg first
if(BAMBOO_CHECK_SEND_MODE()) {
cache_msg_5(STARTUPCORE, STATUSREPORT,
} else {
send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
}
- } // if mem == NULL, the gcflag of the startup core has been set
- // and the gc should be started later, then a GCSTARTINIT msg
- // will be sent to the requesting core to notice it to start gc
- // and try malloc again
+ } else {
+ // if mem == NULL, the gcflag of the startup core has been set
+ // and all the other cores have been informed to start gc
+ // TODO
+ // inform other cores to stop and wait for gc
+ /*gcprecheck = true;
+ for(int i = 0; i < NUMCORESACTIVE; i++) {
+ // reuse the gcnumsendobjs & gcnumreceiveobjs
+ gccorestatus[i] = 1;
+ gcnumsendobjs[0][i] = 0;
+ gcnumreceiveobjs[0][i] = 0;
+ }
+ for(int i = 0; i < NUMCORESACTIVE; i++) {
+ if(i != BAMBOO_NUM_OF_CORE) {
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_1(i, GCSTARTPRE);
+ } else {
+ send_msg_1(i, GCSTARTPRE, true);
+ }
+ }
+ }*/
+ }
#ifdef MULTICORE_GC
}
#endif
}
#ifdef MULTICORE_GC
+INLINE void processmsg_gcstartpre_I() {
+ //BAMBOO_DEBUGPRINT(0xc000); // TODO
+ if(gcprocessing) {
+ // already stall for gc
+ // send a update pregc information msg to the master core
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
+ self_numsendobjs, self_numreceiveobjs);
+ } else {
+ send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
+ self_numsendobjs, self_numreceiveobjs, true);
+ }
+ } else {
+ // the first time to be informed to start gc
+ gcflag = true;
+ if(!smemflag) {
+ // is waiting for response of mem request
+ // let it return NULL and start gc
+ bamboo_smem_size = 0;
+ bamboo_cur_msp = NULL;
+ smemflag = true;
+ bamboo_smem_zero_top = NULL;
+ }
+ }
+}
+
INLINE void processmsg_gcstartinit_I() {
- gcflag = true;
+ //gcflag = true;
gcphase = INITPHASE;
- if(!smemflag) {
+ /*if(!smemflag) {
// is waiting for response of mem request
// let it return NULL and start gc
bamboo_smem_size = 0;
bamboo_cur_msp = NULL;
smemflag = true;
bamboo_smem_zero_top = NULL;
- }
+ }*/
}
INLINE void processmsg_gcstart_I() {
gcphase = FLUSHPHASE;
}
+INLINE void processmsg_gcfinishpre_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data3 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // received a init phase finish msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive this msg
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+ BAMBOO_EXIT(0xb000);
+ }
+ // All cores should do init GC
+ /*if(gcprecheck && (gcnumpre > 0)) {
+ gcnumpre--;
+ } else {*/
+ if(!gcprecheck) {
+ gcprecheck = true;
+ }
+ gccorestatus[data1] = 0;
+ gcnumsendobjs[0][data1] = data2;
+ gcnumreceiveobjs[0][data1] = data3;
+}
+
INLINE void processmsg_gcfinishinit_I() {
int data1 = msgdata[msgdataindex];
MSG_INDEXINC_I();
#ifdef MULTICORE_GC
// GC msgs
- case GCSTARTINIT: {
+ case GCSTARTPRE: {
+ processmsg_gcstartpre_I();
+ break;
+ } // case GCSTARTPRE
+
+ case GCSTARTINIT: {
processmsg_gcstartinit_I();
break;
} // case GCSTARTINIT
break;
} // case GCSTARTFLUSH
- case GCFINISHINIT: {
+ case GCFINISHPRE: {
+ processmsg_gcfinishpre_I();
+ break;
+ } // case GCFINISHPRE
+
+ case GCFINISHINIT: {
processmsg_gcfinishinit_I();
break;
} // case GCFINISHINIT
newtask:
while(hashsize(activetasks)>0) {
#ifdef MULTICORE_GC
- gc(NULL);
+ if(gcflag) gc(NULL);
#endif
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xe990);