85570d210c212440bb225c74eb9e2817f839e67a
[IRC.git] / Robust / src / Runtime / bamboo / multicoregarbage.h
1 #ifndef MULTICORE_GARBAGE_H
2 #define MULTICORE_GARBAGE_H
3 #include "multicoregc.h"
4 #include "multicorehelper.h"  // for mappins between core # and block #
5 #include "structdefs.h"
6 #include "MGCHash.h"
7 #include "GCSharedHash.h"
8 #ifdef GC_CACHE_ADAPT
9 #include "multicorecache.h"
10 #endif // GC_CACHE_ADAPT
11
12 #ifndef bool
13 #define bool int
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 #ifdef GC_FLUSH_DTLB
23 #define GC_NUM_FLUSH_DTLB 1
24 int gc_num_flush_dtlb;
25 #endif
26
27 #define NUMPTRS 100
28
29 // for GC profile
30 #ifdef GC_PROFILE
31 #define GCINFOLENGTH 100
32
33 #ifdef GC_CACHE_ADAPT
34 #define GC_PROFILE_NUM_FIELD 16
35 #else
36 #define GC_PROFILE_NUM_FIELD 15
37 #endif // GC_CACHE_ADAPT
38
39 typedef struct gc_info {
40   unsigned long long time[GC_PROFILE_NUM_FIELD];
41   int index;
42 } GCInfo;
43
44 GCInfo * gc_infoArray[GCINFOLENGTH];
45 int gc_infoIndex;
46 bool gc_infoOverflow;
47 unsigned long long gc_num_livespace;
48 unsigned long long gc_num_freespace;
49 unsigned long long gc_num_lobjspace;
50 unsigned int gc_num_lobj;
51
52 unsigned int gc_num_liveobj;
53 unsigned int gc_num_obj;
54 unsigned int gc_num_forwardobj;
55 int gc_num_profiles;
56
57 #endif // GC_PROFILE
58
59 typedef enum {
60   INIT = 0,           // 0
61   DISCOVERED = 2,     // 2
62   REMOTEM = 4,        // 4
63   MARKED = 8,         // 8
64   COMPACTED = 16,     // 16
65   FLUSHED = 32,       // 32
66   END = 33            // 33
67 } GCOBJFLAG;
68
69 typedef enum {
70   INITPHASE = 0x0,         // 0x0
71   MARKPHASE,               // 0x1
72   COMPACTPHASE,            // 0x2
73   SUBTLECOMPACTPHASE,      // 0x3
74   MAPPHASE,                // 0x4
75   FLUSHPHASE,              // 0x5
76 #ifdef GC_CACHE_ADAPT
77   PREFINISHPHASE,          // 0x6
78 #endif // GC_CACHE_ADAPT
79   FINISHPHASE              // 0x6/0x7
80 } GCPHASETYPE;
81
82 volatile bool gcflag;
83 volatile bool gcprocessing;
84 volatile GCPHASETYPE gcphase; // indicating GC phase
85
86 volatile bool gcpreinform; // counter for stopped cores
87 volatile bool gcprecheck; // indicates if there are updated pregc information
88
89 int gccurr_heaptop;
90 struct MGCHash * gcforwardobjtbl; // cache forwarded objs in mark phase
91 // for mark phase termination
92 volatile int gccorestatus[NUMCORESACTIVE]; // records status of each core
93                                            // 1: running gc
94                                            // 0: stall
95 volatile int gcnumsendobjs[2][NUMCORESACTIVE]; // the # of objects sent out
96 volatile int gcnumreceiveobjs[2][NUMCORESACTIVE]; // the # of objects received
97 volatile int gcnumsrobjs_index;  // indicates which entry to record the info 
98                                          // received before phase 1 of the mark finish 
99                                                          // checking process
100                                                                  // the info received in phase 2 must be 
101                                                                  // recorded in the other entry
102 volatile bool gcbusystatus;
103 int gcself_numsendobjs;
104 int gcself_numreceiveobjs;
105
106 // for load balancing
107 INTPTR gcheaptop;
108 int gcloads[NUMCORES4GC];
109 int gctopcore; // the core host the top of the heap
110 int gctopblock; // the number of current top block
111
112 int gcnumlobjs;
113
114 // compact instruction
115 INTPTR gcmarkedptrbound;
116 int gcblock2fill;
117 int gcstopblock[NUMCORES4GC]; // indicate when to stop compact phase
118 int gcfilledblocks[NUMCORES4GC]; //indicate how many blocks have been fulfilled
119 // move instruction;
120 INTPTR gcmovestartaddr;
121 int gcdstcore;
122 volatile bool gctomove;
123 int gcrequiredmems[NUMCORES4GC]; //record pending mem requests
124 volatile int gcmovepending;
125
126 // shared memory pointer for shared pointer mapping tbls
127 // In GC version, this block of memory is located at the bottom of the 
128 // shared memory, right on the top of the smem tbl.
129 // The bottom of the shared memory = sbstart tbl + smemtbl 
130 //                                  + NUMCORES4GC bamboo_rmsp
131 // These three types of table are always reside at the bottom of the shared 
132 // memory and will never be moved or garbage collected
133 #ifdef GC_SMALLPAGESIZE
134 #define BAMBOO_RMSP_SIZE (1024 * 1024)
135 #else
136 #define BAMBOO_RMSP_SIZE (BAMBOO_SMEM_SIZE) // (45 * 16 * 1024)
137 #endif
138 mspace bamboo_rmsp;
139 // shared pointer mapping tbl
140 mgcsharedhashtbl_t * gcsharedptbl;
141 // remote shared pointer tbls
142 mgcsharedhashtbl_t * gcrpointertbls[NUMCORES4GC];
143
144 #ifdef LOCALHASHTBL_TEST
145 struct RuntimeHash * gcpointertbl;
146 #else
147 mgchashtable_t * gcpointertbl;
148 #endif
149 int gcobj2map;
150 int gcmappedobj;
151 volatile bool gcismapped;
152
153 // table recording the starting address of each small block
154 // (size is BAMBOO_SMEM_SIZE)
155 // Note: 1. this table always resides on the very bottom of the shared memory
156 //       2. it is not counted in the shared heap, would never be garbage 
157 //          collected
158 INTPTR * gcsbstarttbl;
159 int gcreservedsb;  // number of reserved sblock for sbstarttbl
160 int gcnumblock; // number of total blocks in the shared mem
161 int gcbaseva; // base va for shared memory without reserved sblocks
162 #ifdef GC_CACHE_ADAPT
163 int gctopva; // top va for shared memory without reserved sblocks
164 volatile bool gccachestage;
165 // table recording the sampling data collected for cache adaption 
166 unsigned int * gccachesamplingtbl;
167 unsigned int * gccachesamplingtbl_local;
168 unsigned int size_cachesamplingtbl_local;
169 unsigned int * gccachesamplingtbl_r;
170 unsigned int * gccachesamplingtbl_local_r;
171 unsigned int size_cachesamplingtbl_local_r;
172 int * gccachepolicytbl;
173 unsigned int size_cachepolicytbl;
174 #endif // GC_CACHE_ADAPT
175
176 #define ISSHAREDOBJ(p) \
177   ((((int)p)>gcbaseva)&&(((int)p)<(gcbaseva+(BAMBOO_SHARED_MEM_SIZE))))
178
179 #define ALIGNSIZE(s, as) \
180   (*((int*)as)) = (((s) & (~(BAMBOO_CACHE_LINE_MASK))) + (BAMBOO_CACHE_LINE_SIZE))
181
182 // mapping of pointer to block # (start from 0), here the block # is
183 // the global index
184 #define BLOCKINDEX(p, b) \
185   { \
186     int t = (p) - gcbaseva; \
187     if(t < (BAMBOO_LARGE_SMEM_BOUND)) { \
188       (*((int*)b)) = t / (BAMBOO_SMEM_SIZE_L); \
189     } else { \
190       (*((int*)b)) = NUMCORES4GC+((t-(BAMBOO_LARGE_SMEM_BOUND))/(BAMBOO_SMEM_SIZE)); \
191     } \
192   }
193
194 // mapping of pointer to core #
195 #define RESIDECORE(p, c) \
196   { \
197     if(1 == (NUMCORES4GC)) { \
198       (*((int*)c)) = 0; \
199     } else { \
200       int b; \
201       BLOCKINDEX((p), &b); \
202       (*((int*)c)) = gc_block2core[(b%(NUMCORES4GC*2))]; \
203     } \
204   }
205
206 // NOTE: n starts from 0
207 // mapping of heaptop (how many bytes there are in the local heap) to
208 // the number of the block
209 // the number of the block indicates that the block is the xth block on
210 // the local heap
211 #define NUMBLOCKS(s, n) \
212   if(s < (BAMBOO_SMEM_SIZE_L)) { \
213     (*((int*)(n))) = 0; \
214   } else { \
215     (*((int*)(n))) = 1 + ((s) - (BAMBOO_SMEM_SIZE_L)) / (BAMBOO_SMEM_SIZE); \
216   }
217
218 #define OFFSET(s, o) \
219   if(s < BAMBOO_SMEM_SIZE_L) { \
220     (*((int*)(o))) = (s); \
221   } else { \
222     (*((int*)(o))) = ((s) - (BAMBOO_SMEM_SIZE_L)) % (BAMBOO_SMEM_SIZE); \
223   }
224
225 // mapping of (core #, index of the block) to the global block index
226 #define BLOCKINDEX2(c, n) (gc_core2block[(2*(c))+((n)%2)]+((NUMCORES4GC*2)*((n)/2)))
227
228 // mapping of (core #, number of the block) to the base pointer of the block
229 #define BASEPTR(c, n, p) \
230   { \
231     int b = BLOCKINDEX2((c), (n)); \
232     if(b < (NUMCORES4GC)) { \
233       (*((int*)p)) = gcbaseva + b * (BAMBOO_SMEM_SIZE_L); \
234     } else { \
235       (*((int*)p)) = gcbaseva+(BAMBOO_LARGE_SMEM_BOUND)+ \
236                      (b-(NUMCORES4GC))*(BAMBOO_SMEM_SIZE); \
237     } \
238   }
239
240 // the next core in the top of the heap
241 #define NEXTTOPCORE(b) (gc_block2core[((b)+1)%(NUMCORES4GC*2)])
242
243 inline bool gc(struct garbagelist * stackptr); // core coordinator routine
244 inline void gc_collect(struct garbagelist* stackptr); //core collector routine
245 inline void gc_nocollect(struct garbagelist* stackptr); //non-gc core collector routine
246 inline void transferMarkResults_I();
247 inline void gc_enqueue_I(void *ptr);
248 inline void gc_lobjenqueue_I(void *ptr, int length, int host);
249 inline bool gcfindSpareMem_I(int * startaddr,
250                              int * tomove,
251                              int * dstcore,
252                              int requiredmem,
253                              int requiredcore);
254
255 inline void * gc_lobjdequeue4(int * length, int * host);
256 inline int gc_lobjmoreItems4();
257 inline void gc_lobjqueueinit4();
258
259 #ifdef GC_PROFILE
260 INLINE void gc_profileStart(void);
261 INLINE void gc_profileItem(void);
262 INLINE void gc_profileEnd(void);
263 void gc_outputProfileData();
264 #endif
265
266 #endif
267