1 m#ifndef BAMBOO_MULTICORE_GARBAGE_H
2 #define BAMBOO_MULTICORE_GARBAGE_H
5 #include "multicoregc.h"
6 #include "multicorehelper.h" // for mappings between core # and block #
7 #include "structdefs.h"
8 #include "multicoregcprofile.h"
11 #define GC_PRINTF tprintf
13 #define GC_PRINTF if(0) tprintf
16 // data structures for GC
17 #define BAMBOO_SMEM_SIZE_L (BAMBOO_SMEM_SIZE * 2)
18 #define BAMBOO_LARGE_SMEM_BOUND (BAMBOO_SMEM_SIZE_L*NUMCORES4GC)
19 // let each gc core to have one big block, this is very important
20 // for the computation of NUMBLOCKS(s, n), DO NOT change this!
23 INITPHASE = 0x0, // 0x0
26 SUBTLECOMPACTPHASE, // 0x3
29 CACHEPOLICYPHASE, // 0x6
30 PREFINISHPHASE, // 0x7
34 typedef struct gc_status {
35 volatile bool gcprocessing;
36 volatile GCPHASETYPE gcphase; // indicating GC phase
37 volatile bool gcbusystatus;
40 extern volatile bool gcflag;
41 extern gc_status_t gc_status_info;
42 volatile bool gcprecheck; // indicates if there are updated pregc information
44 unsigned INTPTR gccurr_heaptop;
45 struct MGCHash * gcforwardobjtbl; // cache forwarded objs in mark phase
46 // for mark phase termination
47 volatile unsigned int gccorestatus[NUMCORESACTIVE];//records status of each core
50 volatile unsigned int gcnumsendobjs[2][NUMCORESACTIVE];//# of objects sent out
51 volatile unsigned int gcnumreceiveobjs[2][NUMCORESACTIVE];//# of objects received
52 volatile unsigned int gcnumsrobjs_index;//indicates which entry to record the
53 // info received before phase 1 of the mark finish
55 // the info received in phase 2 must be
56 // recorded in the other entry
58 unsigned int gcself_numsendobjs;
59 unsigned int gcself_numreceiveobjs;
62 unsigned int gcheaptop;
63 unsigned INTPTR gcloads[NUMCORES4GC];
64 unsigned INTPTR numblockspercore;
66 //Top of each core's heap
67 void * topptrs[NUMCORES4GC];
69 // compact instruction
70 //keep track of what block we can fill to
71 unsigned int gcblock2fill;
74 //this points to memory handed to core from master
75 volatile unsigned int gcmovestartaddr;
76 //this flag tells core that it is okay to start compacting
77 volatile bool gctomove;
79 //keeps track of memory request master was not able to serve
80 unsigned int gcrequiredmems[NUMCORES4GC]; //record pending mem requests
81 volatile unsigned int gcmovepending;
83 // shared memory pointer for pointer mapping tbls
84 // In GC version, this block of memory is located at the bottom of the
85 // shared memory, right on the top of the smem tbl.
86 // The bottom of the shared memory = sbstart tbl + smemtbl + bamboo_rmsp
87 // These three types of table are always reside at the bottom of the shared
88 // memory and will never be moved or garbage collected
89 //gcmappingtable gives new pointer location
91 //number of bytes in mapping table
92 unsigned int bamboo_rmsp_size;
94 //mark table....keep track of mark bits
95 unsigned int * gcmarktbl;
97 void * gcbaseva; // base va for shared memory without reserved sblocks
99 /* Structure to keep track of free space in block */
101 /* BS_INIT indicates that we don't have information for this block yet */
103 /* BS_LARGEOBJECT indicates that the beginning of this block has a large object*/
105 /* BS_FREE indicates that the block is at least partially free */
110 enum blockstatus status;
111 unsigned INTPTR usedspace;
112 unsigned int corenum;
116 #define NOFREEBLOCK 0xffffffff
118 unsigned int lowestfreeblock;
119 struct blockrecord * blocktable;
122 struct allocrecord allocationinfo;
124 #ifdef GC_CACHE_ADAPT
125 void * gctopva; // top va for shared memory without reserved sblocks
126 volatile bool gccachestage;
127 // table recording the sampling data collected for cache adaption
128 int * gccachesamplingtbl;
129 int * gccachesamplingtbl_local;
130 unsigned int size_cachesamplingtbl_local;
131 int * gccachesamplingtbl_r;
132 int * gccachesamplingtbl_local_r;
133 unsigned int size_cachesamplingtbl_local_r;
134 int * gccachepolicytbl;
135 unsigned int size_cachepolicytbl;
138 /* Total number of blocks in heap */
140 #define GCNUMBLOCK (NUMCORES4GC+(BAMBOO_SHARED_MEM_SIZE-BAMBOO_LARGE_SMEM_BOUND)/BAMBOO_SMEM_SIZE)
141 #define GCNUMLOCALBLOCK (GCNUMBLOCK/NUMCORES4GC)
143 /* This macro waits for the given gc phase */
144 #define WAITFORGCPHASE(phase) while(gc_status_info.gcphase != phase) ;
146 /* Local block number that can never be reached...*/
147 #define MAXBLOCK 0x4fffffff
149 //Takes in pointer to heap object and converts to offset in alignment units
150 #define OBJMAPPINGINDEX(p) ALIGNOBJSIZE((unsigned INTPTR)(p-gcbaseva))
152 //Converts size of object into alignment units (need to round up)
153 #define ALIGNUNITS(s) (((s-1)>>ALIGNMENTSHIFT)+1)
155 //Rounds object size up to next alignment unit size
156 #define ALIGNSIZE(s) ((((unsigned int)(s-1))&~(ALIGNMENTBYTES-1))+ALIGNMENTBYTES)
158 #define GLOBALBLOCK2LOCAL(s) (s/NUMCORES4GC)
160 // mapping of pointer to block # (start from 0), here the block # is
162 #define BLOCKINDEX(b, p) \
164 unsigned INTPTR t = (unsigned INTPTR)(p - gcbaseva); \
165 if(t < BAMBOO_LARGE_SMEM_BOUND) { \
166 b = t / BAMBOO_SMEM_SIZE_L; \
168 b = NUMCORES4GC+((t-BAMBOO_LARGE_SMEM_BOUND)/BAMBOO_SMEM_SIZE); \
172 #define RESIDECORE(c, p) { \
173 if(1 == (NUMCORES4GC)) { \
178 c = gc_block2core[(b%(NUMCORES4GC*2))]; \
182 INLINE static unsigned int hostcore(void * ptr) {
183 // check the host core of ptr
185 RESIDECORE(host, ptr);
189 /*This macro takes in a number of bytes (the current offset into the
190 heap) and returns the number of local blocks needed for that many
193 #define NUMBLOCKS(s, n) \
194 if(s < (BAMBOO_SMEM_SIZE_L)) { \
197 (n) = 1 + ((s) - (BAMBOO_SMEM_SIZE_L)) / (BAMBOO_SMEM_SIZE); \
200 //this macro takes in a global block identifier and returns the base
201 //offset into the heap
202 #define OFFSET2BASEVA(i) \
203 (((i)<NUMCORES4GC)?(BAMBOO_SMEM_SIZE_L*(i)):(BAMBOO_SMEM_SIZE*((i)-NUMCORES4GC)+BAMBOO_LARGE_SMEM_BOUND))
206 //This macro takes in a local block number and returns the size of the block
207 #define BLOCKSIZE(c) \
208 ((c)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE)
210 //Takes as input the core number c and the local block index n and
211 //returns the global block index
213 #define BLOCKINDEX2(c, n) \
214 (gc_core2block[2*(c)+((n)&1)]+(NUMCORES4GC*2)*((n)>>1))
216 //This macro takes in a global block number and returns the base
217 //pointer of the next block
218 #define BOUNDPTR(b) \
219 (((b)<NUMCORES4GC)?(((b)+1)*BAMBOO_SMEM_SIZE_L):(BAMBOO_LARGE_SMEM_BOUND+((b)-NUMCORES4GC+1)*BAMBOO_SMEM_SIZE))
221 //This macro takes in the core number c and the local block number and
222 //sets p to the base pointer
224 #define BASEPTR(p, c, n) { \
225 unsigned int b = BLOCKINDEX2((c), (n)); \
226 if(b < (NUMCORES4GC)) { \
227 p = gcbaseva + b * (BAMBOO_SMEM_SIZE_L); \
229 p = gcbaseva+(BAMBOO_LARGE_SMEM_BOUND)+ \
230 (b-(NUMCORES4GC))*(BAMBOO_SMEM_SIZE); \
234 // the next core in the top of the heap
235 #define NEXTTOPCORE(b) (gc_block2core[((b)+1)%(NUMCORES4GC*2)])
237 // check if all cores are stall now
238 #define GC_CHECK_ALL_CORE_STATUS(f) \
240 gccorestatus[BAMBOO_NUM_OF_CORE] = 0; \
242 if(gc_checkAllCoreStatus()) { \
248 // send a 1-word msg to all clients
249 #define GC_SEND_MSG_1_TO_CLIENT(m) \
251 for(int i = 0; i < NUMCORESACTIVE; ++i) { \
252 gccorestatus[i] = 1; \
253 if(BAMBOO_NUM_OF_CORE != i) { \
254 send_msg_1(i, (m)); \
259 #define ISLOCAL(p) (hostcore(p)==BAMBOO_NUM_OF_CORE)
261 void initmulticoregcdata();
262 void dismulticoregcdata();
263 bool gc_checkAllCoreStatus();
264 bool gc(struct garbagelist * stackptr); // core coordinator routine
265 void gc_collect(struct garbagelist* stackptr); //core collector routine
266 void gc_nocollect(struct garbagelist* stackptr); //non-gc core collector routine
267 void master_mark(struct garbagelist *stackptr);
268 void master_getlargeobjs();
269 void master_compact();
270 void master_updaterefs();
271 void master_finish();
272 void gc_master(struct garbagelist * stackptr);
275 void transferMarkResults_I();
276 void * gcfindSpareMem_I(unsigned int requiredmem,unsigned int requiredcore);
278 #define INITMULTICOREGCDATA() initmulticoregcdata()
279 #define DISMULTICOREGCDATA() dismulticoregcdata()
280 #else // MULTICORE_GC
281 #define INITMULTICOREGCDATA()
282 #define DISMULTICOREGCDATA()
283 #endif // MULTICORE_GC
284 #endif // BAMBOO_MULTICORE_GARBAGE_H