packages feed

dejafu 0.7.1.2 → 0.7.1.3

raw patch · 5 files changed

+159/−128 lines, 5 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Test.DejaFu.SCT.Internal: instance Control.DeepSeq.NFData Test.DejaFu.SCT.Internal.DPORSchedState
- Test.DejaFu.SCT.Internal: instance GHC.Classes.Eq Test.DejaFu.SCT.Internal.DPORSchedState
- Test.DejaFu.SCT.Internal: instance GHC.Show.Show Test.DejaFu.SCT.Internal.DPORSchedState
- Test.DejaFu.SCT.Internal: type BoundFunc = [(Decision, ThreadAction)] -> (Decision, Lookahead) -> Bool
+ Test.DejaFu.SCT.Internal: [schedBState] :: DPORSchedState k -> Maybe k
+ Test.DejaFu.SCT.Internal: instance Control.DeepSeq.NFData k => Control.DeepSeq.NFData (Test.DejaFu.SCT.Internal.DPORSchedState k)
+ Test.DejaFu.SCT.Internal: instance GHC.Classes.Eq k => GHC.Classes.Eq (Test.DejaFu.SCT.Internal.DPORSchedState k)
+ Test.DejaFu.SCT.Internal: instance GHC.Show.Show k => GHC.Show.Show (Test.DejaFu.SCT.Internal.DPORSchedState k)
+ Test.DejaFu.SCT.Internal: type IncrementalBoundFunc k = Maybe k -> Maybe (ThreadId, ThreadAction) -> (Decision, Lookahead) -> Maybe k
- Test.DejaFu.SCT.Internal: DPORSchedState :: Map ThreadId ThreadAction -> [ThreadId] -> Seq (NonEmpty (ThreadId, Lookahead), [ThreadId]) -> Bool -> Bool -> DepState -> DPORSchedState
+ Test.DejaFu.SCT.Internal: DPORSchedState :: Map ThreadId ThreadAction -> [ThreadId] -> Seq ([(ThreadId, Lookahead)], [ThreadId]) -> Bool -> Bool -> DepState -> Maybe k -> DPORSchedState k
- Test.DejaFu.SCT.Internal: [schedBPoints] :: DPORSchedState -> Seq (NonEmpty (ThreadId, Lookahead), [ThreadId])
+ Test.DejaFu.SCT.Internal: [schedBPoints] :: DPORSchedState k -> Seq ([(ThreadId, Lookahead)], [ThreadId])
- Test.DejaFu.SCT.Internal: [schedBoundKill] :: DPORSchedState -> Bool
+ Test.DejaFu.SCT.Internal: [schedBoundKill] :: DPORSchedState k -> Bool
- Test.DejaFu.SCT.Internal: [schedDepState] :: DPORSchedState -> DepState
+ Test.DejaFu.SCT.Internal: [schedDepState] :: DPORSchedState k -> DepState
- Test.DejaFu.SCT.Internal: [schedIgnore] :: DPORSchedState -> Bool
+ Test.DejaFu.SCT.Internal: [schedIgnore] :: DPORSchedState k -> Bool
- Test.DejaFu.SCT.Internal: [schedPrefix] :: DPORSchedState -> [ThreadId]
+ Test.DejaFu.SCT.Internal: [schedPrefix] :: DPORSchedState k -> [ThreadId]
- Test.DejaFu.SCT.Internal: [schedSleep] :: DPORSchedState -> Map ThreadId ThreadAction
+ Test.DejaFu.SCT.Internal: [schedSleep] :: DPORSchedState k -> Map ThreadId ThreadAction
- Test.DejaFu.SCT.Internal: data DPORSchedState
+ Test.DejaFu.SCT.Internal: data DPORSchedState k
- Test.DejaFu.SCT.Internal: dporSched :: MemType -> BoundFunc -> Scheduler DPORSchedState
+ Test.DejaFu.SCT.Internal: dporSched :: MemType -> IncrementalBoundFunc k -> Scheduler (DPORSchedState k)
- Test.DejaFu.SCT.Internal: findBacktrackSteps :: MemType -> BacktrackFunc -> Bool -> Seq (NonEmpty (ThreadId, Lookahead), [ThreadId]) -> Trace -> [BacktrackStep]
+ Test.DejaFu.SCT.Internal: findBacktrackSteps :: MemType -> BacktrackFunc -> Bool -> Seq ([(ThreadId, Lookahead)], [ThreadId]) -> Trace -> [BacktrackStep]
- Test.DejaFu.SCT.Internal: incorporateBacktrackSteps :: ([(Decision, ThreadAction)] -> (Decision, Lookahead) -> Bool) -> [BacktrackStep] -> DPOR -> DPOR
+ Test.DejaFu.SCT.Internal: incorporateBacktrackSteps :: [BacktrackStep] -> DPOR -> DPOR
- Test.DejaFu.SCT.Internal: initialDPORSchedState :: Map ThreadId ThreadAction -> [ThreadId] -> DPORSchedState
+ Test.DejaFu.SCT.Internal: initialDPORSchedState :: Map ThreadId ThreadAction -> [ThreadId] -> DPORSchedState k

