diff options
author | Simon Marlow <marlowsd@gmail.com> | 2012-05-01 11:57:56 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2012-05-03 08:46:31 +0100 |
commit | 8dda2dfb3d1e668e9e1323d2534151069ca099e5 (patch) | |
tree | 1e0f05177a7916d3dd332e5dfe320031f8989c95 | |
parent | 4100b7500c59faf8848115d76067d74ba0d90c21 (diff) | |
download | haskell-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.hs | 22 |
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. |