Use https links in user-facing startup and error messages
[ghc.git] / rts / StablePtr.c
1 /* -*- tab-width: 4 -*- */
2
3 /* -----------------------------------------------------------------------------
4 *
5 * (c) The GHC Team, 1998-2002
6 *
7 * Stable pointers
8 *
9 * ---------------------------------------------------------------------------*/
10
11 #include "PosixSource.h"
12 #include "Rts.h"
13 #include "RtsAPI.h"
14
15 #include "Hash.h"
16 #include "RtsUtils.h"
17 #include "Trace.h"
18 #include "StablePtr.h"
19
20 #include <string.h>
21
22 /* Comment from ADR's implementation in old RTS:
23
24 This files (together with @ghc/runtime/storage/PerformIO.lhc@ and a
25 small change in @HpOverflow.lc@) consists of the changes in the
26 runtime system required to implement "Stable Pointers". But we're
27 getting a bit ahead of ourselves --- what is a stable pointer and what
28 is it used for?
29
30 When Haskell calls C, it normally just passes over primitive integers,
31 floats, bools, strings, etc. This doesn't cause any problems at all
32 for garbage collection because the act of passing them makes a copy
33 from the heap, stack or wherever they are onto the C-world stack.
34 However, if we were to pass a heap object such as a (Haskell) @String@
35 and a garbage collection occured before we finished using it, we'd run
36 into problems since the heap object might have been moved or even
37 deleted.
38
39 So, if a C call is able to cause a garbage collection or we want to
40 store a pointer to a heap object between C calls, we must be careful
41 when passing heap objects. Our solution is to keep a table of all
42 objects we've given to the C-world and to make sure that the garbage
43 collector collects these objects --- updating the table as required to
44 make sure we can still find the object.
45
46
47 Of course, all this rather begs the question: why would we want to
48 pass a boxed value?
49
50 One very good reason is to preserve laziness across the language
51 interface. Rather than evaluating an integer or a string because it
52 {\em might\/} be required by the C function, we can wait until the C
53 function actually wants the value and then force an evaluation.
54
55 Another very good reason (the motivating reason!) is that the C code
56 might want to execute an object of sort $IO ()$ for the side-effects
57 it will produce. For example, this is used when interfacing to an X
58 widgets library to allow a direct implementation of callbacks.
59
60 One final reason is that we may want to store composite Haskell
61 values in data structures implemented in the C side. Serializing and
62 deserializing these structures into unboxed form suitable for C may
63 be more expensive than maintaining the extra layer of indirection of
64 stable pointers.
65
66 The @makeStablePointer :: a -> IO (StablePtr a)@ function
67 converts a value into a stable pointer. It is part of the @PrimIO@
68 monad, because we want to be sure we don't allocate one twice by
69 accident, and then only free one of the copies.
70
71 \begin{verbatim}
72 makeStablePtr# :: a -> State# RealWorld -> (# RealWorld, a #)
73 freeStablePtr# :: StablePtr# a -> State# RealWorld -> State# RealWorld
74 deRefStablePtr# :: StablePtr# a -> State# RealWorld ->
75 (# State# RealWorld, a #)
76 \end{verbatim}
77
78 There may be additional functions on the C side to allow evaluation,
79 application, etc of a stable pointer.
80
81 Stable Pointers are exported to the outside world as indices and not
82 pointers, because the stable pointer table is allowed to be
83 reallocated for growth. The table is never shrunk for its space to
84 be reclaimed.
85
86 Future plans for stable ptrs include distinguishing them by the
87 generation of the pointed object. See
88 http://ghc.haskell.org/trac/ghc/ticket/7670 for details.
89 */
90
91 spEntry *stable_ptr_table = NULL;
92 static spEntry *stable_ptr_free = NULL;
93 static unsigned int SPT_size = 0;
94 #define INIT_SPT_SIZE 64
95
96 /* Each time the stable pointer table is enlarged, we temporarily retain the old
97 * version to ensure dereferences are thread-safe (see Note [Enlarging the
98 * stable pointer table]). Since we double the size of the table each time, we
99 * can (theoretically) enlarge it at most N times on an N-bit machine. Thus,
100 * there will never be more than N old versions of the table.
101 */
102 #if SIZEOF_VOID_P == 4
103 #define MAX_N_OLD_SPTS 32
104 #elif SIZEOF_VOID_P == 8
105 #define MAX_N_OLD_SPTS 64
106 #else
107 #error unknown SIZEOF_VOID_P
108 #endif
109
110 static spEntry *old_SPTs[MAX_N_OLD_SPTS];
111 static uint32_t n_old_SPTs = 0;
112
113 #if defined(THREADED_RTS)
114 Mutex stable_ptr_mutex;
115 #endif
116
117 static void enlargeStablePtrTable(void);
118
119 /* -----------------------------------------------------------------------------
120 * We must lock the StablePtr table during GC, to prevent simultaneous
121 * calls to freeStablePtr().
122 * -------------------------------------------------------------------------- */
123
124 void
125 stablePtrLock(void)
126 {
127 initStablePtrTable();
128 ACQUIRE_LOCK(&stable_ptr_mutex);
129 }
130
131 void
132 stablePtrUnlock(void)
133 {
134 RELEASE_LOCK(&stable_ptr_mutex);
135 }
136
137 /* -----------------------------------------------------------------------------
138 * Initialising the table
139 * -------------------------------------------------------------------------- */
140
141 STATIC_INLINE void
142 initSpEntryFreeList(spEntry *table, uint32_t n, spEntry *free)
143 {
144 spEntry *p;
145 for (p = table + n - 1; p >= table; p--) {
146 p->addr = (P_)free;
147 free = p;
148 }
149 stable_ptr_free = table;
150 }
151
152 void
153 initStablePtrTable(void)
154 {
155 if (SPT_size > 0) return;
156 SPT_size = INIT_SPT_SIZE;
157 stable_ptr_table = stgMallocBytes(SPT_size * sizeof(spEntry),
158 "initStablePtrTable");
159 initSpEntryFreeList(stable_ptr_table,INIT_SPT_SIZE,NULL);
160
161 #if defined(THREADED_RTS)
162 initMutex(&stable_ptr_mutex);
163 #endif
164 }
165
166 /* -----------------------------------------------------------------------------
167 * Enlarging the table
168 * -------------------------------------------------------------------------- */
169
170 // Must be holding stable_ptr_mutex
171 static void
172 enlargeStablePtrTable(void)
173 {
174 uint32_t old_SPT_size = SPT_size;
175 spEntry *new_stable_ptr_table;
176
177 // 2nd and subsequent times
178 SPT_size *= 2;
179
180 /* We temporarily retain the old version instead of freeing it; see Note
181 * [Enlarging the stable pointer table].
182 */
183 new_stable_ptr_table =
184 stgMallocBytes(SPT_size * sizeof(spEntry),
185 "enlargeStablePtrTable");
186 memcpy(new_stable_ptr_table,
187 stable_ptr_table,
188 old_SPT_size * sizeof(spEntry));
189 ASSERT(n_old_SPTs < MAX_N_OLD_SPTS);
190 old_SPTs[n_old_SPTs++] = stable_ptr_table;
191
192 /* When using the threaded RTS, the update of stable_ptr_table is assumed to
193 * be atomic, so that another thread simultaneously dereferencing a stable
194 * pointer will always read a valid address.
195 */
196 stable_ptr_table = new_stable_ptr_table;
197
198 initSpEntryFreeList(stable_ptr_table + old_SPT_size, old_SPT_size, NULL);
199 }
200
201 /* Note [Enlarging the stable pointer table]
202 *
203 * To enlarge the stable pointer table, we allocate a new table, copy the
204 * existing entries, and then store the old version of the table in old_SPTs
205 * until we free it during GC. By not immediately freeing the old version
206 * (or equivalently by not growing the table using realloc()), we ensure that
207 * another thread simultaneously dereferencing a stable pointer using the old
208 * version can safely access the table without causing a segfault (see Trac
209 * #10296).
210 *
211 * Note that because the stable pointer table is doubled in size each time it is
212 * enlarged, the total memory needed to store the old versions is always less
213 * than that required to hold the current version.
214 */
215
216
217 /* -----------------------------------------------------------------------------
218 * Freeing entries and tables
219 * -------------------------------------------------------------------------- */
220
221 static void
222 freeOldSPTs(void)
223 {
224 uint32_t i;
225
226 for (i = 0; i < n_old_SPTs; i++) {
227 stgFree(old_SPTs[i]);
228 }
229 n_old_SPTs = 0;
230 }
231
232 void
233 exitStablePtrTable(void)
234 {
235 if (stable_ptr_table)
236 stgFree(stable_ptr_table);
237 stable_ptr_table = NULL;
238 SPT_size = 0;
239
240 freeOldSPTs();
241
242 #if defined(THREADED_RTS)
243 closeMutex(&stable_ptr_mutex);
244 #endif
245 }
246
247 STATIC_INLINE void
248 freeSpEntry(spEntry *sp)
249 {
250 sp->addr = (P_)stable_ptr_free;
251 stable_ptr_free = sp;
252 }
253
254 void
255 freeStablePtrUnsafe(StgStablePtr sp)
256 {
257 ASSERT((StgWord)sp < SPT_size);
258 freeSpEntry(&stable_ptr_table[(StgWord)sp]);
259 }
260
261 void
262 freeStablePtr(StgStablePtr sp)
263 {
264 stablePtrLock();
265 freeStablePtrUnsafe(sp);
266 stablePtrUnlock();
267 }
268
269 /* -----------------------------------------------------------------------------
270 * Looking up
271 * -------------------------------------------------------------------------- */
272
273 StgStablePtr
274 getStablePtr(StgPtr p)
275 {
276 StgWord sp;
277
278 stablePtrLock();
279 if (!stable_ptr_free) enlargeStablePtrTable();
280 sp = stable_ptr_free - stable_ptr_table;
281 stable_ptr_free = (spEntry*)(stable_ptr_free->addr);
282 stable_ptr_table[sp].addr = p;
283 stablePtrUnlock();
284 return (StgStablePtr)(sp);
285 }
286
287 /* -----------------------------------------------------------------------------
288 * Treat stable pointers as roots for the garbage collector.
289 * -------------------------------------------------------------------------- */
290
291 #define FOR_EACH_STABLE_PTR(p, CODE) \
292 do { \
293 spEntry *p; \
294 spEntry *__end_ptr = &stable_ptr_table[SPT_size]; \
295 for (p = stable_ptr_table; p < __end_ptr; p++) { \
296 /* Internal pointers are free slots. NULL is last in free */ \
297 /* list. */ \
298 if (p->addr && \
299 (p->addr < (P_)stable_ptr_table || p->addr >= (P_)__end_ptr)) \
300 { \
301 do { CODE } while(0); \
302 } \
303 } \
304 } while(0)
305
306 void
307 markStablePtrTable(evac_fn evac, void *user)
308 {
309 /* Since no other thread can currently be dereferencing a stable pointer, it
310 * is safe to free the old versions of the table.
311 */
312 freeOldSPTs();
313
314 FOR_EACH_STABLE_PTR(p, evac(user, (StgClosure **)&p->addr););
315 }
316
317 /* -----------------------------------------------------------------------------
318 * Thread the stable pointer table for compacting GC.
319 *
320 * Here we must call the supplied evac function for each pointer into
321 * the heap from the stable tables, because the compacting
322 * collector may move the object it points to.
323 * -------------------------------------------------------------------------- */
324
325 void
326 threadStablePtrTable( evac_fn evac, void *user )
327 {
328 FOR_EACH_STABLE_PTR(p, evac(user, (StgClosure **)&p->addr););
329 }