summaryrefslogtreecommitdiff
path: root/rts/Globals.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2009-11-11 14:28:22 +0000
committerSimon Marlow <marlowsd@gmail.com>2009-11-11 14:28:22 +0000
commit2d5e052d795c99c17b1ca6fa1ca8be7d082be09c (patch)
tree6eabbfd2ceeb75f8c481d1872e46fa3c6b88bf9d /rts/Globals.c
parentcd0e2c0cc3005c3f5e74eeda57dc9cebbe1bac7e (diff)
downloadhaskell-2d5e052d795c99c17b1ca6fa1ca8be7d082be09c.tar.gz
Second attempt to fix #1185 (forkProcess and -threaded)
Patch 1/2: second part of the patch is to libraries/base This time without dynamic linker hacks, instead I've expanded the existing rts/Globals.c to cache more CAFs, specifically those in GHC.Conc. We were already using this trick for signal handlers, I should have realised before. It's still quite unsavoury, but we can do away with rts/Globals.c in the future when we switch to a dynamically-linked GHCi.
Diffstat (limited to 'rts/Globals.c')
-rw-r--r--rts/Globals.c92
1 files changed, 61 insertions, 31 deletions
diff --git a/rts/Globals.c b/rts/Globals.c
index 15b10130a8..00d911ac56 100644
--- a/rts/Globals.c
+++ b/rts/Globals.c
@@ -7,6 +7,9 @@
* even when multiple versions of the library are loaded. e.g. see
* Data.Typeable and GHC.Conc.
*
+ * If/when we switch to a dynamically-linked GHCi, this can all go
+ * away, because there would be just one copy of each library.
+ *
* ---------------------------------------------------------------------------*/
#include "PosixSource.h"
@@ -15,18 +18,29 @@
#include "Globals.h"
#include "Stable.h"
-static StgStablePtr typeableStore = 0;
-static StgStablePtr signalHandlerStore = 0;
+typedef enum {
+ TypeableStore,
+ GHCConcSignalHandlerStore,
+ GHCConcPendingEventsStore,
+ GHCConcPendingDelaysStore,
+ GHCConcIOManagerThreadStore,
+ GHCConcProddingStore,
+ MaxStoreKey
+} StoreKey;
#ifdef THREADED_RTS
Mutex globalStoreLock;
#endif
+StgStablePtr store[MaxStoreKey];
+
void
initGlobalStore(void)
{
- typeableStore = 0;
- signalHandlerStore = 0;
+ nat i;
+ for (i=0; i < MaxStoreKey; i++) {
+ store[i] = 0;
+ }
#ifdef THREADED_RTS
initMutex(&globalStoreLock);
#endif
@@ -35,53 +49,69 @@ initGlobalStore(void)
void
exitGlobalStore(void)
{
+ nat i;
#ifdef THREADED_RTS
closeMutex(&globalStoreLock);
#endif
- if(typeableStore!=0) {
- freeStablePtr((StgStablePtr)typeableStore);
- typeableStore=0;
- }
- if(signalHandlerStore!=0) {
- freeStablePtr((StgStablePtr)signalHandlerStore);
- signalHandlerStore=0;
+ for (i=0; i < MaxStoreKey; i++) {
+ if (store[i] != 0) {
+ freeStablePtr(store[i]);
+ store[i] = 0;
+ }
}
}
-StgStablePtr
-getOrSetTypeableStore(StgStablePtr ptr)
+static StgStablePtr getOrSetKey(StoreKey key, StgStablePtr ptr)
{
- StgStablePtr ret = typeableStore;
+ StgStablePtr ret = store[key];
if(ret==0) {
#ifdef THREADED_RTS
ACQUIRE_LOCK(&globalStoreLock);
- ret=typeableStore;
+ ret = store[key];
if(ret==0) {
#endif
- typeableStore = ret = ptr;
+ store[key] = ret = ptr;
#ifdef THREADED_RTS
}
RELEASE_LOCK(&globalStoreLock);
#endif
}
return ret;
+}
+
+
+StgStablePtr
+getOrSetTypeableStore(StgStablePtr ptr)
+{
+ return getOrSetKey(TypeableStore,ptr);
}
StgStablePtr
-getOrSetSignalHandlerStore(StgStablePtr ptr)
+getOrSetGHCConcSignalHandlerStore(StgStablePtr ptr)
{
- StgStablePtr ret = signalHandlerStore;
- if(ret==0) {
-#ifdef THREADED_RTS
- ACQUIRE_LOCK(&globalStoreLock);
- ret=signalHandlerStore;
- if(ret==0) {
-#endif
- signalHandlerStore = ret = ptr;
-#ifdef THREADED_RTS
- }
- RELEASE_LOCK(&globalStoreLock);
-#endif
- }
- return ret;
+ return getOrSetKey(GHCConcSignalHandlerStore,ptr);
+}
+
+StgStablePtr
+getOrSetGHCConcPendingEventsStore(StgStablePtr ptr)
+{
+ return getOrSetKey(GHCConcPendingEventsStore,ptr);
+}
+
+StgStablePtr
+getOrSetGHCConcPendingDelaysStore(StgStablePtr ptr)
+{
+ return getOrSetKey(GHCConcPendingDelaysStore,ptr);
+}
+
+StgStablePtr
+getOrSetGHCConcIOManagerThreadStore(StgStablePtr ptr)
+{
+ return getOrSetKey(GHCConcIOManagerThreadStore,ptr);
+}
+
+StgStablePtr
+getOrSetGHCConcProddingStore(StgStablePtr ptr)
+{
+ return getOrSetKey(GHCConcProddingStore,ptr);
}