{-# LANGUAGE CPP #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE Unsafe #-}
module Data.Primitive.PrimVar
(
PrimVar(..)
, newPrimVar
, newPinnedPrimVar
, newAlignedPinnedPrimVar
, readPrimVar
, writePrimVar
, modifyPrimVar
, primVarContents
, primVarToMutablePrimArray
, casInt
, fetchAddInt
, fetchSubInt
, fetchAndInt
, fetchNandInt
, fetchOrInt
, fetchXorInt
, atomicReadInt
, atomicWriteInt
) where
import Control.Monad.Primitive
import Data.Primitive
import GHC.Exts
import GHC.Ptr (castPtr)
newtype PrimVar s a = PrimVar (MutablePrimArray s a)
type role PrimVar nominal nominal
newPrimVar :: (PrimMonad m, Prim a) => a -> m (PrimVar (PrimState m) a)
newPrimVar :: forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
a -> m (PrimVar (PrimState m) a)
newPrimVar a
a = do
MutablePrimArray (PrimState m) a
m <- Int -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPrimArray Int
1
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray (PrimState m) a
m Int
0 a
a
PrimVar (PrimState m) a -> m (PrimVar (PrimState m) a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (MutablePrimArray (PrimState m) a -> PrimVar (PrimState m) a
forall s a. MutablePrimArray s a -> PrimVar s a
PrimVar MutablePrimArray (PrimState m) a
m)
{-# INLINE newPrimVar #-}
newPinnedPrimVar :: (PrimMonad m, Prim a) => a -> m (PrimVar (PrimState m) a)
newPinnedPrimVar :: forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
a -> m (PrimVar (PrimState m) a)
newPinnedPrimVar a
a = do
MutablePrimArray (PrimState m) a
m <- Int -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newPinnedPrimArray Int
1
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray (PrimState m) a
m Int
0 a
a
PrimVar (PrimState m) a -> m (PrimVar (PrimState m) a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (MutablePrimArray (PrimState m) a -> PrimVar (PrimState m) a
forall s a. MutablePrimArray s a -> PrimVar s a
PrimVar MutablePrimArray (PrimState m) a
m)
{-# INLINE newPinnedPrimVar #-}
newAlignedPinnedPrimVar :: (PrimMonad m, Prim a) => a -> m (PrimVar (PrimState m) a)
newAlignedPinnedPrimVar :: forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
a -> m (PrimVar (PrimState m) a)
newAlignedPinnedPrimVar a
a = do
MutablePrimArray (PrimState m) a
m <- Int -> m (MutablePrimArray (PrimState m) a)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
Int -> m (MutablePrimArray (PrimState m) a)
newAlignedPinnedPrimArray Int
1
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray (PrimState m) a
m Int
0 a
a
PrimVar (PrimState m) a -> m (PrimVar (PrimState m) a)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (MutablePrimArray (PrimState m) a -> PrimVar (PrimState m) a
forall s a. MutablePrimArray s a -> PrimVar s a
PrimVar MutablePrimArray (PrimState m) a
m)
{-# INLINE newAlignedPinnedPrimVar #-}
readPrimVar :: (PrimMonad m, Prim a) => PrimVar (PrimState m) a -> m a
readPrimVar :: forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
PrimVar (PrimState m) a -> m a
readPrimVar (PrimVar MutablePrimArray (PrimState m) a
m) = MutablePrimArray (PrimState m) a -> Int -> m a
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> m a
readPrimArray MutablePrimArray (PrimState m) a
m Int
0
{-# INLINE readPrimVar #-}
writePrimVar :: (PrimMonad m, Prim a) => PrimVar (PrimState m) a -> a -> m ()
writePrimVar :: forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
PrimVar (PrimState m) a -> a -> m ()
writePrimVar (PrimVar MutablePrimArray (PrimState m) a
m) a
a = MutablePrimArray (PrimState m) a -> Int -> a -> m ()
forall a (m :: * -> *).
(Prim a, PrimMonad m) =>
MutablePrimArray (PrimState m) a -> Int -> a -> m ()
writePrimArray MutablePrimArray (PrimState m) a
m Int
0 a
a
{-# INLINE writePrimVar #-}
modifyPrimVar :: (PrimMonad m, Prim a) => PrimVar (PrimState m) a -> (a -> a) -> m ()
modifyPrimVar :: forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
PrimVar (PrimState m) a -> (a -> a) -> m ()
modifyPrimVar PrimVar (PrimState m) a
pv a -> a
f = do
a
x <- PrimVar (PrimState m) a -> m a
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
PrimVar (PrimState m) a -> m a
readPrimVar PrimVar (PrimState m) a
pv
PrimVar (PrimState m) a -> a -> m ()
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
PrimVar (PrimState m) a -> a -> m ()
writePrimVar PrimVar (PrimState m) a
pv (a -> a
f a
x)
{-# INLINE modifyPrimVar #-}
instance Eq (PrimVar s a) where
PrimVar MutablePrimArray s a
m == :: PrimVar s a -> PrimVar s a -> Bool
== PrimVar MutablePrimArray s a
n = MutablePrimArray s a -> MutablePrimArray s a -> Bool
forall s a. MutablePrimArray s a -> MutablePrimArray s a -> Bool
sameMutablePrimArray MutablePrimArray s a
m MutablePrimArray s a
n
{-# INLINE (==) #-}
primVarContents :: PrimVar s a -> Ptr a
primVarContents :: forall s a. PrimVar s a -> Ptr a
primVarContents (PrimVar MutablePrimArray s a
m) = Ptr a -> Ptr a
forall a b. Ptr a -> Ptr b
castPtr (Ptr a -> Ptr a) -> Ptr a -> Ptr a
forall a b. (a -> b) -> a -> b
$ MutablePrimArray s a -> Ptr a
forall s a. MutablePrimArray s a -> Ptr a
mutablePrimArrayContents MutablePrimArray s a
m
{-# INLINE primVarContents #-}
primVarToMutablePrimArray :: PrimVar s a -> MutablePrimArray s a
primVarToMutablePrimArray :: forall s a. PrimVar s a -> MutablePrimArray s a
primVarToMutablePrimArray (PrimVar MutablePrimArray s a
m) = MutablePrimArray s a
m
{-# INLINE primVarToMutablePrimArray #-}
casInt :: PrimMonad m => PrimVar (PrimState m) Int -> Int -> Int -> m Int
casInt :: forall (m :: * -> *).
PrimMonad m =>
PrimVar (PrimState m) Int -> Int -> Int -> m Int
casInt (PrimVar (MutablePrimArray MutableByteArray# (PrimState m)
m)) (I# Int#
old) (I# Int#
new) = (State# (PrimState m) -> (# State# (PrimState m), Int #)) -> m Int
forall a.
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int)
-> (State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int
forall a b. (a -> b) -> a -> b
$ \State# (PrimState m)
s -> case MutableByteArray# (PrimState m)
-> Int#
-> Int#
-> Int#
-> State# (PrimState m)
-> (# State# (PrimState m), Int# #)
forall d.
MutableByteArray# d
-> Int# -> Int# -> Int# -> State# d -> (# State# d, Int# #)
casIntArray# MutableByteArray# (PrimState m)
m Int#
0# Int#
old Int#
new State# (PrimState m)
s of
(# State# (PrimState m)
s', Int#
result #) -> (# State# (PrimState m)
s', Int# -> Int
I# Int#
result #)
{-# INLINE casInt #-}
fetchAddInt :: PrimMonad m => PrimVar (PrimState m) Int -> Int -> m Int
fetchAddInt :: forall (m :: * -> *).
PrimMonad m =>
PrimVar (PrimState m) Int -> Int -> m Int
fetchAddInt (PrimVar (MutablePrimArray MutableByteArray# (PrimState m)
m)) (I# Int#
x) = (State# (PrimState m) -> (# State# (PrimState m), Int #)) -> m Int
forall a.
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int)
-> (State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int
forall a b. (a -> b) -> a -> b
$ \State# (PrimState m)
s -> case MutableByteArray# (PrimState m)
-> Int#
-> Int#
-> State# (PrimState m)
-> (# State# (PrimState m), Int# #)
forall d.
MutableByteArray# d
-> Int# -> Int# -> State# d -> (# State# d, Int# #)
fetchAddIntArray# MutableByteArray# (PrimState m)
m Int#
0# Int#
x State# (PrimState m)
s of
(# State# (PrimState m)
s', Int#
result #) -> (# State# (PrimState m)
s', Int# -> Int
I# Int#
result #)
{-# INLINE fetchAddInt #-}
fetchSubInt :: PrimMonad m => PrimVar (PrimState m) Int -> Int -> m Int
fetchSubInt :: forall (m :: * -> *).
PrimMonad m =>
PrimVar (PrimState m) Int -> Int -> m Int
fetchSubInt (PrimVar (MutablePrimArray MutableByteArray# (PrimState m)
m)) (I# Int#
x) = (State# (PrimState m) -> (# State# (PrimState m), Int #)) -> m Int
forall a.
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int)
-> (State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int
forall a b. (a -> b) -> a -> b
$ \State# (PrimState m)
s -> case MutableByteArray# (PrimState m)
-> Int#
-> Int#
-> State# (PrimState m)
-> (# State# (PrimState m), Int# #)
forall d.
MutableByteArray# d
-> Int# -> Int# -> State# d -> (# State# d, Int# #)
fetchSubIntArray# MutableByteArray# (PrimState m)
m Int#
0# Int#
x State# (PrimState m)
s of
(# State# (PrimState m)
s', Int#
result #) -> (# State# (PrimState m)
s', Int# -> Int
I# Int#
result #)
{-# INLINE fetchSubInt #-}
fetchAndInt :: PrimMonad m => PrimVar (PrimState m) Int -> Int -> m Int
fetchAndInt :: forall (m :: * -> *).
PrimMonad m =>
PrimVar (PrimState m) Int -> Int -> m Int
fetchAndInt (PrimVar (MutablePrimArray MutableByteArray# (PrimState m)
m)) (I# Int#
x) = (State# (PrimState m) -> (# State# (PrimState m), Int #)) -> m Int
forall a.
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int)
-> (State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int
forall a b. (a -> b) -> a -> b
$ \State# (PrimState m)
s -> case MutableByteArray# (PrimState m)
-> Int#
-> Int#
-> State# (PrimState m)
-> (# State# (PrimState m), Int# #)
forall d.
MutableByteArray# d
-> Int# -> Int# -> State# d -> (# State# d, Int# #)
fetchAndIntArray# MutableByteArray# (PrimState m)
m Int#
0# Int#
x State# (PrimState m)
s of
(# State# (PrimState m)
s', Int#
result #) -> (# State# (PrimState m)
s', Int# -> Int
I# Int#
result #)
{-# INLINE fetchAndInt #-}
fetchNandInt :: PrimMonad m => PrimVar (PrimState m) Int -> Int -> m Int
fetchNandInt :: forall (m :: * -> *).
PrimMonad m =>
PrimVar (PrimState m) Int -> Int -> m Int
fetchNandInt (PrimVar (MutablePrimArray MutableByteArray# (PrimState m)
m)) (I# Int#
x) = (State# (PrimState m) -> (# State# (PrimState m), Int #)) -> m Int
forall a.
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int)
-> (State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int
forall a b. (a -> b) -> a -> b
$ \State# (PrimState m)
s -> case MutableByteArray# (PrimState m)
-> Int#
-> Int#
-> State# (PrimState m)
-> (# State# (PrimState m), Int# #)
forall d.
MutableByteArray# d
-> Int# -> Int# -> State# d -> (# State# d, Int# #)
fetchNandIntArray# MutableByteArray# (PrimState m)
m Int#
0# Int#
x State# (PrimState m)
s of
(# State# (PrimState m)
s', Int#
result #) -> (# State# (PrimState m)
s', Int# -> Int
I# Int#
result #)
{-# INLINE fetchNandInt #-}
fetchOrInt :: PrimMonad m => PrimVar (PrimState m) Int -> Int -> m Int
fetchOrInt :: forall (m :: * -> *).
PrimMonad m =>
PrimVar (PrimState m) Int -> Int -> m Int
fetchOrInt (PrimVar (MutablePrimArray MutableByteArray# (PrimState m)
m)) (I# Int#
x) = (State# (PrimState m) -> (# State# (PrimState m), Int #)) -> m Int
forall a.
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int)
-> (State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int
forall a b. (a -> b) -> a -> b
$ \State# (PrimState m)
s -> case MutableByteArray# (PrimState m)
-> Int#
-> Int#
-> State# (PrimState m)
-> (# State# (PrimState m), Int# #)
forall d.
MutableByteArray# d
-> Int# -> Int# -> State# d -> (# State# d, Int# #)
fetchOrIntArray# MutableByteArray# (PrimState m)
m Int#
0# Int#
x State# (PrimState m)
s of
(# State# (PrimState m)
s', Int#
result #) -> (# State# (PrimState m)
s', Int# -> Int
I# Int#
result #)
{-# INLINE fetchOrInt #-}
fetchXorInt :: PrimMonad m => PrimVar (PrimState m) Int -> Int -> m Int
fetchXorInt :: forall (m :: * -> *).
PrimMonad m =>
PrimVar (PrimState m) Int -> Int -> m Int
fetchXorInt (PrimVar (MutablePrimArray MutableByteArray# (PrimState m)
m)) (I# Int#
x) = (State# (PrimState m) -> (# State# (PrimState m), Int #)) -> m Int
forall a.
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int)
-> (State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int
forall a b. (a -> b) -> a -> b
$ \State# (PrimState m)
s -> case MutableByteArray# (PrimState m)
-> Int#
-> Int#
-> State# (PrimState m)
-> (# State# (PrimState m), Int# #)
forall d.
MutableByteArray# d
-> Int# -> Int# -> State# d -> (# State# d, Int# #)
fetchXorIntArray# MutableByteArray# (PrimState m)
m Int#
0# Int#
x State# (PrimState m)
s of
(# State# (PrimState m)
s', Int#
result #) -> (# State# (PrimState m)
s', Int# -> Int
I# Int#
result #)
{-# INLINE fetchXorInt #-}
atomicReadInt :: PrimMonad m => PrimVar (PrimState m) Int -> m Int
atomicReadInt :: forall (m :: * -> *).
PrimMonad m =>
PrimVar (PrimState m) Int -> m Int
atomicReadInt (PrimVar (MutablePrimArray MutableByteArray# (PrimState m)
m)) = (State# (PrimState m) -> (# State# (PrimState m), Int #)) -> m Int
forall a.
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive ((State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int)
-> (State# (PrimState m) -> (# State# (PrimState m), Int #))
-> m Int
forall a b. (a -> b) -> a -> b
$ \State# (PrimState m)
s -> case MutableByteArray# (PrimState m)
-> Int# -> State# (PrimState m) -> (# State# (PrimState m), Int# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Int# #)
atomicReadIntArray# MutableByteArray# (PrimState m)
m Int#
0# State# (PrimState m)
s of
(# State# (PrimState m)
s', Int#
result #) -> (# State# (PrimState m)
s', Int# -> Int
I# Int#
result #)
{-# INLINE atomicReadInt #-}
atomicWriteInt :: PrimMonad m => PrimVar (PrimState m) Int -> Int -> m ()
atomicWriteInt :: forall (m :: * -> *).
PrimMonad m =>
PrimVar (PrimState m) Int -> Int -> m ()
atomicWriteInt (PrimVar (MutablePrimArray MutableByteArray# (PrimState m)
m)) (I# Int#
x) = (State# (PrimState m) -> State# (PrimState m)) -> m ()
forall (m :: * -> *).
PrimMonad m =>
(State# (PrimState m) -> State# (PrimState m)) -> m ()
primitive_ ((State# (PrimState m) -> State# (PrimState m)) -> m ())
-> (State# (PrimState m) -> State# (PrimState m)) -> m ()
forall a b. (a -> b) -> a -> b
$ \State# (PrimState m)
s -> MutableByteArray# (PrimState m)
-> Int# -> Int# -> State# (PrimState m) -> State# (PrimState m)
forall d.
MutableByteArray# d -> Int# -> Int# -> State# d -> State# d
atomicWriteIntArray# MutableByteArray# (PrimState m)
m Int#
0# Int#
x State# (PrimState m)
s
{-# INLINE atomicWriteInt #-}