{-# LANGUAGE MagicHash, UnboxedTuples #-} -- Test the primops in GHC 7.8.1 directly. module Main where import GHC.Prim import GHC.IORef import GHC.STRef import GHC.ST import GHC.IO {-# NOINLINE str #-} str :: String str = "hello" t :: MutVar# d a -> a -> a -> State# d -> (# State# d, Int#, a #) t = casMutVar# (===) :: Int# -> Int# -> Bool (===) x y = case x ==# y of { 0# -> False; _ -> True } ---------------------------------------- -- | Performs a machine-level compare and swap operation on an -- 'STRef'. Returns a tuple containing a 'Bool' which is 'True' when a -- swap is performed, along with the 'current' value from the 'STRef'. -- -- Note \"compare\" here means pointer equality in the sense of -- 'GHC.Prim.reallyUnsafePtrEquality#'. casSTRef :: STRef s a -- ^ The 'STRef' containing a value 'current' -> a -- ^ The 'old' value to compare -> a -- ^ The 'new' value to replace 'current' if @old == current@ -> ST s (Bool, a) casSTRef (STRef var#) old new = ST $ \s1# -> -- The primop treats the boolean as a sort of error code. -- Zero means the CAS worked, one that it didn't. -- We flip that here: case casMutVar# var# old new s1# of (# s2#, x#, res #) -> (# s2#, (x# === 0#, res) #) -- | Performs a machine-level compare and swap operation on an -- 'IORef'. Returns a tuple containing a 'Bool' which is 'True' when a -- swap is performed, along with the 'current' value from the 'IORef'. -- -- Note \"compare\" here means pointer equality in the sense of -- 'GHC.Prim.reallyUnsafePtrEquality#'. casIORef :: IORef a -- ^ The 'IORef' containing a value 'current' -> a -- ^ The 'old' value to compare -> a -- ^ The 'new' value to replace 'current' if @old == current@ -> IO (Bool, a) casIORef (IORef var) old new = stToIO (casSTRef var old new) -------------------------------------------------------------------------------- main :: IO () main = do r <- newIORef str pr <- casIORef r str "new str" print pr