diff options
author | Simon Marlow <marlowsd@gmail.com> | 2009-11-11 14:28:22 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2009-11-11 14:28:22 +0000 |
commit | 2d5e052d795c99c17b1ca6fa1ca8be7d082be09c (patch) | |
tree | 6eabbfd2ceeb75f8c481d1872e46fa3c6b88bf9d /rts/Globals.c | |
parent | cd0e2c0cc3005c3f5e74eeda57dc9cebbe1bac7e (diff) | |
download | haskell-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.c | 92 |
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); } |