643251995e5c2a9c74f5f8dfa978b7a71151cb1f
[packages/base.git] / GHC / Event / Unique.hs
1 {-# LANGUAGE Unsafe #-}
2 {-# LANGUAGE BangPatterns, GeneralizedNewtypeDeriving, NoImplicitPrelude #-}
3 module GHC.Event.Unique
4 (
5 UniqueSource
6 , Unique(..)
7 , newSource
8 , newUnique
9 ) where
10
11 import Data.Int (Int64)
12 import GHC.Base
13 import GHC.Conc.Sync (TVar, atomically, newTVarIO, readTVar, writeTVar)
14 import GHC.Num (Num(..))
15 import GHC.Show (Show(..))
16
17 -- We used to use IORefs here, but Simon switched us to STM when we
18 -- found that our use of atomicModifyIORef was subject to a severe RTS
19 -- performance problem when used in a tight loop from multiple
20 -- threads: http://hackage.haskell.org/trac/ghc/ticket/3838
21 --
22 -- There seems to be no performance cost to using a TVar instead.
23
24 newtype UniqueSource = US (TVar Int64)
25
26 newtype Unique = Unique { asInt64 :: Int64 }
27 deriving (Eq, Ord, Num)
28
29 instance Show Unique where
30 show = show . asInt64
31
32 newSource :: IO UniqueSource
33 newSource = US `fmap` newTVarIO 0
34
35 newUnique :: UniqueSource -> IO Unique
36 newUnique (US ref) = atomically $ do
37 u <- readTVar ref
38 let !u' = u+1
39 writeTVar ref u'
40 return $ Unique u'
41 {-# INLINE newUnique #-}