Safe Haskell | None |
---|---|
Language | Haskell2010 |
This should be the most efficient implementation of atomic counters. You probably don't need the others! (Except for testing/debugging.)
- data AtomicCounter
- type CTicket = 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 ()
Documentation
data AtomicCounter Source
The type of mutable atomic counters.
You should not depend on this type. It varies between different implementations of atomic counters.
newCounter :: Int -> IO AtomicCounter Source
Create a new counter initialized to the given value.
readCounterForCAS :: AtomicCounter -> IO CTicket Source
Just like the Data.Atomics CAS interface, this routine returns an opaque
ticket that can be used in CAS operations. Except for the difference in return
type, the semantics of this are the same as readCounter
.
readCounter :: AtomicCounter -> IO Int Source
Equivalent to readCounterForCAS
followed by peekCTicket
.
peekCTicket :: CTicket -> Int Source
Opaque tickets cannot be constructed, but they can be destructed into values.
writeCounter :: AtomicCounter -> Int -> IO () Source
Make a non-atomic write to the counter. No memory-barrier.
casCounter :: AtomicCounter -> CTicket -> Int -> IO (Bool, CTicket) Source
Compare and swap for the counter ADT. Similar behavior to
casIORef
, in particular, in both success and failure cases it
returns a ticket that you should use for the next attempt. (That is, in the
success case, it actually returns the new value that you provided as input, but in
ticket form.)
incrCounter :: Int -> AtomicCounter -> IO Int Source
Increment the counter by a given amount. Returns the value AFTER the increment (in contrast with the behavior of the underlying instruction on architectures like x86.)
Note that UNLIKE with boxed implementations of counters, where increment is based on CAS, this increment is O(1). Fetch-and-add does not require a retry loop like CAS.
incrCounter_ :: Int -> AtomicCounter -> IO () Source
An alternate version for when you don't care about the old value.