diff options
author | Moritz Angermann <moritz.angermann@gmail.com> | 2016-11-29 16:50:32 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2016-11-29 16:50:33 -0500 |
commit | 6f7ed1e51bf360621a3c2a447045ab3012f68575 (patch) | |
tree | f6e047df820dce2a049ead7927c1b36e95b2bfdd /compiler/utils/Util.hs | |
parent | 795f8bd460d604c792a5df8cfec937b2a74c3956 (diff) | |
download | haskell-6f7ed1e51bf360621a3c2a447045ab3012f68575.tar.gz |
Make globals use sharedCAF
The use of globals is quite painful when multiple rts are loaded, e.g.
when plugins are loaded, which bring in a second rts. The sharedCAF
appraoch was employed for the FastStringTable; I've taken the libery
to extend this to the other globals I could find.
Reviewers: rwbarton, simonmar, austin, hvr, erikd, bgamari
Reviewed By: simonmar, bgamari
Subscribers: thomie
Differential Revision: https://phabricator.haskell.org/D2575
Diffstat (limited to 'compiler/utils/Util.hs')
-rw-r--r-- | compiler/utils/Util.hs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/compiler/utils/Util.hs b/compiler/utils/Util.hs index 3104c747a1..88b5090f0a 100644 --- a/compiler/utils/Util.hs +++ b/compiler/utils/Util.hs @@ -104,6 +104,7 @@ module Util ( hSetTranslit, global, consIORef, globalM, + sharedGlobal, sharedGlobalM, -- * Filenames and paths Suffix, @@ -144,6 +145,7 @@ import qualified GHC.Stack import Control.Applicative ( liftA2 ) import Control.Monad ( liftM ) import GHC.IO.Encoding (mkTextEncoding, textEncodingName) +import GHC.Conc.Sync ( sharedCAF ) import System.IO (Handle, hGetEncoding, hSetEncoding) import System.IO.Error as IO ( isDoesNotExistError ) import System.Directory ( doesDirectoryExist, getModificationTime ) @@ -930,6 +932,28 @@ seqList :: [a] -> b -> b seqList [] b = b seqList (x:xs) b = x `seq` seqList xs b + +{- +************************************************************************ +* * + Globals and the RTS +* * +************************************************************************ + +When a plugin is loaded, it currently gets linked against a *newly +loaded* copy of the GHC package. This would not be a problem, except +that the new copy has its own mutable state that is not shared with +that state that has already been initialized by the original GHC +package. + +(Note that if the GHC executable was dynamically linked this +wouldn't be a problem, because we could share the GHC library it +links to; this is only a problem if DYNAMIC_GHC_PROGRAMS=NO.) + +The solution is to make use of @sharedCAF@ through @sharedGlobal@ +for globals that are shared between multiple copies of ghc packages. +-} + -- Global variables: global :: a -> IORef a @@ -942,6 +966,16 @@ consIORef var x = do globalM :: IO a -> IORef a globalM ma = unsafePerformIO (ma >>= newIORef) +-- Shared global variables: + +sharedGlobal :: a -> (Ptr (IORef a) -> IO (Ptr (IORef a))) -> IORef a +sharedGlobal a get_or_set = unsafePerformIO $ + newIORef a >>= flip sharedCAF get_or_set + +sharedGlobalM :: IO a -> (Ptr (IORef a) -> IO (Ptr (IORef a))) -> IORef a +sharedGlobalM ma get_or_set = unsafePerformIO $ + ma >>= newIORef >>= flip sharedCAF get_or_set + -- Module names: looksLikeModuleName :: String -> Bool |