Rename ThreadAction' to Lookahead

This commit is contained in:
Michael Walker 2015-08-26 22:48:38 +01:00
parent a1144610b2
commit 5ff263d96f
6 changed files with 118 additions and 120 deletions

View File

@ -55,7 +55,7 @@ module Test.DejaFu.Deterministic
, Trace
, Decision(..)
, ThreadAction(..)
, ThreadAction'(..)
, Lookahead(..)
, CVarId
, CRefId
, MaskingState(..)

View File

@ -59,7 +59,7 @@ module Test.DejaFu.Deterministic.IO
, Trace
, Decision(..)
, ThreadAction(..)
, ThreadAction'(..)
, Lookahead(..)
, CVarId
, MaskingState(..)
, Trace'

View File

@ -35,7 +35,7 @@ module Test.DejaFu.Deterministic.Internal
, Trace
, Decision(..)
, ThreadAction(..)
, ThreadAction'(..)
, Lookahead(..)
, Trace'
, showTrace
, toTrace
@ -155,30 +155,30 @@ runThreads fixed runstm sched origg origthreads idsrc ref = go idsrc [] Nothing
| otherwise = [(if Just t == prior then Continue else SwitchTo t, na) | (t, na) <- runnable', t /= chosen]
nextActions t = unsafeToNonEmpty . nextActions' . _continuation . fromJust $ M.lookup t threads
nextActions' (AFork _ _) = [Fork']
nextActions' (AMyTId _) = [MyThreadId']
nextActions' (ANew _) = [New']
nextActions' (APut (c, _) _ k) = Put' c : nextActions' k
nextActions' (ATryPut (c, _) _ _) = [TryPut' c]
nextActions' (AGet (c, _) _) = [Read' c]
nextActions' (ATake (c, _) _) = [Take' c]
nextActions' (ATryTake (c, _) _) = [TryTake' c]
nextActions' (ANewRef _) = [NewRef']
nextActions' (AReadRef (r, _) _) = [ReadRef' r]
nextActions' (AModRef (r, _) _ _) = [ModRef' r]
nextActions' (AAtom _ _) = [STM']
nextActions' (AThrow _) = [Throw']
nextActions' (AThrowTo tid _ k) = ThrowTo' tid : nextActions' k
nextActions' (ACatching _ _ _) = [Catching']
nextActions' (APopCatching k) = PopCatching' : nextActions' k
nextActions' (AMasking ms _ _) = [SetMasking' False ms]
nextActions' (AResetMask b1 b2 ms k) = (if b1 then SetMasking' else ResetMasking') b2 ms : nextActions' k
nextActions' (ALift _) = [Lift']
nextActions' (ANoTest _ _) = [NoTest']
nextActions' (AKnowsAbout _ k) = KnowsAbout' : nextActions' k
nextActions' (AForgets _ k) = Forgets' : nextActions' k
nextActions' (AAllKnown k) = AllKnown' : nextActions' k
nextActions' (AStop) = [Stop']
nextActions' (AFork _ _) = [WillFork]
nextActions' (AMyTId _) = [WillMyThreadId]
nextActions' (ANew _) = [WillNew]
nextActions' (APut (c, _) _ k) = WillPut c : nextActions' k
nextActions' (ATryPut (c, _) _ _) = [WillTryPut c]
nextActions' (AGet (c, _) _) = [WillRead c]
nextActions' (ATake (c, _) _) = [WillTake c]
nextActions' (ATryTake (c, _) _) = [WillTryTake c]
nextActions' (ANewRef _) = [WillNewRef]
nextActions' (AReadRef (r, _) _) = [WillReadRef r]
nextActions' (AModRef (r, _) _ _) = [WillModRef r]
nextActions' (AAtom _ _) = [WillSTM]
nextActions' (AThrow _) = [WillThrow]
nextActions' (AThrowTo tid _ k) = WillThrowTo tid : nextActions' k
nextActions' (ACatching _ _ _) = [WillCatching]
nextActions' (APopCatching k) = WillPopCatching : nextActions' k
nextActions' (AMasking ms _ _) = [WillSetMasking False ms]
nextActions' (AResetMask b1 b2 ms k) = (if b1 then WillSetMasking else WillResetMasking) b2 ms : nextActions' k
nextActions' (ALift _) = [WillLift]
nextActions' (ANoTest _ _) = [WillNoTest]
nextActions' (AKnowsAbout _ k) = WillKnowsAbout : nextActions' k
nextActions' (AForgets _ k) = WillForgets : nextActions' k
nextActions' (AAllKnown k) = WillAllKnown : nextActions' k
nextActions' (AStop) = [WillStop]
--------------------------------------------------------------------------------
-- * Single-step execution

View File

