summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2012-05-01 11:57:56 +0100
committerSimon Marlow <marlowsd@gmail.com>2012-05-03 08:46:31 +0100
commit8dda2dfb3d1e668e9e1323d2534151069ca099e5 (patch)
tree1e0f05177a7916d3dd332e5dfe320031f8989c95
parent4100b7500c59faf8848115d76067d74ba0d90c21 (diff)
downloadhaskell-8dda2dfb3d1e668e9e1323d2534151069ca099e5.tar.gz
Use IORef/atomicModifyIORef instead of STM
Follows discussion on the libraries@ mailing list; see comments for rationale.
-rw-r--r--libraries/base/Data/Unique.hs22
1 files changed, 14 insertions, 8 deletions
diff --git a/libraries/base/Data/Unique.hs b/libraries/base/Data/Unique.hs
index 50bc40fce4..3443c9aaee 100644
--- a/libraries/base/Data/Unique.hs
+++ b/libraries/base/Data/Unique.hs
@@ -33,8 +33,8 @@ import System.IO.Unsafe (unsafePerformIO)
#ifdef __GLASGOW_HASKELL__
import GHC.Base
import GHC.Num
-import GHC.Conc
import Data.Typeable
+import Data.IORef
#endif
-- | An abstract unique object. Objects of type 'Unique' may be
@@ -45,8 +45,8 @@ newtype Unique = Unique Integer deriving (Eq,Ord
#endif
)
-uniqSource :: TVar Integer
-uniqSource = unsafePerformIO (newTVarIO 0)
+uniqSource :: IORef Integer
+uniqSource = unsafePerformIO (newIORef 0)
{-# NOINLINE uniqSource #-}
-- | Creates a new object of type 'Unique'. The value returned will
@@ -54,11 +54,9 @@ uniqSource = unsafePerformIO (newTVarIO 0)
-- previous calls to 'newUnique'. There is no limit on the number of
-- times 'newUnique' may be called.
newUnique :: IO Unique
-newUnique = atomically $ do
- val <- readTVar uniqSource
- let next = val+1
- writeTVar uniqSource $! next
- return (Unique next)
+newUnique = do
+ r <- atomicModifyIORef uniqSource $ \x -> let z = x+1 in (z,z)
+ r `seq` return (Unique r)
-- SDM (18/3/2010): changed from MVar to STM. This fixes
-- 1. there was no async exception protection
@@ -67,6 +65,14 @@ newUnique = atomically $ do
-- suffer from adverse scheduling issues (see #3838)
-- 4. also, the STM version is faster.
+-- SDM (30/4/2012): changed to IORef using atomicModifyIORef. Reasons:
+-- 1. STM version could not be used inside unsafePerformIO, if it
+-- happened to be poked inside an STM transaction.
+-- 2. IORef version can be used with unsafeIOToSTM inside STM,
+-- because if the transaction retries then we just get a new
+-- Unique.
+-- 3. IORef version is very slightly faster.
+
-- | Hashes a 'Unique' into an 'Int'. Two 'Unique's may hash to the
-- same value, although in practice this is unlikely. The 'Int'
-- returned makes a good hash key.