{-# LANGUAGE TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses, BangPatterns #-} -- Author: Ryan Newton -- | This is an attempt to imitate a CAS using normal Haskell/GHC operations. -- Useful for debugging. -- module Data.CAS.Internal.Fake ( CASRef, casIORef, ptrEq, atomicModifyIORefCAS, atomicModifyIORefCAS_ ) where import Data.IORef import Data.CAS.Internal.Class import Debug.Trace import System.Mem.StableName -------------------------------------------------------------------------------- -- | The type of references supporting CAS. newtype CASRef a = CR { unCR :: IORef a } instance CASable CASRef a where newCASable x = newIORef x >>= (return . CR) readCASable = readIORef . unCR writeCASable = writeIORef . unCR cas = casIORef . unCR -------------------------------------------------------------------------------- {-# NOINLINE casIORef #-} -- TEMP -- A non-CAS based version. Alas, this has UNDEFINED BEHAVIOR -- (see ptrEq). -- -- casIORef :: Eq a => IORef a -> a -> a -> IO (Bool,a) casIORef :: IORef a -> a -> a -> IO (Bool,a) -- casIORef r !old !new = casIORef r old new = do atomicModifyIORef r $ \val -> {- trace (" DBG: INSIDE ATOMIC MODIFY, ptr eqs found/expected: " ++ show [ptrEq val old, ptrEq val old, ptrEq val old] ++ " ptr eq self: " ++ show [ptrEq val val, ptrEq old old] ++ " names: " ++ show (unsafeName old, unsafeName old, unsafeName val, unsafeName val) ) $ -} if (ptrEq val old) then (new, (True, val)) else (val, (False,val)) atomicModifyIORefCAS = atomicModifyIORef atomicModifyIORefCAS_ = atomicModifyIORef_ atomicModifyIORef_ ref fn = atomicModifyIORef ref (\ x -> (fn x, ()))