Copyright | (c) 2016 Michael Walker |
---|---|
License | MIT |
Maintainer | Michael Walker <mike@barrucadu.co.uk> |
Stability | experimental |
Portability | FlexibleInstances, GeneralizedNewtypeDeriving, MultiParamTypeClasses, RankNTypes, TypeFamilies, TypeSynonymInstances |
Safe Haskell | None |
Language | Haskell2010 |
Deterministic traced execution of concurrent computations.
This works by executing the computation on a single thread, calling out to the supplied scheduler after each step to determine which thread runs next.
- data ConcT r n a
- type ConcST t = ConcT (STRef t) (ST t)
- type ConcIO = ConcT IORef IO
- data Failure
- data MemType
- runConcurrent :: MonadRef r n => Scheduler s -> MemType -> s -> ConcT r n a -> n (Either Failure a, s, Trace)
- subconcurrency :: ConcT r n a -> ConcT r n (Either Failure a)
- type Trace = [(Decision, [(ThreadId, NonEmpty Lookahead)], ThreadAction)]
- data Decision
- data ThreadId = ThreadId (Maybe String) Int
- data ThreadAction
- = Fork ThreadId
- | MyThreadId
- | GetNumCapabilities Int
- | SetNumCapabilities Int
- | Yield
- | NewMVar MVarId
- | PutMVar MVarId [ThreadId]
- | BlockedPutMVar MVarId
- | TryPutMVar MVarId Bool [ThreadId]
- | ReadMVar MVarId
- | TryReadMVar MVarId Bool
- | BlockedReadMVar MVarId
- | TakeMVar MVarId [ThreadId]
- | BlockedTakeMVar MVarId
- | TryTakeMVar MVarId Bool [ThreadId]
- | NewCRef CRefId
- | ReadCRef CRefId
- | ReadCRefCas CRefId
- | ModCRef CRefId
- | ModCRefCas CRefId
- | WriteCRef CRefId
- | CasCRef CRefId Bool
- | CommitCRef ThreadId CRefId
- | STM TTrace [ThreadId]
- | BlockedSTM TTrace
- | Catching
- | PopCatching
- | Throw
- | ThrowTo ThreadId
- | BlockedThrowTo ThreadId
- | Killed
- | SetMasking Bool MaskingState
- | ResetMasking Bool MaskingState
- | LiftIO
- | Return
- | Stop
- | Subconcurrency
- | StopSubconcurrency
- data Lookahead
- = WillFork
- | WillMyThreadId
- | WillGetNumCapabilities
- | WillSetNumCapabilities Int
- | WillYield
- | WillNewMVar
- | WillPutMVar MVarId
- | WillTryPutMVar MVarId
- | WillReadMVar MVarId
- | WillTryReadMVar MVarId
- | WillTakeMVar MVarId
- | WillTryTakeMVar MVarId
- | WillNewCRef
- | WillReadCRef CRefId
- | WillReadCRefCas CRefId
- | WillModCRef CRefId
- | WillModCRefCas CRefId
- | WillWriteCRef CRefId
- | WillCasCRef CRefId
- | WillCommitCRef ThreadId CRefId
- | WillSTM
- | WillCatching
- | WillPopCatching
- | WillThrow
- | WillThrowTo ThreadId
- | WillSetMasking Bool MaskingState
- | WillResetMasking Bool MaskingState
- | WillLiftIO
- | WillReturn
- | WillStop
- | WillSubconcurrency
- | WillStopSubconcurrency
- data MVarId
- data CRefId
- data MaskingState :: *
- showTrace :: Trace -> String
- showFail :: Failure -> String
- module Test.DejaFu.Schedule
The ConcT
monad transformer
Since: 0.6.0.0
MonadIO ConcIO Source # | |
MonadBase IO ConcIO Source # | |
MonadTrans (ConcT r) Source # | |
MonadRef (CRef r) (ConcT r n) Source # | |
MonadAtomicRef (CRef r) (ConcT r n) Source # | |
Monad (ConcT r n) Source # | |
Functor (ConcT r n) Source # | |
Applicative (ConcT r n) Source # | |
Monad n => MonadConc (ConcT r n) Source # | |
MonadThrow (ConcT r n) Source # | |
MonadCatch (ConcT r n) Source # | |
MonadMask (ConcT r n) Source # | |
type ThreadId (ConcT r n) Source # | |
type Ticket (ConcT r n) Source # | |
type CRef (ConcT r n) Source # | |
type MVar (ConcT r n) Source # | |
type STM (ConcT r n) Source # | |
type ConcST t = ConcT (STRef t) (ST t) Source #
A MonadConc
implementation using ST
, this should be preferred
if you do not need liftIO
.
Since: 0.4.0.0
Executing computations
An indication of how a concurrent computation failed.
Since: 0.5.0.0
InternalError | Will be raised if the scheduler does something bad. This should never arise unless you write your own, faulty, scheduler! If it does, please file a bug report. |
Abort | The scheduler chose to abort execution. This will be produced if, for example, all possible decisions exceed the specified bounds (there have been too many pre-emptions, the computation has executed for too long, or there have been too many yields). |
Deadlock | The computation became blocked indefinitely on |
STMDeadlock | The computation became blocked indefinitely on |
UncaughtException | An uncaught exception bubbled to the top of the computation. |
IllegalSubconcurrency | Calls to |
The memory model to use for non-synchronised CRef
operations.
Since: 0.4.0.0
SequentialConsistency | The most intuitive model: a program behaves as a simple
interleaving of the actions in different threads. When a |
TotalStoreOrder | Each thread has a write buffer. A thread sees its writes immediately, but other threads will only see writes when they are committed, which may happen later. Writes are committed in the same order that they are created. |
PartialStoreOrder | Each |
runConcurrent :: MonadRef r n => Scheduler s -> MemType -> s -> ConcT r n a -> n (Either Failure a, s, Trace) Source #
Run a concurrent computation with a given Scheduler
and initial
state, returning a failure reason on error. Also returned is the
final state of the scheduler, and an execution trace.
Warning: Blocking on the action of another thread in liftIO
cannot be detected! So if you perform some potentially blocking
action in a liftIO
the entire collection of threads may deadlock!
You should therefore keep IO
blocks small, and only perform
blocking operations with the supplied primitives, insofar as
possible.
Note: In order to prevent computation from hanging, the runtime will assume that a deadlock situation has arisen if the scheduler attempts to (a) schedule a blocked thread, or (b) schedule a nonexistent thread. In either of those cases, the computation will be halted.
Since: 0.6.0.0
subconcurrency :: ConcT r n a -> ConcT r n (Either Failure a) Source #
Run a concurrent computation and return its result.
This can only be called in the main thread, when no other threads
exist. Calls to subconcurrency
cannot be nested. Violating either
of these conditions will result in the computation failing with
IllegalSubconcurrency
.
Since: 0.6.0.0
Execution traces
type Trace = [(Decision, [(ThreadId, NonEmpty Lookahead)], ThreadAction)] Source #
One of the outputs of the runner is a Trace
, which is a log of
decisions made, all the runnable threads and what they would do,
and the action a thread took in its step.
Since: 0.5.0.0
Scheduling decisions are based on the state of the running program, and so we can capture some of that state in recording what specific decision we made.
Since: 0.5.0.0
Every live thread has a unique identitifer.
Since: 0.4.0.0
data ThreadAction Source #
All the actions that a thread can perform.
Since: 0.5.0.2
Fork ThreadId | Start a new thread. |
MyThreadId | Get the |
GetNumCapabilities Int | Get the number of Haskell threads that can run simultaneously. |
SetNumCapabilities Int | Set the number of Haskell threads that can run simultaneously. |
Yield | Yield the current thread. |
NewMVar MVarId | Create a new |
PutMVar MVarId [ThreadId] | Put into a |
BlockedPutMVar MVarId | Get blocked on a put. |
TryPutMVar MVarId Bool [ThreadId] | Try to put into a |
ReadMVar MVarId | Read from a |
TryReadMVar MVarId Bool | Try to read from a |
BlockedReadMVar MVarId | Get blocked on a read. |
TakeMVar MVarId [ThreadId] | Take from a |
BlockedTakeMVar MVarId | Get blocked on a take. |
TryTakeMVar MVarId Bool [ThreadId] | Try to take from a |
NewCRef CRefId | Create a new |
ReadCRef CRefId | Read from a |
ReadCRefCas CRefId | Read from a |
ModCRef CRefId | Modify a |
ModCRefCas CRefId | Modify a |
WriteCRef CRefId | Write to a |
CasCRef CRefId Bool | Attempt to to a |
CommitCRef ThreadId CRefId | Commit the last write to the given |
STM TTrace [ThreadId] | An STM transaction was executed, possibly waking up some threads. |
BlockedSTM TTrace | Got blocked in an STM transaction. |
Catching | Register a new exception handler |
PopCatching | Pop the innermost exception handler from the stack. |
Throw | Throw an exception. |
ThrowTo ThreadId | Throw an exception to a thread. |
BlockedThrowTo ThreadId | Get blocked on a |
Killed | Killed by an uncaught exception. |
SetMasking Bool MaskingState | Set the masking state. If |
ResetMasking Bool MaskingState | Return to an earlier masking state. If |
LiftIO | Lift an IO action. Note that this can only happen with
|
Return | |
Stop | Cease execution and terminate. |
Subconcurrency | Start executing an action with |
StopSubconcurrency | Stop executing an action with |
Eq ThreadAction Source # | |
Show ThreadAction Source # | |
NFData ThreadAction Source # | Since: 0.5.1.0 |
A one-step look-ahead at what a thread will do next.
Since: 0.5.0.2
WillFork | Will start a new thread. |
WillMyThreadId | Will get the |
WillGetNumCapabilities | Will get the number of Haskell threads that can run simultaneously. |
WillSetNumCapabilities Int | Will set the number of Haskell threads that can run simultaneously. |
WillYield | Will yield the current thread. |
WillNewMVar | Will create a new |
WillPutMVar MVarId | Will put into a |
WillTryPutMVar MVarId | Will try to put into a |
WillReadMVar MVarId | Will read from a |
WillTryReadMVar MVarId | Will try to read from a |
WillTakeMVar MVarId | Will take from a |
WillTryTakeMVar MVarId | Will try to take from a |
WillNewCRef | Will create a new |
WillReadCRef CRefId | Will read from a |
WillReadCRefCas CRefId | Will read from a |
WillModCRef CRefId | Will modify a |
WillModCRefCas CRefId | Will modify a |
WillWriteCRef CRefId | Will write to a |
WillCasCRef CRefId | Will attempt to to a |
WillCommitCRef ThreadId CRefId | Will commit the last write by the given thread to the |
WillSTM | Will execute an STM transaction, possibly waking up some threads. |
WillCatching | Will register a new exception handler |
WillPopCatching | Will pop the innermost exception handler from the stack. |
WillThrow | Will throw an exception. |
WillThrowTo ThreadId | Will throw an exception to a thread. |
WillSetMasking Bool MaskingState | Will set the masking state. If |
WillResetMasking Bool MaskingState | Will return to an earlier masking state. If |
WillLiftIO | Will lift an IO action. Note that this can only happen with
|
WillReturn | |
WillStop | Will cease execution and terminate. |
WillSubconcurrency | Will execute an action with |
WillStopSubconcurrency | Will stop executing an extion with |
Every MVar
has a unique identifier.
Since: 0.4.0.0
Every CRef
has a unique identifier.
Since: 0.4.0.0
data MaskingState :: * #
Describes the behaviour of a thread when an asynchronous exception is received.
Unmasked | asynchronous exceptions are unmasked (the normal state) |
MaskedInterruptible | the state during |
MaskedUninterruptible | the state during |
showTrace :: Trace -> String Source #
Pretty-print a trace, including a key of the thread IDs (not including thread 0). Each line of the key is indented by two spaces.
Since: 0.5.0.0
Scheduling
module Test.DejaFu.Schedule