Files

CHANGELOG.markdown view
@@ -7,8 +7,26 @@ *de facto* standard Haskell versioning scheme.  +0.7.1.3+-------++- **Date**    2017-09-08+- **Git tag** [dejafu-0.7.1.3][]+- **Hackage** https://hackage.haskell.org/package/dejafu-0.7.1.3++### Miscellaneous++- Aborted STM transactions are now rolled back correctly (issue #111).+- Slightly improved run-time of systematic testing.++[dejafu-0.7.1.3]: https://github.com/barrucadu/dejafu/releases/tag/dejafu-0.7.1.3+++---------------------------------------------------------------------------------------------------++ 0.7.1.2-----------+-------  - **Date**    2017-08-21 - **Git tag** [dejafu-0.7.1.2][]
Test/DejaFu/SCT.hs view
@@ -111,6 +111,7 @@ import           Control.Monad.Ref        (MonadRef) import           Data.List                (foldl') import qualified Data.Map.Strict          as M+import           Data.Maybe               (fromMaybe) import           Data.Set                 (Set) import qualified Data.Set                 as S import           System.Random            (RandomGen, randomR)@@ -354,11 +355,11 @@   }  -- | Combination bound function-cBound :: Bounds -> BoundFunc+cBound :: Bounds -> IncrementalBoundFunc (((Int, Maybe ThreadId), M.Map ThreadId Int), Int) cBound (Bounds pb fb lb) =-  maybe trueBound pBound pb &+&-  maybe trueBound fBound fb &+&-  maybe trueBound lBound lb+  maybe (trueBound (0, Nothing)) pBound pb &+&+  maybe (trueBound M.empty)      fBound fb &+&+  maybe (trueBound 0)            lBound lb  -- | Combination backtracking function. Add all backtracking points -- corresponding to enabled bound functions.@@ -384,8 +385,10 @@  -- | Pre-emption bound function. This does not count pre-emptive -- context switches to a commit thread.-pBound :: PreemptionBound -> BoundFunc-pBound (PreemptionBound pb) ts dl = preEmpCount ts dl <= pb+pBound :: PreemptionBound -> IncrementalBoundFunc (Int, Maybe ThreadId)+pBound (PreemptionBound pb) k prior lhead =+  let k'@(pcount, _) = preEmpCountInc (fromMaybe (0, Nothing) k) prior lhead+  in if pcount <= pb then Just k' else Nothing  -- | Add a backtrack point, and also conservatively add one prior to -- the most recent transition before that point. This may result in@@ -420,8 +423,10 @@   rnf (FairBound i) = rnf i  -- | Fair bound function-fBound :: FairBound -> BoundFunc-fBound (FairBound fb) ts (_, l) = maxYieldCountDiff ts l <= fb+fBound :: FairBound -> IncrementalBoundFunc (M.Map ThreadId Int)+fBound (FairBound fb) k prior lhead =+  let k' = yieldCountInc (fromMaybe M.empty k) prior lhead+  in if maxDiff (M.elems k') <= fb then Just k' else Nothing  -- | Add a backtrack point. If the thread isn't runnable, or performs -- a release operation, add all runnable threads.@@ -443,8 +448,10 @@   rnf (LengthBound i) = rnf i  -- | Length bound function-lBound :: LengthBound -> BoundFunc-lBound (LengthBound lb) ts _ = length ts < lb+lBound :: LengthBound -> IncrementalBoundFunc Int+lBound (LengthBound lb) len _ _ =+  let len' = maybe 1 (+1) len+  in if len' < lb then Just len' else Nothing  -- | Add a backtrack point. If the thread isn't runnable, add all -- runnable threads.@@ -505,7 +512,7 @@        if schedIgnore s         then go (force newDPOR)-        else checkDiscard discard res trace $ go (force (addBacktracks bpoints newDPOR))+        else checkDiscard discard res trace $ go (force (incorporateBacktrackSteps bpoints newDPOR))      Nothing -> pure [] @@ -518,9 +525,6 @@   -- Incorporate a trace into the DPOR tree.   addTrace = incorporateTrace memtype -  -- Incorporate the new backtracking steps into the DPOR tree.-  addBacktracks = incorporateBacktrackSteps (cBound cb)- -- | SCT via uniform random scheduling. -- -- Schedules are generated by assigning to each new thread a random@@ -619,63 +623,71 @@ ------------------------------------------------------------------------------- -- Utilities +-- | An incremental version of 'preEmpCount', going one step at a time.+preEmpCountInc+  :: (Int, Maybe ThreadId)+  -- ^ The number of preemptions so far and, if currently executing a+  -- commit thread, what the prior thread was.+  -> Maybe (ThreadId, ThreadAction)+  -- ^ What just happened.+  -> (Decision, a)+  -- ^ What's coming up.+  -> (Int, Maybe ThreadId)+preEmpCountInc (sofar, lastnoncommit) prior (d, _) = case (prior, d) of+    (Just (tid, _),   Start    tnext) -> cswitch tid tnext False+    (Just (tid, act), SwitchTo tnext) -> cswitch tid tnext (not (didYield act))+    (_, Continue) -> (sofar, lastnoncommit)+    (Nothing, _)  -> (sofar, lastnoncommit)+  where+    cswitch tid tnext isPreemptive+      | isCommitThread tnext = (sofar, if isCommitThread tid then lastnoncommit else Just tid)+      | isCommitThread tid   = (if lastnoncommit == Just tnext then sofar else sofar + 1, Nothing)+      | otherwise = (if isPreemptive then sofar + 1 else sofar, Nothing)++    isCommitThread = (< initialThread)++-- | An incremental count of yields, going one step at a time.+yieldCountInc+  :: M.Map ThreadId Int+  -- ^ The number of yields of each thread so far+  -> Maybe (ThreadId, a)+  -- ^ What just happened.+  -> (Decision, Lookahead)+  -- ^ What's coming up.+  -> M.Map ThreadId Int+yieldCountInc sofar prior (d, lnext) = case prior of+    Just (tid, _) -> ycount (tidOf tid d)+    Nothing       -> ycount initialThread+  where+    ycount tnext = case lnext of+      WillYield -> M.alter (Just . maybe 1 (+1)) tnext sofar+      _ -> M.alter (Just . maybe 0 id) tnext sofar+ -- | Determine if an action is a commit or not. isCommitRef :: ThreadAction -> Bool isCommitRef (CommitCRef _ _) = True isCommitRef _ = False --- | Extra threads created in a fork.-forkTids :: ThreadAction -> [ThreadId]-forkTids (Fork t) = [t]-forkTids _ = []---- | Count the number of yields by a thread in a schedule prefix.-yieldCount :: ThreadId-  -- ^ The thread to count yields for.-  -> [(Decision, ThreadAction)]-  -> Lookahead-  -> Int-yieldCount tid ts l = go initialThread ts where-  go t ((Start    t', act):rest) = go' t t' act rest-  go t ((SwitchTo t', act):rest) = go' t t' act rest-  go t ((Continue,    act):rest) = go' t t  act rest-  go t []-    | t == tid && willYield l = 1-    | otherwise = 0--  {-# INLINE go' #-}-  go' t t' act rest-    | t == tid && didYield act = 1 + go t' rest-    | otherwise = go t' rest---- | Get the maximum difference between the yield counts of all--- threads in this schedule prefix.-maxYieldCountDiff :: [(Decision, ThreadAction)]-  -> Lookahead-  -> Int-maxYieldCountDiff ts l = go 0 yieldCounts where-  go m (yc:ycs) =-    let m' = m `max` foldl' (go' yc) 0 ycs-    in go m' ycs+-- | Get the maximum difference between two ints in a list.+maxDiff :: [Int] -> Int+maxDiff = go 0 where+  go m (x:xs) =+    let m' = m `max` foldl' (go' x) 0 xs+    in go m' xs   go m [] = m-  go' yc0 m yc = m `max` abs (yc0 - yc)--  yieldCounts = [yieldCount t ts l | t <- allTids ts]--  -- All the threads created during the lifetime of the system.-  allTids ((_, act):rest) =-    let tids' = forkTids act-    in if null tids' then allTids rest else tids' ++ allTids rest-  allTids [] = [initialThread]+  go' x0 m x = m `max` abs (x0 - x)  -- | The \"true\" bound, which allows everything.-trueBound :: BoundFunc-trueBound _ _ = True+trueBound :: k -> IncrementalBoundFunc k+trueBound k _ _ _ = Just k  -- | Combine two bounds into a larger bound, where both must be -- satisfied.-(&+&) :: BoundFunc -> BoundFunc -> BoundFunc-(&+&) b1 b2 ts dl = b1 ts dl && b2 ts dl+(&+&) :: IncrementalBoundFunc k1 -> IncrementalBoundFunc k2 -> IncrementalBoundFunc (k1, k2)+(&+&) f1 f2 ks prior lhead =+  let k1' = f1 (fst <$> ks) prior lhead+      k2' = f2 (snd <$> ks) prior lhead+  in (,) <$> k1' <*> k2'  -- | Apply the discard function. checkDiscard :: Functor f => (a -> Maybe Discard) -> a -> [b] -> f [(a, [b])] -> f [(a, [b])]
Test/DejaFu/SCT/Internal.hs view
@@ -1,10 +1,12 @@+{-# LANGUAGE TupleSections #-}+ -- | -- Module      : Test.DejaFu.SCT.Internal -- Copyright   : (c) 2016 Michael Walker -- License     : MIT -- Maintainer  : Michael Walker <mike@barrucadu.co.uk> -- Stability   : experimental--- Portability : portable+-- Portability : TupleSections -- -- Internal types and functions for dynamic partial-order -- reduction. This module is NOT considered to form part of the public@@ -17,7 +19,7 @@ import qualified Data.Foldable        as F import           Data.Function        (on) import           Data.List            (nubBy, partition, sortOn)-import           Data.List.NonEmpty   (NonEmpty(..), toList)+import           Data.List.NonEmpty   (toList) import           Data.Map.Strict      (Map) import qualified Data.Map.Strict      as M import           Data.Maybe           (catMaybes, fromJust, fromMaybe, isJust,@@ -216,9 +218,9 @@   -> Bool   -- ^ Whether the computation was aborted due to no decisions being   -- in-bounds.-  -> Seq (NonEmpty (ThreadId, Lookahead), [ThreadId])-  -- ^ A sequence of threads at each step: the nonempty list of-  -- runnable threads (with lookahead values), and the list of threads+  -> Seq ([(ThreadId, Lookahead)], [ThreadId])+  -- ^ A sequence of threads at each step: the list of runnable+  -- in-bound threads (with lookahead values), and the list of threads   -- still to try. The reason for the two separate lists is because   -- the threads chosen to try will be dependent on the specific   -- domain.@@ -235,11 +237,11 @@           { bcktThreadid   = tid'           , bcktDecision   = d           , bcktAction     = a-          , bcktRunnable   = M.fromList . toList $ e+          , bcktRunnable   = M.fromList e           , bcktBacktracks = M.fromList $ map (\i' -> (i', False)) i           , bcktState      = state'           }-        bs' = doBacktrack killsEarly allThreads' (toList e) (bs++[this])+        bs' = doBacktrack killsEarly allThreads' e (bs++[this])         runnable = S.fromList (M.keys $ bcktRunnable this)         allThreads' = allThreads `S.union` runnable         killsEarly = null ts && boundKill@@ -280,53 +282,44 @@     in backtrack bs idxs  -- | Add new backtracking points, if they have not already been--- visited, fit into the bound, and aren't in the sleep set.-incorporateBacktrackSteps-  :: ([(Decision, ThreadAction)] -> (Decision, Lookahead) -> Bool)-  -- ^ Bound function: returns true if that schedule prefix terminated-  -- with the lookahead decision fits within the bound.-  -> [BacktrackStep]-  -- ^ Backtracking steps identified by 'findBacktrackSteps'.-  -> DPOR-  -> DPOR-incorporateBacktrackSteps bv = go Nothing [] where-  go priorTid pref (b:bs) dpor =-    let dpor' = doBacktrack priorTid pref b dpor-        tid   = bcktThreadid b-        pref' = pref ++ [(bcktDecision b, bcktAction b)]-        child = case dporNext dpor of-                  Just (t, d)-                    | t /= tid -> err "incorporateBacktrackSteps" "incorporating wrong trace!"-                    | otherwise -> go (Just t) pref' bs d-                  Nothing -> err "incorporateBacktrackSteps" "child is missing!"-    in dpor' { dporNext = Just (tid, child) }-  go _ _ [] dpor = dpor+-- visited and aren't in the sleep set.+incorporateBacktrackSteps :: [BacktrackStep] -> DPOR -> DPOR+incorporateBacktrackSteps (b:bs) dpor = dpor' where+  tid = bcktThreadid b -  doBacktrack priorTid pref b dpor =-    let todo' = [ x-                | x@(t,c) <- M.toList $ bcktBacktracks b-                , let decision  = decisionOf priorTid (dporRunnable dpor) t-                , let lahead = fromJust . M.lookup t $ bcktRunnable b-                , bv pref (decision, lahead)-                , Just t /= (fst <$> dporNext dpor)-                , S.notMember t (dporDone dpor)-                , c || M.notMember t (dporSleep dpor)-                ]-    in dpor { dporTodo = dporTodo dpor `M.union` M.fromList todo' }+  dpor' = dpor+    { dporTodo = dporTodo dpor `M.union` M.fromList todo+    , dporNext = Just (tid, child)+    } +  todo =+    [ x+    | x@(t,c) <- M.toList $ bcktBacktracks b+    , Just t /= (fst <$> dporNext dpor)+    , S.notMember t (dporDone dpor)+    , c || M.notMember t (dporSleep dpor)+    ]++  child = case dporNext dpor of+    Just (t, d)+      | t /= tid -> err "incorporateBacktrackSteps" "incorporating wrong trace!"+      | otherwise -> incorporateBacktrackSteps bs d+    Nothing -> err "incorporateBacktrackSteps" "child is missing!"+incorporateBacktrackSteps [] dpor = dpor+ ------------------------------------------------------------------------------- -- * DPOR scheduler  -- | The scheduler state-data DPORSchedState = DPORSchedState+data DPORSchedState k = DPORSchedState   { schedSleep     :: Map ThreadId ThreadAction   -- ^ The sleep set: decisions not to make until something dependent   -- with them happens.   , schedPrefix    :: [ThreadId]   -- ^ Decisions still to make-  , schedBPoints   :: Seq (NonEmpty (ThreadId, Lookahead), [ThreadId])-  -- ^ Which threads are runnable at each step, and the alternative-  -- decisions still to make.+  , schedBPoints   :: Seq ([(ThreadId, Lookahead)], [ThreadId])+  -- ^ Which threads are runnable and in-bound at each step, and the+  -- alternative decisions still to make.   , schedIgnore    :: Bool   -- ^ Whether to ignore this execution or not: @True@ if the   -- execution is aborted due to all possible decisions being in the@@ -338,15 +331,18 @@   , schedDepState  :: DepState   -- ^ State used by the dependency function to determine when to   -- remove decisions from the sleep set.+  , schedBState    :: Maybe k+  -- ^ State used by the incremental bounding function.   } deriving (Eq, Show) -instance NFData DPORSchedState where+instance NFData k => NFData (DPORSchedState k) where   rnf s = rnf ( schedSleep     s               , schedPrefix    s               , schedBPoints   s               , schedIgnore    s               , schedBoundKill s               , schedDepState  s+              , schedBState    s               )  -- | Initial DPOR scheduler state for a given prefix@@ -354,7 +350,7 @@   -- ^ The initial sleep set.   -> [ThreadId]   -- ^ The schedule prefix.-  -> DPORSchedState+  -> DPORSchedState k initialDPORSchedState sleep prefix = DPORSchedState   { schedSleep     = sleep   , schedPrefix    = prefix@@ -362,13 +358,14 @@   , schedIgnore    = False   , schedBoundKill = False   , schedDepState  = initialDepState+  , schedBState    = Nothing   } --- | A bounding function takes the scheduling decisions so far and a--- decision chosen to come next, and returns if that decision is--- within the bound.-type BoundFunc-  = [(Decision, ThreadAction)] -> (Decision, Lookahead) -> Bool+-- | An incremental bounding function is a stateful function that+-- takes the last and next decisions, and returns a new state only if+-- the next decision is within the bound.+type IncrementalBoundFunc k+  = Maybe k -> Maybe (ThreadId, ThreadAction) -> (Decision, Lookahead) -> Maybe k  -- | A backtracking step is a point in the execution where another -- decision needs to be made, in order to explore interesting new@@ -439,21 +436,23 @@ dporSched   :: MemType   -- ^ Memory model.-  -> BoundFunc+  -> IncrementalBoundFunc k   -- ^ Bound function: returns true if that schedule prefix terminated   -- with the lookahead decision fits within the bound.-  -> Scheduler DPORSchedState-dporSched memtype inBound trc prior threads s = schedule where+  -> Scheduler (DPORSchedState k)+dporSched memtype boundf _ prior threads s = schedule where   -- Pick a thread to run.   schedule = case schedPrefix s of     -- If there is a decision available, make it-    (d:ds) -> (Just d, (nextState []) { schedPrefix = ds })+    (t:ts) ->+      let bstate' = boundf (schedBState s) prior (decision t, action t)+      in (Just t, (nextState []) { schedPrefix = ts, schedBState = bstate' })      -- Otherwise query the initialise function for a list of possible     -- choices, filter out anything in the sleep set, and make one of     -- them arbitrarily (recording the others).     [] ->-      let choices  = restrictToBound initialise+      let choices  = restrictToBound id initialise           checkDep t a = case prior of             Just (tid, act) -> dependent memtype (schedDepState s) tid act t a             Nothing -> False@@ -462,12 +461,15 @@           signore' = not (null choices) && all (`elem` M.keys ssleep') choices           sbkill'  = not (null initialise) && null choices       in case choices' of-            (nextTid:rest) -> (Just nextTid, (nextState rest) { schedSleep = ssleep' })-            [] -> (Nothing, (nextState []) { schedIgnore = signore', schedBoundKill = sbkill' })+            (nextTid:rest) ->+              let bstate' = boundf (schedBState s) prior (decision nextTid, action nextTid)+              in (Just nextTid, (nextState rest) { schedSleep = ssleep', schedBState = bstate' })+            [] ->+              (Nothing, (nextState []) { schedIgnore = signore', schedBoundKill = sbkill', schedBState = Nothing })    -- The next scheduler state   nextState rest = s-    { schedBPoints  = schedBPoints s |> (threads, rest)+    { schedBPoints  = schedBPoints s |> (restrictToBound fst threads', rest)     , schedDepState = nextDepState     }   nextDepState = let ds = schedDepState s in maybe ds (uncurry $ updateDepState ds) prior@@ -478,7 +480,7 @@   initialise = tryDaemons . yieldsToEnd $ case prior of     Just (tid, act)       | not (didYield act) && tid `elem` tids -> [tid]-    _ -> tids'+    _ -> tids    -- If one of the chosen actions will kill the computation, and there   -- are daemon threads, try them instead.@@ -501,30 +503,29 @@   -- See commits a056f54 and 8554ce9, and my 4th June comment in issue   -- #52.   tryDaemons ts-    | any doesKill ts = case partition doesKill tids' of+    | any doesKill ts = case partition doesKill tids of         (kills, nokills) -> nokills ++ kills     | otherwise = ts   doesKill t = killsDaemons t (action t)    -- Restrict the possible decisions to those in the bound.-  restrictToBound = filter (\t -> inBound trc (decision t, action t))+  restrictToBound f = filter (\x -> let t = f x in isJust $ boundf (schedBState s) prior (decision t, action t))    -- Move the threads which will immediately yield to the end of the list   yieldsToEnd ts = case partition (willYield . action) ts of     (yields, noyields) -> noyields ++ yields    -- Get the decision that will lead to a thread being scheduled.-  decision = decisionOf (fst <$> prior) (S.fromList tids')+  decision = decisionOf (fst <$> prior) (S.fromList tids)    -- Get the action of a thread   action t = fromJust $ lookup t threads'    -- The runnable thread IDs-  tids = fst <$> threads+  tids = map fst threads'    -- The runnable threads as a normal list.   threads' = toList threads-  tids'    = toList tids  ------------------------------------------------------------------------------- -- Weighted random scheduler
Test/DejaFu/STM/Internal.hs view
@@ -151,7 +151,7 @@        let newIDSource = nidsrc'           newAct = act'-          newUndo = undo >> undo'+          newUndo = undo' >> undo           newReaden = readen' ++ readen           newWritten = written' ++ written           newSofar = tact : sofar
dejafu.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                dejafu-version:             0.7.1.2+version:             0.7.1.3 synopsis:            Systematic testing for Haskell concurrency.  description:@@ -37,7 +37,7 @@ source-repository this   type:     git   location: https://github.com/barrucadu/dejafu.git-  tag:      dejafu-0.7.1.2+  tag:      dejafu-0.7.1.3  library   exposed-modules:     Test.DejaFu