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