1e5b6989c5623ee1e23b77b8a047e19859b9857a
[IRC.git] / Robust / src / Runtime / bamboo / multicoregarbage.h
1 m#ifndef BAMBOO_MULTICORE_GARBAGE_H
2 #define BAMBOO_MULTICORE_GARBAGE_H
3 #ifdef MULTICORE_GC
4 #include "multicore.h"
5 #include "multicoregc.h"
6 #include "multicorehelper.h"  // for mappings between core # and block #
7 #include "structdefs.h"
8 #include "multicoregcprofile.h"
9
10 #ifdef GC_DEBUG
11 #define GC_PRINTF tprintf
12 #else
13 #define GC_PRINTF if(0) tprintf
14 #endif 
15
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!
21
22 typedef enum {
23   INITPHASE = 0x0,         // 0x0
24   MARKPHASE,               // 0x1
25   COMPACTPHASE,            // 0x2
26   SUBTLECOMPACTPHASE,      // 0x3
27   MAPPHASE,                // 0x4
28   UPDATEPHASE,             // 0x5
29   CACHEPOLICYPHASE,        // 0x6
30   PREFINISHPHASE,          // 0x7
31   FINISHPHASE              // 0x8
32 } GCPHASETYPE;
33
34 typedef struct gc_status {
35   volatile bool gcprocessing;
36   volatile GCPHASETYPE gcphase; // indicating GC phase
37   volatile bool gcbusystatus;
38 } gc_status_t;
39
40 extern volatile bool gcflag;
41 extern gc_status_t gc_status_info;
42 volatile bool gcprecheck; // indicates if there are updated pregc information
43
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
48                                                    // 1: running gc
49                                                    // 0: stall
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 
54                  // checking process
55                  // the info received in phase 2 must be 
56                  // recorded in the other entry
57
58 unsigned int gcself_numsendobjs;
59 unsigned int gcself_numreceiveobjs;
60
61 // for load balancing
62 unsigned int gcheaptop;
63 unsigned INTPTR gcloads[NUMCORES4GC];
64 unsigned INTPTR numblockspercore;
65
66 //Top of each core's heap
67 void * topptrs[NUMCORES4GC];
68
69 // compact instruction
70 //keep track of what block we can fill to
71 unsigned int gcblock2fill;
72
73 // move instruction;
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;
78
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;
82
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
90 void ** gcmappingtbl;
91 //number of bytes in mapping table
92 unsigned int bamboo_rmsp_size;
93
94 //mark table....keep track of mark bits
95 unsigned int * gcmarktbl;
96
97 void * gcbaseva; // base va for shared memory without reserved sblocks
98
99 /* Structure to keep track of free space in block */
100 enum blockstatus {
101   /* BS_INIT indicates that we don't have information for this block yet */
102   BS_INIT,
103   /* BS_LARGEOBJECT indicates that the beginning of this block has a large object*/
104   BS_LARGEOBJECT,
105   /* BS_FREE indicates that the block is at least partially free */
106   BS_FREE
107 };
108
109 struct blockrecord {
110   enum blockstatus status;
111   unsigned INTPTR usedspace;
112   unsigned int corenum;
113
114 };
115
116 #define NOFREEBLOCK 0xffffffff
117 struct allocrecord {
118   unsigned int lowestfreeblock;
119   struct blockrecord * blocktable;
120 };
121
122 struct allocrecord allocationinfo;
123
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;
136 #endif
137
138 /* Total number of blocks in heap */
139
140 #define GCNUMBLOCK (NUMCORES4GC+(BAMBOO_SHARED_MEM_SIZE-BAMBOO_LARGE_SMEM_BOUND)/BAMBOO_SMEM_SIZE)
141 #define GCNUMLOCALBLOCK (GCNUMBLOCK/NUMCORES4GC)
142
143 /* This macro waits for the given gc phase */
144 #define WAITFORGCPHASE(phase) while(gc_status_info.gcphase != phase) ;
145
146 /* Local block number that can never be reached...*/
147 #define MAXBLOCK 0x4fffffff 
148
149 //Takes in pointer to heap object and converts to offset in alignment units
150 #define OBJMAPPINGINDEX(p) ALIGNOBJSIZE((unsigned INTPTR)(p-gcbaseva))
151
152 //Converts size of object into alignment units (need to round up)
153 #define ALIGNUNITS(s) (((s-1)>>ALIGNMENTSHIFT)+1)
154
155 //Rounds object size up to next alignment unit size
156 #define ALIGNSIZE(s) ((((unsigned int)(s-1))&~(ALIGNMENTBYTES-1))+ALIGNMENTBYTES)
157
158 #define GLOBALBLOCK2LOCAL(s) (s/NUMCORES4GC)
159
160 // mapping of pointer to block # (start from 0), here the block # is
161 // the global index
162 #define BLOCKINDEX(b, p)                        \
163   {                                                             \
164     unsigned INTPTR t = (unsigned INTPTR)(p - gcbaseva);        \
165     if(t < BAMBOO_LARGE_SMEM_BOUND) {                           \
166       b = t / BAMBOO_SMEM_SIZE_L;                               \
167     } else {                                                          \
168       b = NUMCORES4GC+((t-BAMBOO_LARGE_SMEM_BOUND)/BAMBOO_SMEM_SIZE); \
169     }                                                                 \
170   }
171
172 #define RESIDECORE(c, p) {     \
173     if(1 == (NUMCORES4GC)) { \
174       c = 0; \
175     } else { \
176       unsigned INTPTR b; \
177       BLOCKINDEX(b, p);               \
178       c = gc_block2core[(b%(NUMCORES4GC*2))]; \
179     } \
180   }
181
182 INLINE static unsigned int hostcore(void * ptr) {
183   // check the host core of ptr
184   unsigned int host;
185   RESIDECORE(host, ptr);
186   return host;
187 }
188
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
191   bytes */
192
193 #define NUMBLOCKS(s, n) \
194   if(s < (BAMBOO_SMEM_SIZE_L)) { \
195     (n) = 0; \
196   } else { \
197     (n) = 1 + ((s) - (BAMBOO_SMEM_SIZE_L)) / (BAMBOO_SMEM_SIZE); \
198   }
199
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))
204
205
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)
209
210 //Takes as input the core number c and the local block index n and
211 //returns the global block index
212
213 #define BLOCKINDEX2(c, n) \
214   (gc_core2block[2*(c)+((n)&1)]+(NUMCORES4GC*2)*((n)>>1))
215
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))
220
221 //This macro takes in the core number c and the local block number and
222 //sets p to the base pointer
223
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);             \
228     } else {                                               \
229       p = gcbaseva+(BAMBOO_LARGE_SMEM_BOUND)+              \
230         (b-(NUMCORES4GC))*(BAMBOO_SMEM_SIZE);              \
231     }                                                      \
232   }
233
234 // the next core in the top of the heap
235 #define NEXTTOPCORE(b) (gc_block2core[((b)+1)%(NUMCORES4GC*2)])
236
237 // check if all cores are stall now
238 #define GC_CHECK_ALL_CORE_STATUS(f) \
239   { \
240     gccorestatus[BAMBOO_NUM_OF_CORE] = 0; \
241     while(f) { \
242       if(gc_checkAllCoreStatus()) { \
243         break; \
244       } \
245     } \
246   }
247
248 // send a 1-word msg to all clients
249 #define GC_SEND_MSG_1_TO_CLIENT(m) \
250   { \
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)); \
255       } \
256     } \
257   }
258
259 #define ISLOCAL(p) (hostcore(p)==BAMBOO_NUM_OF_CORE)
260
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);
273
274
275 void transferMarkResults_I();
276 void * gcfindSpareMem_I(unsigned int requiredmem,unsigned int requiredcore);
277
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