Finish stable split
[ghc.git] / rts / Globals.c
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 1995-2009
4 *
5 * The RTS stores some "global" values on behalf of libraries, so that
6 * some libraries can ensure that certain top-level things are shared
7 * even when multiple versions of the library are loaded. e.g. see
8 * Data.Typeable and GHC.Conc.
9 *
10 * How are multiple versions of a library loaded? Examples:
11 *
12 * base - a statically-linked ghci has its own copy, so might libraries it
13 * dynamically loads
14 *
15 * libHSghc - a statically-linked ghc has its own copy and so will Core
16 * plugins it dynamically loads.
17 *
18 * ---------------------------------------------------------------------------*/
19
20 #include "PosixSource.h"
21 #include "Rts.h"
22
23 #include "Globals.h"
24 #include "StablePtr.h"
25
26 typedef enum {
27 GHCConcSignalSignalHandlerStore,
28 GHCConcWindowsPendingDelaysStore,
29 GHCConcWindowsIOManagerThreadStore,
30 GHCConcWindowsProddingStore,
31 SystemEventThreadEventManagerStore,
32 SystemEventThreadIOManagerThreadStore,
33 SystemTimerThreadEventManagerStore,
34 SystemTimerThreadIOManagerThreadStore,
35 LibHSghcFastStringTable,
36 LibHSghcPersistentLinkerState,
37 LibHSghcInitLinkerDone,
38 LibHSghcGlobalDynFlags,
39 LibHSghcStaticOptions,
40 LibHSghcStaticOptionsReady,
41 MaxStoreKey
42 } StoreKey;
43
44 #if defined(THREADED_RTS)
45 Mutex globalStoreLock;
46 #endif
47
48 static StgStablePtr store[MaxStoreKey];
49
50 void
51 initGlobalStore(void)
52 {
53 uint32_t i;
54 for (i=0; i < MaxStoreKey; i++) {
55 store[i] = 0;
56 }
57 #if defined(THREADED_RTS)
58 initMutex(&globalStoreLock);
59 #endif
60 }
61
62 void
63 exitGlobalStore(void)
64 {
65 uint32_t i;
66 #if defined(THREADED_RTS)
67 closeMutex(&globalStoreLock);
68 #endif
69 for (i=0; i < MaxStoreKey; i++) {
70 if (store[i] != 0) {
71 freeStablePtr(store[i]);
72 store[i] = 0;
73 }
74 }
75 }
76
77 static StgStablePtr getOrSetKey(StoreKey key, StgStablePtr ptr)
78 {
79 StgStablePtr ret = store[key];
80 if(ret==0) {
81 #if defined(THREADED_RTS)
82 ACQUIRE_LOCK(&globalStoreLock);
83 ret = store[key];
84 if(ret==0) {
85 #endif
86 store[key] = ret = ptr;
87 #if defined(THREADED_RTS)
88 }
89 RELEASE_LOCK(&globalStoreLock);
90 #endif
91 }
92 return ret;
93 }
94
95 #define mkStoreAccessor(name) \
96 StgStablePtr \
97 getOrSet##name(StgStablePtr ptr) \
98 { return getOrSetKey(name, ptr); }
99
100 mkStoreAccessor(GHCConcSignalSignalHandlerStore)
101 mkStoreAccessor(GHCConcWindowsPendingDelaysStore)
102 mkStoreAccessor(GHCConcWindowsIOManagerThreadStore)
103 mkStoreAccessor(GHCConcWindowsProddingStore)
104 mkStoreAccessor(SystemEventThreadEventManagerStore)
105 mkStoreAccessor(SystemEventThreadIOManagerThreadStore)
106 mkStoreAccessor(SystemTimerThreadEventManagerStore)
107 mkStoreAccessor(SystemTimerThreadIOManagerThreadStore)
108 mkStoreAccessor(LibHSghcFastStringTable)
109 mkStoreAccessor(LibHSghcPersistentLinkerState)
110 mkStoreAccessor(LibHSghcInitLinkerDone)
111 mkStoreAccessor(LibHSghcGlobalDynFlags)
112 mkStoreAccessor(LibHSghcStaticOptions)
113 mkStoreAccessor(LibHSghcStaticOptionsReady)