@ -112,17 +112,17 @@ initialIdSource = Id 0 0 0 0
-- attempts to (a) schedule a blocked thread, or (b) schedule a
-- nonexistent thread. In either of those cases, the computation will
-- be halted.
type Scheduler s = s -> Maybe (ThreadId, ThreadAction) -> NonEmpty (ThreadId, NonEmpty ThreadAction') -> (ThreadId, s)
type Scheduler s = s -> Maybe (ThreadId, ThreadAction) -> NonEmpty (ThreadId, NonEmpty Lookahead) -> (ThreadId, s)
-- | One of the outputs of the runner is a @Trace@, which is a log of
-- decisions made, alternative decisions (including what action would
-- have been performed had that decision been taken), and the action a
-- thread took in its step.
type Trace = [(Decision, [(Decision, ThreadAction')], ThreadAction)]
type Trace = [(Decision, [(Decision, Lookahead)], ThreadAction)]
-- | Like a 'Trace', but gives more lookahead (where possible) for
-- alternative decisions.
type Trace' = [(Decision, [(Decision, NonEmpty ThreadAction')], ThreadAction)]
type Trace' = [(Decision, [(Decision, NonEmpty Lookahead)], ThreadAction)]
-- | Throw away information from a 'Trace'' to get just a 'Trace'.
toTrace :: Trace' -> Trace
@ -249,78 +249,76 @@ instance NFData ThreadAction where
rnf (Read c) = rnf c
rnf ta = ta `seq` ()
-- | A simplified view of the actions that a thread can perform.
data ThreadAction' =
Fork'
-- ^ Start a new thread.
| MyThreadId'
-- ^ Get the 'ThreadId' of the current thread.
| New'
-- ^ Create a new 'CVar'.
| Put' CVarId
-- ^ Put into a 'CVar', possibly waking up some threads.
| TryPut' CVarId
-- ^ Try to put into a 'CVar', possibly waking up some threads.
| Read' CVarId
-- ^ Read from a 'CVar'.
| Take' CVarId
-- ^ Take from a 'CVar', possibly waking up some threads.
| TryTake' CVarId
-- ^ Try to take from a 'CVar', possibly waking up some threads.
| NewRef'
-- ^ Create a new 'CRef'.
| ReadRef' CRefId
-- ^ Read from a 'CRef'.
| ModRef' CRefId
-- ^ Modify a 'CRef'.
| STM'
-- ^ An STM transaction was executed, possibly waking up some
-- | A one-step look-ahead at what a thread will do next.
data Lookahead =
WillFork
-- ^ Will start a new thread.
| WillMyThreadId
-- ^ Will get the 'ThreadId'.
| WillNew
-- ^ Will create a new 'CVar'.
| WillPut CVarId
-- ^ Will put into a 'CVar', possibly waking up some threads.
| WillTryPut CVarId
-- ^ Will try to put into a 'CVar', possibly waking up some threads.
| WillRead CVarId
-- ^ Will read from a 'CVar'.
| WillTake CVarId
-- ^ Will take from a 'CVar', possibly waking up some threads.
| WillTryTake CVarId
-- ^ Will try to take from a 'CVar', possibly waking up some threads.
| WillNewRef
-- ^ Will create a new 'CRef'.
| WillReadRef CRefId
-- ^ Will read from a 'CRef'.
| WillModRef CRefId
-- ^ Will modify a 'CRef'.
| WillSTM
-- ^ Will execute an STM transaction, possibly waking up some
-- threads.
| 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.
| Killed'
-- ^ Killed by an uncaught exception.
| SetMasking' Bool MaskingState
-- ^ Set the masking state. If 'True', this is being used to set the
-- masking state to the original state in the argument passed to a
-- 'mask'ed function.
| ResetMasking' Bool MaskingState
-- ^ Return to an earlier masking state. If 'True', this is being
-- used to return to the state of the masked block in the argument
| 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 'True', this is being used to
-- set the masking state to the original state in the argument
-- passed to a 'mask'ed function.
| Lift'
-- ^ Lift an action from the underlying monad. Note that the
| WillResetMasking Bool MaskingState
-- ^ Will return to an earlier masking state. If 'True', this is
-- being used to return to the state of the masked block in the
-- argument passed to a 'mask'ed function.
| WillLift
-- ^ Will lift an action from the underlying monad. Note that the
-- penultimate action in a trace will always be a @Lift@, this is an
-- artefact of how the runner works.
| NoTest'
-- ^ A computation annotated with '_concNoTest' was executed in a
| WillNoTest
-- ^ Will execute a computation annotated with '_concNoTest' in a
-- single step.
| KnowsAbout'
-- ^ A '_concKnowsAbout' annotation was processed.
| Forgets'
-- ^ A '_concForgets' annotation was processed.
| AllKnown'
-- ^ A '_concALlKnown' annotation was processed.
| Stop'
-- ^ Cease execution and terminate.
| WillKnowsAbout
-- ^ Will process a '_concKnowsAbout' annotation.
| WillForgets
-- ^ Will process a '_concForgets' annotation.
| WillAllKnown
-- ^ Will process a '_concALlKnown' annotation.
| WillStop
-- ^ Will cease execution and terminate.
deriving (Eq, Show)
instance NFData ThreadAction' where
rnf (SetMasking' b ms) = b `seq` ms `seq` ()
rnf (ResetMasking' b ms) = b `seq` ms `seq` ()
rnf (Put' c) = rnf c
rnf (TryPut' c) = rnf c
rnf (Read' c) = rnf c
rnf (Take' c) = rnf c
rnf (TryTake' c) = rnf c
rnf (ReadRef' c) = rnf c
rnf (ModRef' c) = rnf c
instance NFData Lookahead where
rnf (WillSetMasking b ms) = b `seq` ms `seq` ()
rnf (WillResetMasking b ms) = b `seq` ms `seq` ()
rnf (WillPut c) = rnf c
rnf (WillTryPut c) = rnf c
rnf (WillRead c) = rnf c
rnf (WillTake c) = rnf c
rnf (WillTryTake c) = rnf c
rnf (WillReadRef c) = rnf c
rnf (WillModRef c) = rnf c
rnf ta = ta `seq` ()
--------------------------------------------------------------------------------

View File

@ -128,7 +128,7 @@ sctBounded :: ([Decision] -> Bool)
-- the execution so far, the index to insert the
-- backtracking point, and the thread to backtrack to. This
-- may insert more than one backtracking point.
-> (Maybe (ThreadId, ThreadAction) -> NonEmpty (ThreadId, ThreadAction') -> NonEmpty ThreadId)
-> (Maybe (ThreadId, ThreadAction) -> NonEmpty (ThreadId, Lookahead) -> NonEmpty ThreadId)
-- ^ Produce possible scheduling decisions, all will be
-- tried.
-> (forall t. Conc t a) -> [(Either Failure a, Trace)]
@ -138,7 +138,7 @@ sctBounded bv backtrack initialise c = runIdentity $ sctBoundedM bv backtrack in
-- | Variant of 'sctBounded' for computations which do 'IO'.
sctBoundedIO :: ([Decision] -> Bool)
-> ([BacktrackStep] -> Int -> ThreadId -> [BacktrackStep])
-> (Maybe (ThreadId, ThreadAction) -> NonEmpty (ThreadId, ThreadAction') -> NonEmpty ThreadId)
-> (Maybe (ThreadId, ThreadAction) -> NonEmpty (ThreadId, Lookahead) -> NonEmpty ThreadId)
-> (forall t. ConcIO t a) -> IO [(Either Failure a, Trace)]
sctBoundedIO bv backtrack initialise c = sctBoundedM bv backtrack initialise run where
run sched s = runConcIO' sched s c
@ -147,7 +147,7 @@ sctBoundedIO bv backtrack initialise c = sctBoundedM bv backtrack initialise run
sctBoundedM :: (Functor m, Monad m)
=> ([Decision] -> Bool)
-> ([BacktrackStep] -> Int -> ThreadId -> [BacktrackStep])
-> (Maybe (ThreadId, ThreadAction) -> NonEmpty (ThreadId, ThreadAction') -> NonEmpty ThreadId)
-> (Maybe (ThreadId, ThreadAction) -> NonEmpty (ThreadId, Lookahead) -> NonEmpty ThreadId)
-> (Scheduler SchedState -> SchedState -> m (Either Failure a, SchedState, Trace'))
-- ^ Monadic runner, with computation fixed.
-> m [(Either Failure a, Trace)]
@ -170,7 +170,7 @@ sctBoundedM bv backtrack initialise run = go initialState where
data SchedState = SchedState
{ _sprefix :: [ThreadId]
-- ^ Decisions still to make
, _sbpoints :: Seq (NonEmpty (ThreadId, ThreadAction'), [ThreadId])
, _sbpoints :: Seq (NonEmpty (ThreadId, Lookahead), [ThreadId])
-- ^ Which threads are runnable at each step, and the alternative
-- decisions still to make.
, _scvstate :: IntMap Bool
@ -188,7 +188,7 @@ initialSchedState prefix = SchedState
-- | BPOR scheduler: takes a list of decisions, and maintains a trace
-- including the runnable threads, and the alternative choices allowed
-- by the bound-specific initialise function.
bporSched :: (Maybe (ThreadId, ThreadAction) -> NonEmpty (ThreadId, ThreadAction') -> NonEmpty ThreadId)
bporSched :: (Maybe (ThreadId, ThreadAction) -> NonEmpty (ThreadId, Lookahead) -> NonEmpty ThreadId)
-> Scheduler SchedState
bporSched initialise = force $ \s prior threads -> case _sprefix s of
-- If there is a decision available, make it

View File

@ -107,7 +107,7 @@ next = go 0 where
-- | Produce a list of new backtracking points from an execution
-- trace.
findBacktrack :: ([BacktrackStep] -> Int -> ThreadId -> [BacktrackStep])
-> Seq (NonEmpty (ThreadId, ThreadAction'), [ThreadId])
-> Seq (NonEmpty (ThreadId, Lookahead), [ThreadId])
-> Trace'
-> [BacktrackStep]
findBacktrack backtrack = go S.empty 0 [] . Sq.viewl where
@ -265,16 +265,16 @@ dependent d1 (_, d2) = cref || cvar || ctvar where
ctvar' _ = False
-- | Variant of 'dependent' to handle 'ThreadAction''s
dependent' :: ThreadAction -> (ThreadId, ThreadAction') -> Bool
dependent' Lift (_, Lift') = True
dependent' :: ThreadAction -> (ThreadId, Lookahead) -> Bool
dependent' Lift (_, WillLift) = True
dependent' (ThrowTo t) (t2, _) = t == t2
dependent' d1 (_, d2) = cref || cvar || ctvar where
cref = Just True == ((\(r1, w1) (r2, w2) -> r1 == r2 && (w1 || w2)) <$> cref' d1 <*> cref'' d2)
cref' (ReadRef r) = Just (r, False)
cref' (ModRef r) = Just (r, True)
cref' _ = Nothing
cref'' (ReadRef' r) = Just (r, False)
cref'' (ModRef' r) = Just (r, True)
cref'' (WillReadRef r) = Just (r, False)
cref'' (WillModRef r) = Just (r, True)
cref'' _ = Nothing
cvar = Just True == ((==) <$> cvar' d1 <*> cvar'' d2)
@ -284,17 +284,17 @@ dependent' d1 (_, d2) = cref || cvar || ctvar where
cvar' (Read c) = Just c
cvar' (Take c _) = Just c
cvar' _ = Nothing
cvar'' (TryPut' c) = Just c
cvar'' (TryTake' c) = Just c
cvar'' (Put' c) = Just c
cvar'' (Read' c) = Just c
cvar'' (Take' c) = Just c
cvar'' (WillTryPut c) = Just c
cvar'' (WillTryTake c) = Just c
cvar'' (WillPut c) = Just c
cvar'' (WillRead c) = Just c
cvar'' (WillTake c) = Just c
cvar'' _ = Nothing
ctvar = ctvar' d1 && ctvar'' d2
ctvar' (STM _) = True
ctvar' _ = False
ctvar'' STM' = True
ctvar'' WillSTM = True
ctvar'' _ = False
-- * Keeping track of 'CVar' full/empty states
@ -312,18 +312,18 @@ updateCVState cvstate (TryTake c True _) = I.insert c False cvstate
updateCVState cvstate _ = cvstate
-- | Check if an action will block.
willBlock :: IntMap Bool -> ThreadAction' -> Bool
willBlock cvstate (Put' c) = I.lookup c cvstate == Just True
willBlock cvstate (Take' c) = I.lookup c cvstate == Just False
willBlock :: IntMap Bool -> Lookahead -> Bool
willBlock cvstate (WillPut c) = I.lookup c cvstate == Just True
willBlock cvstate (WillTake c) = I.lookup c cvstate == Just False
willBlock _ _ = False
-- | Check if a list of actions will block safely (without modifying
-- any global state). This allows further lookahead at, say, the
-- 'spawn' of a thread (which always starts with 'KnowsAbout'.
willBlockSafely :: IntMap Bool -> [ThreadAction'] -> Bool
willBlockSafely cvstate (KnowsAbout':as) = willBlockSafely cvstate as
willBlockSafely cvstate (Forgets':as) = willBlockSafely cvstate as
willBlockSafely cvstate (AllKnown':as) = willBlockSafely cvstate as
willBlockSafely cvstate (Put' c:_) = willBlock cvstate (Put' c)
willBlockSafely cvstate (Take' c:_) = willBlock cvstate (Take' c)
willBlockSafely :: IntMap Bool -> [Lookahead] -> Bool
willBlockSafely cvstate (WillKnowsAbout:as) = willBlockSafely cvstate as
willBlockSafely cvstate (WillForgets:as) = willBlockSafely cvstate as
willBlockSafely cvstate (WillAllKnown:as) = willBlockSafely cvstate as
willBlockSafely cvstate (WillPut c:_) = willBlock cvstate (WillPut c)
willBlockSafely cvstate (WillTake c:_) = willBlock cvstate (WillTake c)
willBlockSafely _ _ = False