lvish-1.0.0.6: Parallel scheduler, LVar data structures, and infrastructure to build more.

Safe HaskellUnsafe

Control.LVish.SchedIdempotent

Contents

Description

This is an internal module that provides the core parallel scheduler. It is not for end-users.

Synopsis

Basic types and accessors

data LVar a d Source

LVars are parameterized by two types:

  • The first, a, characterizes the "state" of the LVar (i.e., the lattice element), and should be a concurrently mutable data type. That means, in particular, that only a transient snapshot of the state can be obtained in general. But the information in such a snapshot is always a lower bound on the current value of the LVar.
  • The second, d, characterizes the "delta" associated with a putLV operation (i.e., the actual change, if any, to the LVar's state). In many cases such deltas allow far more efficient communication between putLVs and blocked getLVs or handlers. It is crucial, however, that the behavior of a get or handler does not depend on the particular choice of putLV operations (and hence deltas) that moved the LVar over the threshold. For simple data structures, the delta may just be the entire LVar state, but for, e.g., collection data structures, delta will generally represent a single insertion.

Instances

NFData (LVar a d) 

state :: LVar a d -> aSource

data HandlerPool Source

A HandlerPool contains a way to count outstanding parallel computations that are affiliated with the pool. It detects the condition where all such threads have completed.

newtype Par a Source

A monadic type constructor for parallel computations producing an answer a. This is the internal, unsafe type.

Constructors

Par 

Fields

close :: (a -> ClosedPar) -> ClosedPar
 

Instances

Monad Par 
Functor Par 
Applicative Par 

newtype ClosedPar Source

Constructors

ClosedPar 

Fields

exec :: SchedState -> IO ()
 

Safe, deterministic operations

yield :: Par ()Source

Cooperatively schedule other threads.

newPool :: Par HandlerPoolSource

Create a handler pool.

fork :: Par () -> Par ()Source

Fork a child thread.

forkHP :: Maybe HandlerPool -> Par () -> Par ()Source

Fork a child thread, optionally in the context of a handler pool.

runPar :: Par a -> aSource

Run a deterministic parallel computation as pure.

runParIO :: Par a -> IO aSource

A version that avoids an internal unsafePerformIO for calling contexts that are already in the IO monad.

runParLogged :: Par a -> IO ([String], a)Source

Debugging aid. Return debugging logs, in realtime order, in addition to the final result.

withNewPool :: (HandlerPool -> Par a) -> Par (a, HandlerPool)Source

Convenience function. Execute a Par computation in the context of a fresh handler pool.

withNewPool_ :: (HandlerPool -> Par ()) -> Par HandlerPoolSource

Convenience function. Execute a Par computation in the context of a fresh handler pool, while ignoring the result of the computation.

forkWithExceptions :: (IO () -> IO ThreadId) -> String -> IO () -> IO ThreadIdSource

Exceptions that walk up the fork tree of threads.

Quasi-deterministic operations

quiesce :: HandlerPool -> Par ()Source

Block until a handler pool is quiescent.

quiesceAll :: Par ()Source

A global barrier.

Debug facilities

logStrLn :: String -> Par ()Source

Atomically add a line to the given log.

dbgLvl :: IntSource

Debugging flag shared by several modules. This is activated by setting the environment variable DEBUG=1..5.

Unsafe operations; should be used only by experts to build new abstractions

newLV :: IO a -> Par (LVar a d)Source

Create an LVar.

getLVSource

Arguments

:: LVar a d

the LVar

-> (a -> Bool -> IO (Maybe b))

already past threshold? The Bool indicates whether the LVar is FROZEN.

-> (d -> IO (Maybe b))

does d pass the threshold?

-> Par b 

Do a threshold read on an LVar

putLVSource

Arguments

:: LVar a d

the LVar

-> (a -> IO (Maybe d))

how to do the put, and whether the LVar's value changed

-> Par () 

Update an LVar without generating a result.

putLV_Source

Arguments

:: LVar a d

the LVar

-> (a -> Par (Maybe d, b))

how to do the put, and whether the LVar's value changed

-> Par b 

Update an LVar.

freezeLV :: LVar a d -> Par ()Source

Freeze an LVar (introducing quasi-determinism). It is the data structure implementor's responsibility to expose this as quasi-deterministc.

freezeLVAfterSource

Arguments

:: LVar a d

the LVar of interest

-> (a -> IO (Maybe (Par ())))

initial callback

-> (d -> IO (Maybe (Par ())))

subsequent callbacks: updates

-> Par () 

Freeze an LVar after a given handler quiesces.

addHandlerSource

Arguments

:: Maybe HandlerPool

pool to enroll in, if any

-> LVar a d

LVar to listen to

-> (a -> IO (Maybe (Par ())))

initial callback

-> (d -> IO (Maybe (Par ())))

subsequent callbacks: updates

-> Par () 

Add a handler to an existing pool.

liftIO :: IO a -> Par aSource

Perform an IO action.

toss :: MonadToss m => m BoolSource