{-# LANGUAGE BangPatterns, ForeignFunctionInterface #-}
module Data.Atomic
(
Atomic
, new
, read
, write
, inc
, dec
, add
, subtract
) where
import Data.Int (Int64)
import Foreign.ForeignPtr (ForeignPtr, mallocForeignPtr, withForeignPtr)
import Foreign.Ptr (Ptr)
import Foreign.Storable (poke)
import Prelude hiding (read, subtract)
newtype Atomic = C (ForeignPtr Int64)
new :: Int64 -> IO Atomic
new n = do
fp <- mallocForeignPtr
withForeignPtr fp $ \ p -> poke p n
return $ C fp
read :: Atomic -> IO Int64
read (C fp) = withForeignPtr fp cRead
foreign import ccall unsafe "hs_atomic_read" cRead :: Ptr Int64 -> IO Int64
write :: Atomic -> Int64 -> IO ()
write (C fp) n = withForeignPtr fp $ \ p -> cWrite p n
foreign import ccall unsafe "hs_atomic_write" cWrite
:: Ptr Int64 -> Int64 -> IO ()
inc :: Atomic -> IO ()
inc atomic = add atomic 1
dec :: Atomic -> IO ()
dec atomic = subtract atomic 1
add :: Atomic -> Int64 -> IO ()
add (C fp) n = withForeignPtr fp $ \ p -> cAdd p n
subtract :: Atomic -> Int64 -> IO ()
subtract (C fp) n = withForeignPtr fp $ \ p -> cSubtract p n
foreign import ccall unsafe "hs_atomic_add" cAdd :: Ptr Int64 -> Int64 -> IO ()
foreign import ccall unsafe "hs_atomic_subtract" cSubtract
:: Ptr Int64 -> Int64 -> IO ()