module Data.IORef.Unboxed
(
IORefU
, newIORefU
, readIORefU
, writeIORefU
, modifyIORefU
, Counter
, newCounter
, atomicAddCounter
, atomicSubCounter
, atomicAndCounter
, atomicNandCounter
, atomicOrCounter
, atomicXorCounter
, atomicAddCounter_
, atomicSubCounter_
, atomicAndCounter_
, atomicNandCounter_
, atomicOrCounter_
, atomicXorCounter_
) where
import Data.Primitive.Types
import Data.Primitive.ByteArray
import GHC.Prim
import GHC.Types
import GHC.ST
import GHC.IO(stToIO)
import Data.STRef.Unboxed.Internal
newtype IORefU a = IORefU (STRefU RealWorld a)
newIORefU :: Prim a => a -> IO (IORefU a)
newIORefU init = IORefU `fmap` stToIO (newSTRefU init)
readIORefU :: Prim a => IORefU a -> IO a
readIORefU (IORefU stRefU) = stToIO (readSTRefU stRefU)
writeIORefU :: Prim a => IORefU a -> a -> IO ()
writeIORefU (IORefU stRefU) x = stToIO (writeSTRefU stRefU x)
modifyIORefU :: Prim a => IORefU a -> (a -> a) -> IO ()
modifyIORefU ref f = readIORefU ref >>= writeIORefU ref . f
type Counter = IORefU Int
newCounter :: Int -> IO Counter
newCounter = newIORefU
atomicAddCounter :: Counter -> Int -> IO Int
atomicAddCounter (IORefU (STRefU (MutableByteArray mba#))) (I# x#) = IO $ \ s1# ->
let (# s2#, res# #) = fetchAddIntArray# mba# 0# x# s1# in (# s2#, (I# (res# +# x#)) #)
atomicAddCounter_ :: Counter -> Int -> IO Int
atomicAddCounter_ (IORefU (STRefU (MutableByteArray mba#))) (I# x#) = IO $ \ s1# ->
let (# s2#, res# #) = fetchAddIntArray# mba# 0# x# s1# in (# s2#, (I# res#) #)
atomicSubCounter :: Counter -> Int -> IO Int
atomicSubCounter (IORefU (STRefU (MutableByteArray mba#))) (I# x#) = IO $ \ s1# ->
let (# s2#, res# #) = fetchSubIntArray# mba# 0# x# s1# in (# s2#, (I# (res# -# x#)) #)
atomicSubCounter_ :: Counter -> Int -> IO Int
atomicSubCounter_ (IORefU (STRefU (MutableByteArray mba#))) (I# x#) = IO $ \ s1# ->
let (# s2#, res# #) = fetchSubIntArray# mba# 0# x# s1# in (# s2#, (I# res#) #)
atomicAndCounter :: Counter -> Int -> IO Int
atomicAndCounter (IORefU (STRefU (MutableByteArray mba#))) (I# x#) = IO $ \ s1# ->
let (# s2#, res# #) = fetchAndIntArray# mba# 0# x# s1# in (# s2#, (I# (res# `andI#` x#)) #)
atomicAndCounter_ :: Counter -> Int -> IO Int
atomicAndCounter_ (IORefU (STRefU (MutableByteArray mba#))) (I# x#) = IO $ \ s1# ->
let (# s2#, res# #) = fetchAndIntArray# mba# 0# x# s1# in (# s2#, (I# res#) #)
atomicNandCounter :: Counter -> Int -> IO Int
atomicNandCounter (IORefU (STRefU (MutableByteArray mba#))) (I# x#) = IO $ \ s1# ->
let (# s2#, res# #) = fetchNandIntArray# mba# 0# x# s1# in (# s2#, (I# (notI# (res# `andI#` x#))) #)
atomicNandCounter_ :: Counter -> Int -> IO Int
atomicNandCounter_ (IORefU (STRefU (MutableByteArray mba#))) (I# x#) = IO $ \ s1# ->
let (# s2#, res# #) = fetchNandIntArray# mba# 0# x# s1# in (# s2#, (I# res#) #)
atomicOrCounter :: Counter -> Int -> IO Int
atomicOrCounter (IORefU (STRefU (MutableByteArray mba#))) (I# x#) = IO $ \ s1# ->
let (# s2#, res# #) = fetchOrIntArray# mba# 0# x# s1# in (# s2#, (I# (res# `orI#` x#)) #)
atomicOrCounter_ :: Counter -> Int -> IO Int
atomicOrCounter_ (IORefU (STRefU (MutableByteArray mba#))) (I# x#) = IO $ \ s1# ->
let (# s2#, res# #) = fetchOrIntArray# mba# 0# x# s1# in (# s2#, (I# res#) #)
atomicXorCounter :: Counter -> Int -> IO Int
atomicXorCounter (IORefU (STRefU (MutableByteArray mba#))) (I# x#) = IO $ \ s1# ->
let (# s2#, res# #) = fetchXorIntArray# mba# 0# x# s1# in (# s2#, (I# (res# `xorI#` x#)) #)
atomicXorCounter_ :: Counter -> Int -> IO Int
atomicXorCounter_ (IORefU (STRefU (MutableByteArray mba#))) (I# x#) = IO $ \ s1# ->
let (# s2#, res# #) = fetchXorIntArray# mba# 0# x# s1# in (# s2#, (I# res#) #)