[commit: ghc] wip/dfeuer-interleave-mvars: Switch to single-MVar unsafeInterleaveIO (aed2d85)
git at git.haskell.org
git at git.haskell.org
Wed May 3 13:48:39 UTC 2017
Repository : ssh://git@git.haskell.org/ghc
On branch : wip/dfeuer-interleave-mvars
Link : http://ghc.haskell.org/trac/ghc/changeset/aed2d85f5deacc0e9b0500eb5b1095643e536581/ghc
>---------------------------------------------------------------
commit aed2d85f5deacc0e9b0500eb5b1095643e536581
Author: David Feuer <David.Feuer at gmail.com>
Date: Wed May 3 09:47:32 2017 -0400
Switch to single-MVar unsafeInterleaveIO
Ben Gamari has pointed out that using two `MVar`s may be reducing
efficiency. Let's see what happens with an `MVar . Maybe` approach.
The next potential stage is to switch from `Maybe` to null pointers.
>---------------------------------------------------------------
aed2d85f5deacc0e9b0500eb5b1095643e536581
libraries/base/GHC/IO/Unsafe.hs | 33 ++++++++++++++++++++++-----------
1 file changed, 22 insertions(+), 11 deletions(-)
diff --git a/libraries/base/GHC/IO/Unsafe.hs b/libraries/base/GHC/IO/Unsafe.hs
index 5498e19..3c958c1 100644
--- a/libraries/base/GHC/IO/Unsafe.hs
+++ b/libraries/base/GHC/IO/Unsafe.hs
@@ -112,18 +112,29 @@ file reading, see 'System.IO.hGetContents'.
{-# INLINE unsafeInterleaveIO #-}
unsafeInterleaveIO :: IO a -> IO a
unsafeInterleaveIO m = do
- claimedV <- newEmptyMVar
- resultV <- newEmptyMVar
+ v <- newMVar Nothing
unsafeDupableInterleaveIO $ do
- claimSucceeded <- tryPutMVar claimedV ()
- if claimSucceeded
- then do
- -- We were the first ones to claim the computation, so we
- -- perform it and store the result.
- res <- m
- putMVar resultV res
- pure res
- else readMVar resultV
+ r <- tryTakeMVar v
+ case r of
+ -- Someone else has taken the MVar. By the time they put
+ -- it back, the action will surely have been performed,
+ -- so we use the result.
+ Nothing -> do
+ res <- readMVar v
+ case res of
+ Nothing -> errorWithoutStackTrace "unsafeInterleaveIO: impossible Nothing"
+ Just a -> pure a
+
+ -- Someone else has performed the action, so we use
+ -- their result and put it back in the MVar.
+ Just j@(Just r) -> r <$ putMVar v j
+
+ -- We're the first ones to get the MVar, so we actually
+ -- do the work.
+ Just Nothing -> do
+ res <- m
+ putMVar v (Just res)
+ pure res
-- Note [unsafeDupableInterleaveIO should not be inlined]
More information about the ghc-commits
mailing list