module Data.Atomics.Counter.Foreign
where
import Data.Bits.Atomic
import Foreign.ForeignPtr
import Foreign.Storable
type AtomicCounter = ForeignPtr Int
type CTicket = Int
newCounter :: IO AtomicCounter
newCounter = do x <- mallocForeignPtr
writeCounter x 0
return x
incrCounter :: AtomicCounter -> IO Int
incrCounter r = withForeignPtr r$ \r' -> fetchAndAdd r' 1
readCounterForCAS :: AtomicCounter -> IO CTicket
readCounterForCAS = readCounter
peekCTicket :: CTicket -> Int
peekCTicket x = x
readCounter :: AtomicCounter -> IO Int
readCounter r = withForeignPtr r peek
writeCounter :: AtomicCounter -> Int -> IO ()
writeCounter r !new = withForeignPtr r $ \r' -> poke r' new
casCounter :: AtomicCounter -> CTicket -> Int -> IO (Bool, CTicket)
casCounter r !tick !new = withForeignPtr r $ \r' -> do
b <- compareAndSwap r' tick new
return (b==tick, b)