This version uses a boxed IORef representation, but it can be somewhat cheaper than the Refence version because it uses raw CAS rather than full atomicModifyIORef.
- data AtomicCounter
- type CTicket = Ticket Int
- newCounter :: Int -> IO AtomicCounter
- readCounterForCAS :: AtomicCounter -> IO CTicket
- readCounter :: AtomicCounter -> IO Int
- peekCTicket :: CTicket -> Int
- writeCounter :: AtomicCounter -> Int -> IO ()
- casCounter :: AtomicCounter -> CTicket -> Int -> IO (Bool, CTicket)
- incrCounter :: Int -> AtomicCounter -> IO Int
- incrCounter_ :: Int -> AtomicCounter -> IO ()
Just like the Data.Atomics CAS interface, this routine returns an opaque ticket that can be used in CAS operations.
Opaque tickets cannot be constructed, but they can be destructed into values.
Make a non-atomic write to the counter. No memory-barrier.
Compare and swap for the counter ADT. Similar behavior to
Try repeatedly until we successfully increment the counter by a given amount. Returns the original value of the counter (pre-increment).