summaryrefslogtreecommitdiff
path: root/compiler/main
diff options
context:
space:
mode:
authorThomas Schilling <nominolo@googlemail.com>2009-08-17 00:48:19 +0000
committerThomas Schilling <nominolo@googlemail.com>2009-08-17 00:48:19 +0000
commit9f68c34843602e815e71ef68f43adc01da993672 (patch)
treeb1d54a85d4086b0ff7d48bc6e73be8e5792e15e1 /compiler/main
parentf391c6e6b04055eac8bc878af31042e103387530 (diff)
downloadhaskell-9f68c34843602e815e71ef68f43adc01da993672.tar.gz
Make access to NameCache atomic. Sometimes needs a lock.
'readBinIface' updates the name cache in a way that is hard to use with atomicModifyIORef, so this patch introduces a lock for this case. All other updates use atomicModifyIORef. Having a single lock is quite pessimistic, so it remains to be seen whether this will become a problem. In principle we only need to make sure that we do not load the same file concurrently (or that it's idempotent). In practice we also need to ensure that concurrent reads do not cancel each other out (since the new NameCache may be based on an outdated version).
Diffstat (limited to 'compiler/main')
-rw-r--r--compiler/main/HscMain.lhs3
-rw-r--r--compiler/main/HscTypes.lhs4
2 files changed, 7 insertions, 0 deletions
diff --git a/compiler/main/HscMain.lhs b/compiler/main/HscMain.lhs
index 26247b143a..fec3f6cb6b 100644
--- a/compiler/main/HscMain.lhs
+++ b/compiler/main/HscMain.lhs
@@ -115,6 +115,7 @@ import Exception
-- import MonadUtils
import Control.Monad
+import Control.Concurrent.MVar ( newMVar )
-- import System.IO
import Data.IORef
\end{code}
@@ -133,6 +134,7 @@ newHscEnv callbacks dflags
= do { eps_var <- newIORef initExternalPackageState
; us <- mkSplitUniqSupply 'r'
; nc_var <- newIORef (initNameCache us knownKeyNames)
+ ; nc_lock <- newMVar ()
; fc_var <- newIORef emptyUFM
; mlc_var <- newIORef emptyModuleEnv
; optFuel <- initOptFuelState
@@ -144,6 +146,7 @@ newHscEnv callbacks dflags
hsc_HPT = emptyHomePackageTable,
hsc_EPS = eps_var,
hsc_NC = nc_var,
+ hsc_NC_lock = nc_lock,
hsc_FC = fc_var,
hsc_MLC = mlc_var,
hsc_OptFuel = optFuel,
diff --git a/compiler/main/HscTypes.lhs b/compiler/main/HscTypes.lhs
index 05c17abeb9..962c7a3fd5 100644
--- a/compiler/main/HscTypes.lhs
+++ b/compiler/main/HscTypes.lhs
@@ -164,6 +164,7 @@ import Data.Array ( Array, array )
import Data.List
import Control.Monad ( mplus, guard, liftM, when )
import Exception
+import Control.Concurrent.MVar ( MVar )
\end{code}
@@ -544,6 +545,9 @@ data HscEnv
-- reflect sucking in interface files. They cache the state of
-- external interface files, in effect.
+ hsc_NC_lock :: !(MVar ()),
+ -- ^ A lock used for updating the name cache.
+
hsc_FC :: {-# UNPACK #-} !(IORef FinderCache),
-- ^ The cached result of performing finding in the file system
hsc_MLC :: {-# UNPACK #-} !(IORef ModLocationCache),