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))];
+ }
+ }
+
INIT_MULTICORE_GCPROFILE_DATA();
}
void initGC() {
if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+ for(int i=0; i<GCNUMBLOCK;i++) {
+ allocationinfo.blocktable[i].status=BS_INIT;
+ }
+ allocationinfo.lowestfreeblock=NOFREEBLOCK;
for(int i = 0; i < NUMCORES4GC; i++) {
gccorestatus[i] = 1;
gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 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;
}
-#ifndef BAMBOO_MULTICORE_GARBAGE_H
+m#ifndef BAMBOO_MULTICORE_GARBAGE_H
#define BAMBOO_MULTICORE_GARBAGE_H
#ifdef MULTICORE_GC
#include "multicore.h"
COMPACTPHASE, // 0x2
SUBTLECOMPACTPHASE, // 0x3
MAPPHASE, // 0x4
- UPDATEPHASE, // 0x5
+ UPDATEPHASE, // 0x5
CACHEPOLICYPHASE, // 0x6
PREFINISHPHASE, // 0x7
- FINISHPHASE // 0x6/0x8
+ FINISHPHASE // 0x8
} GCPHASETYPE;
typedef struct gc_status {
volatile unsigned int gcnumsendobjs[2][NUMCORESACTIVE];//# of objects sent out
volatile unsigned int gcnumreceiveobjs[2][NUMCORESACTIVE];//# of objects received
volatile unsigned int gcnumsrobjs_index;//indicates which entry to record the
- // info received before phase 1 of the mark finish
- // checking process
- // the info received in phase 2 must be
- // recorded in the other entry
+ // info received before phase 1 of the mark finish
+ // checking process
+ // the info received in phase 2 must be
+ // recorded in the other entry
unsigned int gcself_numsendobjs;
unsigned int gcself_numreceiveobjs;
//mark table....keep track of mark bits
unsigned int * gcmarktbl;
+void * gcbaseva; // base va for shared memory without reserved sblocks
+/* Structure to keep track of free space in block */
+enum blockstatus {
+ /* BS_INIT indicates that we don't have information for this block yet */
+ BS_INIT,
+ /* BS_LARGEOBJECT indicates that the beginning of this block has a large object*/
+ BS_LARGEOBJECT,
+ /* BS_FREE indicates that the block is at least partially free */
+ BS_FREE
+};
-unsigned int gcnumblock; // number of total blocks in the shared mem
-void * gcbaseva; // base va for shared memory without reserved sblocks
+struct blockrecord {
+ enum blockstatus status;
+ unsigned INTPTR usedspace;
+ unsigned int corenum;
+
+};
+
+#define NOFREEBLOCK 0xffffffff
+struct allocrecord {
+ unsigned int lowestfreeblock;
+ struct blockrecord * blocktable;
+};
+
+struct allocrecord allocationinfo;
#ifdef GC_CACHE_ADAPT
void * gctopva; // top va for shared memory without reserved sblocks
unsigned int size_cachepolicytbl;
#endif
-#define WAITFORGCPHASE(phase) while(gc_status_info.gcphase != phase) ;
-
-#define ISSHAREDOBJ(p) \
- ((((unsigned int)p)>=gcbaseva)&&(((unsigned int)p)<(gcbaseva+(BAMBOO_SHARED_MEM_SIZE))))
+/* Total number of blocks in heap */
-#define MAXBLOCK 0x4fffffff //local block number that can never be reached...
+#define GCNUMBLOCK (NUMCORES4GC+(BAMBOO_SHARED_MEM_SIZE-BAMBOO_LARGE_SMEM_BOUND)/BAMBOO_SMEM_SIZE)
+/* This macro waits for the given gc phase */
+#define WAITFORGCPHASE(phase) while(gc_status_info.gcphase != phase) ;
-/* Number of bits used for each alignment unit */
+/* Local block number that can never be reached...*/
+#define MAXBLOCK 0x4fffffff
//Takes in pointer to heap object and converts to offset in alignment units
#define OBJMAPPINGINDEX(p) ALIGNOBJSIZE((unsigned INTPTR)(p-gcbaseva))
} \
}
-#define RESIDECORE(p, c) { \
+#define RESIDECORE(c, p) { \
if(1 == (NUMCORES4GC)) { \
c = 0; \
} else { \
INLINE static unsigned int hostcore(void * ptr) {
// check the host core of ptr
- unsigned int host = 0;
- RESIDECORE(ptr, host);
+ unsigned int host;
+ RESIDECORE(host, ptr);
return host;
}
//set flag to wait for memory
gctomove=false;
//send request for memory
- send_msg_4(STARTUPCORE,GCFINISHCOMPACT,BAMBOO_NUM_OF_CORE, to->ptr, minimumbytes);
+ send_msg_3(STARTUPCORE,GCFINISHCOMPACT,BAMBOO_NUM_OF_CORE, minimumbytes);
//wait for flag to be set that we received message
while(!gctomove) ;
}
void compacthelper(struct moveHelper * orig,struct moveHelper * to) {
+ bool senttopmessage=false;
while(true) {
+ if ((gcheaptop < ((unsigned INTPTR)(to->bound-to->ptr)))&&!senttopmessage) {
+ //This block is the last for this core...let the startup know
+ send_msg_3(STARTUPCORE, GCRETURNMEM, BAMBOO_NUM_OF_CORE, to->ptr+gcheaptop);
+ //Only send the message once
+ senttopmessage=true;
+ }
+
unsigned int minimumbytes=compactblocks(orig, to);
if (orig->ptr==orig->bound) {
//need more data to compact
getSpace(to, minimumbytes);
}
}
-
- send_msg_4(STARTUPCORE,GCFINISHCOMPACT,BAMBOO_NUM_OF_CORE, to->ptr, 0);
+
+ send_msg_3(STARTUPCORE,GCFINISHCOMPACT,BAMBOO_NUM_OF_CORE, 0);
}
/* Should be invoked with interrupt turned off. */
/* This function is performance critical... spend more time optimizing it */
unsigned int compactblocks(struct moveHelper * orig, struct moveHelper * to) {
- void *toptr=to->ptr;
+ void *toptrinit=to->ptr;
+ void *toptr=toptr;
void *tobound=to->bound;
void *origptr=orig->ptr;
void *origbound=orig->bound;
origptr=origbound;
to->ptr=toptr;
orig->ptr=origptr;
+ gcheaptop-=(unsigned INTPTR)(toptr-toptrinit)
return 0;
}
} while(!gcmarktbl[arrayoffset]);
unsigned int length=ALIGNSIZETOBYTES(objlength);
void *endtoptr=toptr+length;
if (endtoptr>tobound) {
- toptr=tobound;
- to->ptr=toptr;
+ gcheaptop-=(unsigned INTPTR)(toptr-toptrinit)
+ to->ptr=tobound;
orig->ptr=origptr;
return length;
}
unsigned int type = 0;
bool islarge=isLarge(ptr, &type, &size);
unsigned int iunits = ALIGNUNITS(size);
-
+
setLengthMarked(ptr,iunits);
if(islarge) {
{ \
if(gc_profile_flag) { \
gc_num_livespace = 0; \
- for(int tmpi = 0; tmpi < gcnumblock; tmpi++) { \
+ for(int tmpi = 0; tmpi < GCNUMBLOCK; tmpi++) { \
gc_num_livespace += bamboo_smemtbl[tmpi]; \
} \
gc_num_freespace = (BAMBOO_SHARED_MEM_SIZE) - gc_num_livespace; \
#define GCPROFILE_RECORD_SPACE() \
{ \
gc_num_livespace = 0; \
- for(int tmpi = 0; tmpi < gcnumblock; tmpi++) { \
+ for(int tmpi = 0; tmpi < GCNUMBLOCK; tmpi++) { \
gc_num_livespace += bamboo_smemtbl[tmpi]; \
} \
gc_num_freespace = (BAMBOO_SHARED_MEM_SIZE) - gc_num_livespace; \
continue;
}
tofindb=totest=gc_core2block[2*core2test[gccorenum][k]];
- mem=searchBlock4Mem(&tofindb,&totest,core2test[gccorenum][k],isize,allocsize,(k==0)?0:((gcnumblock/NUMCORES4GC)>>LOCALMEMRESERVATION));
+ mem=searchBlock4Mem(&tofindb,&totest,core2test[gccorenum][k],isize,allocsize,(k==0)?0:((GCNUMBLOCK/NUMCORES4GC)>>LOCALMEMRESERVATION));
if(mem!=NULL) {
return mem;
}
continue;
}
tofindb=totest=gc_core2block[2*core2test[gccorenum][k]];
- mem=searchBlock4Mem(&tofindb,&totest,core2test[gccorenum][k],isize,allocsize,(k==0)?0:((gcnumblock/NUMCORES4GC)>>LOCALMEMRESERVATION));
+ mem=searchBlock4Mem(&tofindb,&totest,core2test[gccorenum][k],isize,allocsize,(k==0)?0:((GCNUMBLOCK/NUMCORES4GC)>>LOCALMEMRESERVATION));
if(mem!=NULL) {
return mem;
}
4, //GCFINISHPRE, // 0xE7
2, //GCFINISHINIT, // 0xE8
4, //GCFINISHMARK, // 0xE9
- 4, //GCFINISHCOMPACT, // 0xEa
+ 3, //GCFINISHCOMPACT, // 0xEa
+ 3, //GCRETURNMEM,
2, //GCFINISHUPDATE, // 0xEb
1, //GCFINISH, // 0xEc
1, //GCMARKCONFIRM, // 0xEd
gcnumreceiveobjs[entry_index][data1] = data3;
}
}
+
+void processmsg_returnmem_I() {
+ unsigned int cnum = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ void * heaptop = (void *) msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ unsigned int blockindex;
+ BLOCKINDEX(blockindex, heaptop);
+ struct blockrecord * blockrecord=&allocationinfo.blocktable[blockindex];
+ if (cnum==blockrecord) {
+ //this is our own memory...need to clear our lower blocks
+ }
+}
INLINE void processmsg_gcfinishcompact_I() {
BAMBOO_ASSERT(BAMBOO_NUM_OF_CORE == STARTUPCORE);
int cnum = msgdata[msgdataindex];
MSG_INDEXINC_I();
- void * heaptop = (void *) msgdata[msgdataindex];
- MSG_INDEXINC_I();
unsigned int bytesneeded = msgdata[msgdataindex];
MSG_INDEXINC_I();
break;
}
+ case GCRETURNMEM: {
+ processmsg_returnmem_I();
+ break;
+ }
+
case GCFINISHCOMPACT: {
// received a compact phase finish msg
processmsg_gcfinishcompact_I();
GCFINISHINIT, // 0xE8
GCFINISHMARK, // 0xE9
GCFINISHCOMPACT, // 0xEa
+ GCRETURNMEM,
GCFINISHUPDATE, // 0xEb
GCFINISH, // 0xEc
GCMARKCONFIRM, // 0xEd
}
#endif
-void * mycalloc(int size,
- char * file,
- int line) {
- void * p = NULL;
- int isize = size;
+void * mycalloc(int size, char * file, int line) {
BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- p = BAMBOO_LOCAL_MEM_CALLOC(isize);
-
- if(p == NULL) {
- printf("mycalloc %s %d \n", file, line);
- BAMBOO_EXIT();
- }
+ void * p = mycalloc_i(size, file, line);
BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
return p;
}
-void * mycalloc_i(int size,
- char * file,
- int line) {
- void * p = NULL;
- int isize = size;
- p = BAMBOO_LOCAL_MEM_CALLOC(isize);
+void * mycalloc_i(int size, char * file, int line) {
+ void * p = BAMBOO_LOCAL_MEM_CALLOC(size);
if(p == NULL) {
tprintf("mycalloc_i %s %d \n", file, line);
BAMBOO_EXIT();