diff options
author | Simon Marlow <marlowsd@gmail.com> | 2010-03-18 10:44:36 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2010-03-18 10:44:36 +0000 |
commit | 843fd341a530850b7a00a13aa73f05645dd228f5 (patch) | |
tree | 44413a2a9c8e1f4ab2abbbd452e7bd7023e8b7c9 /libraries/base/Data/Unique.hs | |
parent | 522a41a9cf2e9b3c147f77c1169248cdf85c8396 (diff) | |
download | haskell-843fd341a530850b7a00a13aa73f05645dd228f5.tar.gz |
change to use STM, fixing 4 things
1. there was no async exception protection
2. there was a space leak (now new value is strict)
3. using atomicModifyIORef would be slightly quicker, but can
suffer from adverse scheduling issues (see #3838)
4. also, the STM version is faster.
Diffstat (limited to 'libraries/base/Data/Unique.hs')
-rw-r--r-- | libraries/base/Data/Unique.hs | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/libraries/base/Data/Unique.hs b/libraries/base/Data/Unique.hs index 6f8c24f0e3..38c8e483bb 100644 --- a/libraries/base/Data/Unique.hs +++ b/libraries/base/Data/Unique.hs @@ -21,20 +21,20 @@ module Data.Unique ( import Prelude -import Control.Concurrent.MVar import System.IO.Unsafe (unsafePerformIO) #ifdef __GLASGOW_HASKELL__ import GHC.Base import GHC.Num +import GHC.Conc #endif -- | An abstract unique object. Objects of type 'Unique' may be -- compared for equality and ordering and hashed into 'Int'. newtype Unique = Unique Integer deriving (Eq,Ord) -uniqSource :: MVar Integer -uniqSource = unsafePerformIO (newMVar 0) +uniqSource :: TVar Integer +uniqSource = unsafePerformIO (newTVarIO 0) {-# NOINLINE uniqSource #-} -- | Creates a new object of type 'Unique'. The value returned will @@ -42,11 +42,18 @@ uniqSource = unsafePerformIO (newMVar 0) -- previous calls to 'newUnique'. There is no limit on the number of -- times 'newUnique' may be called. newUnique :: IO Unique -newUnique = do - val <- takeMVar uniqSource - let next = val+1 - putMVar uniqSource next - return (Unique next) +newUnique = atomically $ do + val <- readTVar uniqSource + let next = val+1 + writeTVar uniqSource $! val + 1 + return (Unique next) + +-- SDM (18/3/2010): changed from MVar to STM. This fixes +-- 1. there was no async exception protection +-- 2. there was a space leak (now new value is strict) +-- 3. using atomicModifyIORef would be slightly quicker, but can +-- suffer from adverse scheduling issues (see #3838) +-- 4. also, the STM version is faster. -- | Hashes a 'Unique' into an 'Int'. Two 'Unique's may hash to the -- same value, although in practice this is unlikely. The 'Int' |