{-# language MagicHash #-} {-# language UnboxedTuples #-} module Data.Primitive.Array.Atomic ( casArray ) where import Control.Monad.Primitive (PrimMonad,PrimState,primitive) import Data.Primitive (MutableArray(..)) import GHC.Exts (Int(I#),casArray#,isTrue#,(==#)) -- | Given an array, an offset in Int units, the expected old value, -- and the new value, perform an atomic compare and swap i.e. write -- the new value if the current value matches the provided old value. -- Returns the value of the element before the operation. Implies a -- full memory barrier. -- -- Note that lifted values in GHC have limited guarantees concerning -- pointer equality. In particular, data constructor applications of -- single-constructor data types may be mangled by GHC Core optimizations. -- Users of this function are expected to understand how to make -- pointer equality survive GHC's optimization passes. casArray :: PrimMonad m => MutableArray (PrimState m) a -- ^ prim array -> Int -- ^ index -> a -- ^ expected old value -> a -- ^ new value -> m (Bool,a) {-# INLINE casArray #-} casArray (MutableArray arr#) (I# i#) old new = primitive $ \s0 -> case casArray# arr# i# old new s0 of (# s1, n, r #) -> (# s1, (isTrue# (n ==# 0# ),r) #)