atomic-primops-0.4: A safe approach to CAS and other atomic ops in Haskell.

Safe HaskellNone

Data.Atomics

Contents

Description

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.

Synopsis

Types for atomic operations

type Ticket a = Any aSource

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

Atomic operations on IORefs

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

casIORefSource

Arguments

:: IORef a

The IORef containing a value current

-> Ticket a

A ticket for the old value

-> a

The new value to replace current if old == current

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

casIORef2Source

Arguments

:: IORef a 
-> Ticket a

A ticket for the old value

-> Ticket a

A ticket for the new value

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

readMutVarForCAS :: MutVar# RealWorld a -> IO (Ticket a)Source

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