cpp: Use #pragma once instead of #ifndef guards
[ghc.git] / rts / sm / Storage.h
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 1998-2009
4 *
5 * Storage Manger Interface
6 *
7 * ---------------------------------------------------------------------------*/
8
9 #pragma once
10
11 #include "Capability.h"
12
13 #include "BeginPrivate.h"
14
15 /* -----------------------------------------------------------------------------
16 Initialisation / De-initialisation
17 -------------------------------------------------------------------------- */
18
19 void initStorage(void);
20 void exitStorage(void);
21 void freeStorage(bool free_heap);
22
23 // Adding more Capabilities later: this function allocates nurseries
24 // and initialises other storage-related things.
25 void storageAddCapabilities (uint32_t from, uint32_t to);
26
27 /* -----------------------------------------------------------------------------
28 Should we GC?
29 -------------------------------------------------------------------------- */
30
31 INLINE_HEADER
32 bool doYouWantToGC(Capability *cap)
33 {
34 return (cap->r.rCurrentNursery->link == NULL ||
35 g0->n_new_large_words >= large_alloc_lim);
36 }
37
38 /* -----------------------------------------------------------------------------
39 The storage manager mutex
40 -------------------------------------------------------------------------- */
41
42 #if defined(THREADED_RTS)
43 extern Mutex sm_mutex;
44 #endif
45
46 #if defined(THREADED_RTS)
47 #define ACQUIRE_SM_LOCK ACQUIRE_LOCK(&sm_mutex);
48 #define RELEASE_SM_LOCK RELEASE_LOCK(&sm_mutex);
49 #define ASSERT_SM_LOCK() ASSERT_LOCK_HELD(&sm_mutex);
50 #else
51 #define ACQUIRE_SM_LOCK
52 #define RELEASE_SM_LOCK
53 #define ASSERT_SM_LOCK()
54 #endif
55
56 /* -----------------------------------------------------------------------------
57 The write barrier for MVARs and TVARs
58 -------------------------------------------------------------------------- */
59
60 void dirty_MVAR(StgRegTable *reg, StgClosure *p);
61 void dirty_TVAR(Capability *cap, StgTVar *p);
62
63 /* -----------------------------------------------------------------------------
64 Nursery manipulation
65 -------------------------------------------------------------------------- */
66
67 extern nursery *nurseries;
68 extern uint32_t n_nurseries;
69
70 void resetNurseries (void);
71 void clearNursery (Capability *cap);
72 void resizeNurseries (StgWord blocks);
73 void resizeNurseriesFixed (void);
74 StgWord countNurseryBlocks (void);
75 bool getNewNursery (Capability *cap);
76
77 /* -----------------------------------------------------------------------------
78 Allocation accounting
79
80 See [Note allocation accounting] in Storage.c
81 -------------------------------------------------------------------------- */
82
83 //
84 // Called when we are finished allocating into a block; account for the amount
85 // allocated in cap->total_allocated.
86 //
87 INLINE_HEADER void finishedNurseryBlock (Capability *cap, bdescr *bd) {
88 cap->total_allocated += bd->free - bd->start;
89 }
90
91 INLINE_HEADER void newNurseryBlock (bdescr *bd) {
92 bd->free = bd->start;
93 }
94
95 void updateNurseriesStats (void);
96 StgWord calcTotalAllocated (void);
97
98 /* -----------------------------------------------------------------------------
99 Stats 'n' DEBUG stuff
100 -------------------------------------------------------------------------- */
101
102 StgWord countOccupied (bdescr *bd);
103 StgWord calcNeeded (bool force_major, StgWord *blocks_needed);
104
105 StgWord gcThreadLiveWords (uint32_t i, uint32_t g);
106 StgWord gcThreadLiveBlocks (uint32_t i, uint32_t g);
107
108 StgWord genLiveWords (generation *gen);
109 StgWord genLiveBlocks (generation *gen);
110
111 StgWord calcTotalLargeObjectsW (void);
112 StgWord calcTotalCompactW (void);
113
114 /* ----------------------------------------------------------------------------
115 Storage manager internal APIs and globals
116 ------------------------------------------------------------------------- */
117
118 extern bdescr *exec_block;
119
120 void move_STACK (StgStack *src, StgStack *dest);
121
122 /* -----------------------------------------------------------------------------
123 Note [STATIC_LINK fields]
124
125 The low 2 bits of the static link field have the following meaning:
126
127 00 we haven't seen this static object before
128
129 01/10 if it equals static_flag, then we saw it in this GC, otherwise
130 we saw it in the previous GC.
131
132 11 ignore during GC. This value is used in two ways
133 - When we put CAFs on a list (see Note [CAF lists])
134 - a static constructor that was determined to have no CAF
135 references at compile time is given this value, so we
136 don't traverse it during GC
137
138 This choice of values is quite deliberate, because it means we can
139 decide whether a static object should be traversed during GC using a
140 single test:
141
142 bits = link_field & 3;
143 if ((bits | prev_static_flag) != 3) { ... }
144
145 -------------------------------------------------------------------------- */
146
147 #define STATIC_BITS 3
148
149 #define STATIC_FLAG_A 1
150 #define STATIC_FLAG_B 2
151 #define STATIC_FLAG_LIST 3
152
153 #define END_OF_CAF_LIST ((StgClosure*)STATIC_FLAG_LIST)
154
155 // The previous and current values of the static flag. These flip
156 // between STATIC_FLAG_A and STATIC_FLAG_B at each major GC.
157 extern uint32_t prev_static_flag, static_flag;
158
159 // In the chain of static objects built up during GC, all the link
160 // fields are tagged with the current static_flag value. How to mark
161 // the end of the chain? It must be a special value so that we can
162 // tell it is the end of the chain, but note that we're going to store
163 // this value in the link field of a static object, which means that
164 // during the NEXT GC we should treat it like any other object that
165 // has not been visited during this GC. Therefore, we use static_flag
166 // as the sentinel value.
167 #define END_OF_STATIC_OBJECT_LIST ((StgClosure*)(StgWord)static_flag)
168
169 #define UNTAG_STATIC_LIST_PTR(p) ((StgClosure*)((StgWord)(p) & ~STATIC_BITS))
170
171 /* -----------------------------------------------------------------------------
172 Note [CAF lists]
173
174 dyn_caf_list (CAFs chained through static_link)
175 This is a chain of all CAFs in the program, used for
176 dynamically-linked GHCi.
177 See Note [dyn_caf_list].
178
179 debug_caf_list (CAFs chained through saved_info)
180 A chain of all *live* CAFs in the program, that does not keep
181 the CAFs alive. Used for detecting when we enter a GC'd CAF,
182 and to give diagnostics with +RTS -DG.
183
184 revertible_caf_list (CAFs chained through static_link)
185 A chain of CAFs in object code loaded with the RTS linker.
186 These CAFs can be reverted to their unevaluated state using
187 revertCAFs.
188
189 Pointers in these lists are tagged with STATIC_FLAG_LIST, so when
190 traversing the list remember to untag each pointer with
191 UNTAG_STATIC_LIST_PTR().
192 --------------------------------------------------------------------------- */
193
194 extern StgIndStatic * dyn_caf_list;
195 extern StgIndStatic * debug_caf_list;
196 extern StgIndStatic * revertible_caf_list;
197
198 #include "EndPrivate.h"