}
void gc_master(struct garbagelist * stackptr) {
- tprintf("start GC!\n");
+ //tprintf("start GC!\n");
gc_status_info.gcprocessing = true;
gc_status_info.gcphase = INITPHASE;
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();
//tprintf("finish GC ! %d \n",gcflag);
#define MINMEMORYCHUNKSIZE 32768
+#define ISVALIDPTR(x) ((((unsigned INTPTR)x)>=((unsigned INTPTR)gcbaseva))&&(((unsigned INTPTR)x)<((unsigned INTPTR)(gcbaseva+BAMBOO_SHARED_MEM_SIZE))))
+
/* This macro waits for the given gc phase */
#define WAITFORGCPHASE(phase) while(gc_status_info.gcphase != phase) ;
#include "multicoregarbage.h"
#include "markbit.h"
#include "multicoremem_helper.h"
+#include "gcqueue.h"
int gc_countRunningCores() {
int count=0;
}
/* This is our own block...means we should mark other blocks above us as free*/
+
if (cnum==blockrecord->corenum) {
unsigned INTPTR nextlocalblocknum=localblocknum+1;
for(;nextlocalblocknum<numblockspercore;nextlocalblocknum++) {
senttopmessage=true;
}
unsigned int minimumbytes=compactblocks(orig, to);
+
if (orig->ptr==orig->bound) {
//need more data to compact
//increment the core
if (block->status==BS_FREE) {
if(firstfree==NOFREEBLOCK)
firstfree=searchblock;
+ //don't take a block from another core that hasn't returned its memory yet
+ if (block->corenum!=core&&returnedmem[block->corenum])
+ continue;
+
unsigned INTPTR freespace=block->freespace&~BAMBOO_CACHE_LINE_MASK;
if (freespace>=memcheck) {
//TODO: should check memory block at same level on our own core...if that works, use it to preserve locality
initOrig_Dst(&orig, &to);
CACHEADAPT_SAMPLING_DATA_REVISE_INIT(&orig, &to);
-
compacthelper(&orig, &to);
}
// NOTE: the objptr should not be NULL and should not be non shared ptr
#define updateObj(objptr) gcmappingtbl[OBJMAPPINGINDEX(objptr)]
//#define UPDATEOBJ(obj) {void *updatetmpptr=obj; if (updatetmpptr!=NULL) obj=updateObj(updatetmpptr);if (obj<gcbaseva) tprintf("BAD PTR %x to %x in %u\n", updatetmpptr, obj, __LINE__);}
-#define UPDATEOBJ(obj) {void *updatetmpptr=obj; if (updatetmpptr!=NULL) {obj=updateObj(updatetmpptr);}}
+#define UPDATEOBJ(obj) {void *updatetmpptr=obj; if (updatetmpptr!=NULL) {obj=updateObj(updatetmpptr);if (!ISVALIDPTR(obj)) tprintf("Mapping problem for object %x -> %x, mark=%u, line=%u\n", updatetmpptr, obj, getMarkedLength(updatetmpptr),__LINE__);}}
-//if (obj==NULL) tprintf("Mapping problem for object %x, mark=%u, line=%u\n", updatetmpptr, getMarkedLength(updatetmpptr),__LINE__);}}
-
-#define UPDATEOBJNONNULL(obj) {void *updatetmpptr=obj; obj=updateObj(updatetmpptr);}
-//if (updatetmpptr!=NULL&&obj==NULL) tprintf("Mapping parameter for object %x, mark=%u, line=%u\n", updatetmpptr, getMarkedLength(updatetmpptr),__LINE__);}
+#define UPDATEOBJNONNULL(obj) {void *updatetmpptr=obj; obj=updateObj(updatetmpptr); if (!ISVALIDPTR(obj)) tprintf("Mapping parameter for object %x -> %x, mark=%u, line=%u\n", updatetmpptr, obj, getMarkedLength(updatetmpptr),__LINE__);}
INLINE void updategarbagelist(struct garbagelist *listptr) {
for(;listptr!=NULL; listptr=listptr->next) {
//Scan more carefully next
objlength=getMarkedLength(origptr);
- void *dstptr=gcmappingtbl[OBJMAPPINGINDEX(origptr)];
if (objlength!=NOTMARKED) {
+ void *dstptr=gcmappingtbl[OBJMAPPINGINDEX(origptr)];
unsigned int length=ALIGNSIZETOBYTES(objlength);
void *endtoptr=dstptr+length;
- if (endtoptr>tobound||endtoptr<tobase) {
+ if (endtoptr>tobound||dstptr<tobase) {
//get use the next block of memory
orig->ptr=origptr;
return dstptr;
}
/* Move the object */
- if(origptr <= endtoptr) {
+ if(origptr >= endtoptr||dstptr >= origptr+length) {
memmove(dstptr, origptr, length);
} else if (origptr!=dstptr) {
//no need to copy if the source & dest are equal....
}
//tprintf("Moving object %x to %x with length %u\n", origptr, dstptr, length);
-
+
/* Update the pointers in the object */
updatePtrsInObj(dstptr);
-
/* Clear the mark */
clearMark(origptr);
-
+
//good to move objects and update pointers
origptr+=length;
} else
origptr+=ALIGNMENTSIZE;
}
+ orig->ptr=origptr;
+ return NULL;
}
void updateOrigPtr(void *currtop) {
//increment the core
orig->localblocknum++;
BASEPTR(orig->base,BAMBOO_NUM_OF_CORE, orig->localblocknum);
- update_origblockptr=orig->base;
orig->ptr=orig->base;
orig->bound = orig->base + BLOCKSIZE(orig->localblocknum);
if (orig->base >= gcbaseva+BAMBOO_SHARED_MEM_SIZE) {
- //free our entire memory for others to use
break;
}
}
#endif
if(islarge) {
// ptr is a large object and not marked or enqueued
- printf("NEED TO SUPPORT LARGE OBJECTS!\n");
+ printf("NEED TO SUPPORT LARGE OBJECTS: ptr=%x type=%u size=%u!\n", ptr, type, size);
} else {
// ptr is an unmarked active object on this core
unsigned int isize=iunits<<ALIGNMENTSHIFT;
int * allocsize) {
for(block_t localblocknum=0;localblocknum<GCNUMLOCALBLOCK;localblocknum++) {
block_t searchblock=BLOCKINDEX2(coren, localblocknum);
+ if (searchblock>=GCNUMBLOCK)
+ return NULL;
struct blockrecord * block=&allocationinfo.blocktable[searchblock];
if (block->status==BS_FREE) {
unsigned INTPTR freespace=block->freespace&~BAMBOO_CACHE_LINE_MASK;
return mem;
//failed try neighbors...in a round robin fashion
-
for(block_t lblock=0;lblock<MAXNEIGHBORALLOC;lblock++) {
for(int i=0;i<NUM_CORES2TEST;i++) {
- int neighborcore=core2test[corenum][i];
+ int neighborcore=core2test[coren][i];
if (neighborcore!=-1) {
block_t globalblockindex=BLOCKINDEX2(neighborcore, lblock);
+ if (globalblockindex>=GCNUMBLOCK)
+ return NULL;
struct blockrecord * block=&allocationinfo.blocktable[globalblockindex];
if (block->status==BS_FREE) {
unsigned INTPTR freespace=block->freespace&~BAMBOO_CACHE_LINE_MASK;
- if (memcheck<=freespace) {
+ if (freespace>=memcheck) {
//we have a block
//mark block as used
block->status=BS_USED;
}
}
}
-
//no memory
return NULL;
}
void * globalmalloc_I(int coren, unsigned INTPTR memcheck, int * allocsize) {
block_t firstfree=NOFREEBLOCK;
block_t lowestblock=allocationinfo.lowestfreeblock;
-
for(block_t searchblock=lowestblock;searchblock<GCNUMBLOCK;searchblock++) {
struct blockrecord * block=&allocationinfo.blocktable[searchblock];
if (block->status==BS_FREE) {
#ifdef GC_DEBUG
#include "structdefs.h"
-#define BAMBOO_NUM_BLOCKS (NUMCORES4GC*(2+1)+3)
+#define BAMBOO_NUM_BLOCKS (NUMCORES4GC*(2+3))
#define BAMBOO_PAGE_SIZE (64 * 64)
#define BAMBOO_SMEM_SIZE ((unsigned int)(BAMBOO_PAGE_SIZE))
#define BAMBOO_SHARED_MEM_SIZE ((unsigned int)((BAMBOO_SMEM_SIZE) *(BAMBOO_NUM_BLOCKS)))
int index=0;
for(int x=xcoord-1;x<=(xcoord+1);x++) {
for(int y=ycoord-1;y<=(ycoord+1);y++) {
+ if (x==xcoord&&y==ycoord)
+ continue;
+
if ((x<0||x>7)||(y<0||y>7)) {
//bad coordinate
core2test[i][index]=-1;
void processmsg_gcstartpre_I() {
// the first time to be informed to start gc
gcflag = true;
- // 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_smem_size = 0;
- bamboo_cur_msp = NULL;
- smemflag = true;
}
void processmsg_gcstartinit_I() {
// initialize runtime data structures
initruntimedata();
initCommunication();
-
if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
numconfirm=NUMCORES-1;
for(int i=0;i<NUMCORES;i++) {