Safe Haskell | None |
---|---|
Language | Haskell2010 |
Synopsis
- data IORef a
- newIORef :: MonadIO m => a -> m (IORef a)
- readIORef :: MonadIO m => IORef a -> m a
- writeIORef :: MonadIO m => IORef a -> a -> m ()
- writeIORef' :: IORef a -> a -> IO ()
- modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m ()
- modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m ()
- atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
- atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b
- atomicWriteIORef :: MonadIO m => IORef a -> a -> m ()
- atomicWriteIORef' :: IORef a -> a -> IO ()
- mkWeakIORef :: MonadUnliftIO m => IORef a -> m () -> m (Weak (IORef a))
- data Ticket a
- peekTicket :: Ticket a -> a
- readForCAS :: IORef a -> IO (Ticket a)
- casIORef :: IORef a -> Ticket a -> a -> IO (Bool, Ticket a)
- casIORef2 :: IORef a -> Ticket a -> Ticket a -> IO (Bool, Ticket a)
- atomicModifyIORefCAS :: IORef a -> (a -> (a, b)) -> IO b
- atomicModifyIORefCAS_ :: IORef t -> (t -> t) -> IO ()
IORef
A mutable variable in the IO
monad
Instances
NFData1 IORef | Since: deepseq-1.4.3.0 |
Defined in Control.DeepSeq | |
Eq (IORef a) | Pointer equality. Since: base-4.1.0.0 |
NFData (IORef a) | NOTE: Only strict in the reference and not the referenced value. Since: deepseq-1.4.2.0 |
Defined in Control.DeepSeq |
writeIORef :: MonadIO m => IORef a -> a -> m () #
Lifted writeIORef
.
Since: unliftio-0.1.0.0
writeIORef' :: IORef a -> a -> IO () #
Evaluates the value before calling writeIORef
.
modifyIORef :: MonadIO m => IORef a -> (a -> a) -> m () #
Lifted modifyIORef
.
Since: unliftio-0.1.0.0
modifyIORef' :: MonadIO m => IORef a -> (a -> a) -> m () #
Lifted modifyIORef'
.
Since: unliftio-0.1.0.0
atomicModifyIORef :: MonadIO m => IORef a -> (a -> (a, b)) -> m b #
Lifted atomicModifyIORef
.
Since: unliftio-0.1.0.0
atomicModifyIORef' :: MonadIO m => IORef a -> (a -> (a, b)) -> m b #
Lifted atomicModifyIORef'
.
Since: unliftio-0.1.0.0
atomicWriteIORef :: MonadIO m => IORef a -> a -> m () #
Lifted atomicWriteIORef
.
Since: unliftio-0.1.0.0
atomicWriteIORef' :: IORef a -> a -> IO () #
Evaluates the value before calling atomicWriteIORef
.
mkWeakIORef :: MonadUnliftIO m => IORef a -> m () -> m (Weak (IORef a)) #
Unlifted mkWeakIORef
.
Since: unliftio-0.1.0.0
Atomic check-and-set
When performing compare-and-swaps, the ticket encapsulates proof that a thread observed a specific previous value of a mutable variable. It is provided in lieu of the "old" value to compare-and-swap.
Design note: Ticket
s exist to hide objects from the GHC compiler, which
can normally perform many optimizations that change pointer equality. A Ticket,
on the other hand, is a first-class object that can be handled by the user,
but will not have its pointer identity changed by compiler optimizations
(but will of course, change addresses during garbage collection).
peekTicket :: Ticket a -> a #
A ticket contains or can get the usable Haskell value. This function does just that.
readForCAS :: IORef a -> IO (Ticket a) #
Ordinary processor load instruction (non-atomic, not implying any memory barriers).
The difference between this function and readIORef
, is that it returns a ticket,
for use in future compare-and-swap operations.
:: IORef a | The |
-> Ticket a | A ticket for the |
-> a | The |
-> IO (Bool, Ticket a) | Success flag, plus ticket for the NEXT operation. |
Performs a machine-level compare and swap (CAS) operation on an
IORef
. Returns a tuple containing a Bool
which is True
when a
swap is performed, along with the most current
value from the IORef
.
Note that this differs from the more common CAS behavior, which is to
return the old value before the CAS occured.
The reason for the difference is the ticket API. This function always returns the
ticket that you should use in your next CAS attempt. In case of success, this ticket
corresponds to the new
value which you yourself installed in the IORef
, whereas
in the case of failure it represents the preexisting value currently in the IORef.
Note "compare" here means pointer equality in the sense of
reallyUnsafePtrEquality#
. However, the ticket API absolves
the user of this module from needing to worry about the pointer equality of their
values, which in general requires reasoning about the details of the Haskell
implementation (GHC).
By convention this function is strict in the "new" value argument. This isn't absolutely necesary, but we think it's a bad habit to use unevaluated thunks in this context.
:: IORef a | |
-> Ticket a | A ticket for the |
-> Ticket a | A ticket for the |
-> IO (Bool, Ticket a) |
This variant takes two tickets, i.e. the new
value is a ticket rather than an
arbitrary, lifted, Haskell value.
:: IORef a | Mutable location to modify |
-> (a -> (a, b)) | Computation runs one or more times (speculation) |
-> IO b |
A drop-in replacement for atomicModifyIORef
that
optimistically attempts to compute the new value and CAS it into
place without introducing new thunks or locking anything. Note
that this is more STRICT than its standard counterpart and will only
place evaluated (WHNF) values in the IORef.
The upside is that sometimes we see a performance benefit. The downside is that this version is speculative -- when it retries, it must reexecute the compution.
atomicModifyIORefCAS_ :: IORef t -> (t -> t) -> IO () #
A simpler version that modifies the state but does not return anything.