{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
module Ki.Internal.Counter
( Counter,
newCounter,
incrCounter,
)
where
import Data.Bits
import GHC.Base
import Ki.Internal.Prelude
data Counter
= Counter (MutableByteArray# RealWorld)
newCounter :: IO Counter
newCounter :: IO Counter
newCounter =
(State# RealWorld -> (# State# RealWorld, Counter #)) -> IO Counter
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO \State# RealWorld
s0# ->
case Int#
-> State# RealWorld
-> (# State# RealWorld, MutableByteArray# RealWorld #)
forall d. Int# -> State# d -> (# State# d, MutableByteArray# d #)
newByteArray# Int#
size State# RealWorld
s0# of
(# State# RealWorld
s1#, MutableByteArray# RealWorld
arr# #) ->
case MutableByteArray# RealWorld
-> Int# -> Int# -> State# RealWorld -> State# RealWorld
forall d.
MutableByteArray# d -> Int# -> Int# -> State# d -> State# d
writeIntArray# MutableByteArray# RealWorld
arr# Int#
0# Int#
0# State# RealWorld
s1# of
State# RealWorld
s2# -> (# State# RealWorld
s2#, MutableByteArray# RealWorld -> Counter
Counter MutableByteArray# RealWorld
arr# #)
where
!(I# Int#
size) =
Int -> Int
forall b. FiniteBits b => b -> Int
finiteBitSize (Int
forall a. HasCallStack => a
undefined :: Int) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
8
{-# INLINE newCounter #-}
incrCounter :: Counter -> IO Int
incrCounter :: Counter -> IO Int
incrCounter (Counter MutableByteArray# RealWorld
arr#) =
(State# RealWorld -> (# State# RealWorld, Int #)) -> IO Int
forall a. (State# RealWorld -> (# State# RealWorld, a #)) -> IO a
IO \State# RealWorld
s0# ->
case MutableByteArray# RealWorld
-> Int# -> Int# -> State# RealWorld -> (# State# RealWorld, Int# #)
forall d.
MutableByteArray# d
-> Int# -> Int# -> State# d -> (# State# d, Int# #)
fetchAddIntArray# MutableByteArray# RealWorld
arr# Int#
0# Int#
1# State# RealWorld
s0# of
(# State# RealWorld
s1#, Int#
n# #) -> (# State# RealWorld
s1#, Int# -> Int
I# Int#
n# #)
{-# INLINE incrCounter #-}