Safe Haskell | None |
---|

Provides atomic memory operations on IORefs and Mutable Arrays.

Pointer equality need not be maintained by a Haskell compiler. For example, Int
values will frequently be boxed and unboxed, changing the pointer identity of
the thunk. To deal with this, the compare-and-swap (CAS) approach used in this
module is uses a *sealed* representation of pointers into the Haskell heap
(`Tickets`

). Currently, the user cannot coin new tickets, rather a `Ticket`

provides evidence of a past observation, and grants permission to make a future
change.

- type Ticket a = Any a
- peekTicket :: Ticket a -> a
- casArrayElem :: MutableArray RealWorld a -> Int -> Ticket a -> a -> IO (Bool, Ticket a)
- casArrayElem2 :: MutableArray RealWorld a -> Int -> Ticket a -> Ticket a -> IO (Bool, Ticket a)
- readArrayElem :: forall a. MutableArray RealWorld a -> Int -> IO (Ticket a)
- casByteArrayInt :: MutableByteArray RealWorld -> Int -> Int -> Int -> IO Int
- fetchAddByteArrayInt :: MutableByteArray RealWorld -> Int -> Int -> IO Int
- 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)
- readMutVarForCAS :: MutVar# RealWorld a -> IO (Ticket a)
- casMutVar :: MutVar# RealWorld a -> Ticket a -> a -> IO (Bool, Ticket a)
- casMutVar2 :: MutVar# RealWorld a -> Ticket a -> Ticket a -> IO (Bool, Ticket a)
- storeLoadBarrier :: IO ()
- loadLoadBarrier :: IO ()
- writeBarrier :: IO ()

# Types for atomic operations

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.

peekTicket :: Ticket a -> aSource

A ticket contains or can get the usable Haskell value.

# Atomic operations on mutable arrays

casArrayElem :: MutableArray RealWorld a -> Int -> Ticket a -> a -> IO (Bool, Ticket a)Source

Compare-and-swap

casArrayElem2 :: MutableArray RealWorld a -> Int -> Ticket a -> Ticket a -> IO (Bool, Ticket a)Source

This variant takes two tickets: the `new`

value is a ticket rather than an
arbitrary, lifted, Haskell value.

readArrayElem :: forall a. MutableArray RealWorld a -> Int -> IO (Ticket a)Source

# Atomic operations on byte arrays

casByteArrayInt :: MutableByteArray RealWorld -> Int -> Int -> Int -> IO IntSource

fetchAddByteArrayInt :: MutableByteArray RealWorld -> Int -> Int -> IO IntSource

# Atomic operations on IORefs

readForCAS :: IORef a -> IO (Ticket a)Source

:: IORef a | The |

-> Ticket a | A ticket for the |

-> a | The |

-> IO (Bool, Ticket a) |

Performs a machine-level compare and swap operation on an
`IORef`

. Returns a tuple containing a `Bool`

which is `True`

when a
swap is performed, along with the `current`

value from the `IORef`

.

Note "compare" here means pointer equality in the sense of
`reallyUnsafePtrEquality#`

.

:: 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.

# Atomic operations on raw MutVars

casMutVar :: MutVar# RealWorld a -> Ticket a -> a -> IO (Bool, Ticket a)Source

MutVar counterpart of `casIORef`

.

casMutVar2 :: MutVar# RealWorld a -> Ticket a -> Ticket a -> IO (Bool, Ticket a)Source

This variant takes two tickets, i.e. the `new`

value is a ticket rather than an
arbitrary, lifted, Haskell value.

# Memory barriers

storeLoadBarrier :: IO ()Source

Memory barrier implemented by the GHC rts (SMP.h).

loadLoadBarrier :: IO ()Source

Memory barrier implemented by the GHC rts (SMP.h).

writeBarrier :: IO ()Source

Memory barrier implemented by the GHC rts (SMP.h).