#include "pmc_forward.h"
+void pmc_count() {
+ for(int i=0;i<NUMPMCUNITS;i++) {
+ if (!tmc_spin_mutex_trylock(&pmc_heapptr->units[i].lock)) {
+ //got lock
+ void *unitbase=gcbaseva+i*UNITSIZE;
+ void *unittop=unitbase+UNITSIZE;
+ pmc_countbytes(&pmc_heapptr->unit[i], unitbase, unittop);
+ }
+ }
+}
//Comment: should build dummy byte arrays to allow skipping data...
-void pmc_countbytes(struct pmc_region * region, void *bottomptr, void *topptr) {
+void pmc_countbytes(struct pmc_unit * unit, void *bottomptr, void *topptr) {
void *tmpptr=bottomptr;
unsigned int totalbytes=0;
while(tmpptr<topptr) {
totalbytes+=size;
tmpptr+=size;
}
- region->numbytes=totalbytes;
+ unit->numbytes=totalbytes;
+}
+
+void pmc_processunits() {
+ unsigned int livebytes=0;
+ for(int i=0;i<NUMPMCUNITS;i++) {
+ livebytes+=pmc_heapptr->units[i].numbytes;
+ }
+ //make sure to round up
+ unsigned int livebytespercore=((livebytes-1)/NUMCORES4GC)+1;
+ unsigned int regionnum=0;
+ int totalbytes=0;
+ int numregions=0;
+
+ for(int i=0;i<NUMPMCUNITS;i++) {
+ if (numregions>0&&(totalbytes+pmc_heapptr->units[i].numbytes)>livebytespercore) {
+ regionnum++;
+ totalbytes-=livebytespercore;
+ numregions=0;
+ }
+ numregions++;
+ pmc_heapptr->units[i].regionnum=regionnum;
+ tmc_spin_mutex_init(&pmc_heapptr->units[i].lock);
+ totalbytes+=pmc_heapptr->units[i].numbytes;
+ }
}
#include "pmc_garbage.h"
+struct pmc_queue * pmc_localqueue;
+
void incrementthreads() {
tmc_spin_mutex_lock(&pmc_heapptr->lock);
pmc_heapptr->numthreads++;
pmc_heapptr->numthreads--;
tmc_spin_mutex_unlock(&pmc_heapptr->lock);
}
+
+void pmc_onceInit() {
+ pmc_localqueue=&pmc_heapptr->regions[BAMBOO_NUM_OF_THREADS].markqueue;
+ pmc_queueinit(pmc_localqueue);
+ tmc_spin_barrier_init(&pmc_heapptr->barrier, NUMCORES4GC);
+}
+
+void pmc_init() {
+ if (BAMBOO_NUM_OF_THREADS==STARTUPCORE) {
+ pmc_heapptr->numthreads=NUMCORES4GC;
+ }
+ tmc_spin_barrier_wait(&pmc_heapptr->barrier);
+}
+
+void gc(struct garbagelist *gl) {
+ pmc_init();
+ pmc_mark(gl);
+ pmc_count();
+ tmc_spin_barrier_wait(&pmc_heapptr->barrier);
+ if (BAMBOO_NUM_OF_THREADS==STARTUPCORE) {
+ pmc_processunits();
+ }
+ tmc_spin_barrier_wait(&pmc_heapptr->barrier);
+
+}
#define PMC_GARBAGE_H
#include <tmc/spin.h>
+#define NUMPMCUNITS (4*NUMCORES4GC)
+#define UNITSIZE (BAMBOO_SHARED_MEM_SIZE/NUMPMCUNITS)
+
struct pmc_unit {
tmc_spin_mutex_t lock;
unsigned int numbytes;
+ unsigned int regionnum;
};
struct pmc_region {
};
struct pmc_heap {
- struct pmc_region units[NUMCORES4GC*4];
+ struct pmc_region units[NUMPMCUNITS];
struct pmc_region regions[NUMCORES4GC];
tmc_spin_mutex_t lock;
volatile unsigned int numthreads;
};
extern struct pmc_heap * pmc_heapptr;
+extern struct pmc_queue * pmc_localqueue;
void incrementthreads();
-void decrementthreads() {
+void decrementthreads();
+void pmc_onceInit();
+void pmc_init();
#endif
#include "pmc_queue.h"
-void pmc_init(struct pmc_queue *queue) {
+void pmc_queueinit(struct pmc_queue *queue) {
queue->head=queue->tail=RUNMALLOC(struct pmc_queue_segment);
queue->headindex=queue->tailindex=0;
}
volatile int headindex;
volatile int tailindex;
tmc_spin_mutex_t lock;
+ tmc_spin_barrier_t barrier;
};
void * pmc_dequeue(struct pmc_queue *queue);
void pmc_enqueue(struct pmc_queue* queue, void *ptr);
bool pmc_isEmpty(struct pmc_queue *queue);
-void pmc_init(struct pmc_queue *queue);
+void pmc_queueinit(struct pmc_queue *queue);
#endif