packages feed

dejafu 1.4.0.0 → 1.5.0.0

raw patch · 13 files changed

+162/−159 lines, 13 filesdep −semigroupsdep ~basedep ~concurrencydep ~transformersPVP ok

version bump matches the API change (PVP)

Dependencies removed: semigroups

Dependency ranges changed: base, concurrency, transformers

API changes (from Hackage documentation)

- Test.DejaFu.Conc.Internal: killAllThreads :: MonadConc n => Context n g -> n ()
+ Test.DejaFu.Conc.Internal: killAllThreads :: (MonadConc n, HasCallStack) => Context n g -> n ()
- Test.DejaFu.Conc.Internal: runConcurrency :: MonadConc n => Bool -> Scheduler g -> MemType -> g -> IdSource -> Int -> ModelConc n a -> n (CResult n g a)
+ Test.DejaFu.Conc.Internal: runConcurrency :: (MonadConc n, HasCallStack) => Bool -> Scheduler g -> MemType -> g -> IdSource -> Int -> ModelConc n a -> n (CResult n g a)
- Test.DejaFu.Conc.Internal: runConcurrency' :: MonadConc n => Bool -> Scheduler g -> MemType -> Context n g -> ModelConc n a -> n (CResult n g a)
+ Test.DejaFu.Conc.Internal: runConcurrency' :: (MonadConc n, HasCallStack) => Bool -> Scheduler g -> MemType -> Context n g -> ModelConc n a -> n (CResult n g a)
- Test.DejaFu.Conc.Internal: runConcurrencyWithSnapshot :: MonadConc n => Scheduler g -> MemType -> Context n g -> (Threads n -> n ()) -> CRef n (Maybe (Either Failure a)) -> n (CResult n g a)
+ Test.DejaFu.Conc.Internal: runConcurrencyWithSnapshot :: (MonadConc n, HasCallStack) => Scheduler g -> MemType -> Context n g -> (Threads n -> n ()) -> CRef n (Maybe (Either Failure a)) -> n (CResult n g a)
- Test.DejaFu.Conc.Internal: runThreads :: MonadConc n => Bool -> Scheduler g -> MemType -> CRef n (Maybe (Either Failure a)) -> Context n g -> n (CResult n g a)
+ Test.DejaFu.Conc.Internal: runThreads :: (MonadConc n, HasCallStack) => Bool -> Scheduler g -> MemType -> CRef n (Maybe (Either Failure a)) -> Context n g -> n (CResult n g a)
- Test.DejaFu.Conc.Internal: stepThread :: MonadConc n => Bool -> Bool -> Scheduler g -> MemType -> ThreadId -> Action n -> Context n g -> n (What n g, Act, Threads n -> n ())
+ Test.DejaFu.Conc.Internal: stepThread :: (MonadConc n, HasCallStack) => Bool -> Bool -> Scheduler g -> MemType -> ThreadId -> Action n -> Context n g -> n (What n g, Act, Threads n -> n ())
- Test.DejaFu.Conc.Internal.Memory: readFromMVar :: MonadConc n => ModelMVar n a -> (a -> Action n) -> ThreadId -> Threads n -> n (Bool, Threads n, [ThreadId], n ())
+ Test.DejaFu.Conc.Internal.Memory: readFromMVar :: (MonadConc n, HasCallStack) => ModelMVar n a -> (a -> Action n) -> ThreadId -> Threads n -> n (Bool, Threads n, [ThreadId], n ())
- Test.DejaFu.Conc.Internal.Memory: takeFromMVar :: MonadConc n => ModelMVar n a -> (a -> Action n) -> ThreadId -> Threads n -> n (Bool, Threads n, [ThreadId], n ())
+ Test.DejaFu.Conc.Internal.Memory: takeFromMVar :: (MonadConc n, HasCallStack) => ModelMVar n a -> (a -> Action n) -> ThreadId -> Threads n -> n (Bool, Threads n, [ThreadId], n ())
- Test.DejaFu.Conc.Internal.Threading: block :: BlockedOn -> ThreadId -> Threads n -> Threads n
+ Test.DejaFu.Conc.Internal.Threading: block :: HasCallStack => BlockedOn -> ThreadId -> Threads n -> Threads n
- Test.DejaFu.Conc.Internal.Threading: catching :: Exception e => (e -> Action n) -> ThreadId -> Threads n -> Threads n
+ Test.DejaFu.Conc.Internal.Threading: catching :: (Exception e, HasCallStack) => (e -> Action n) -> ThreadId -> Threads n -> Threads n
- Test.DejaFu.Conc.Internal.Threading: except :: (MaskingState -> Action n) -> [Handler n] -> ThreadId -> Threads n -> Threads n
+ Test.DejaFu.Conc.Internal.Threading: except :: HasCallStack => (MaskingState -> Action n) -> [Handler n] -> ThreadId -> Threads n -> Threads n
- Test.DejaFu.Conc.Internal.Threading: goto :: Action n -> ThreadId -> Threads n -> Threads n
+ Test.DejaFu.Conc.Internal.Threading: goto :: HasCallStack => Action n -> ThreadId -> Threads n -> Threads n
- Test.DejaFu.Conc.Internal.Threading: kill :: MonadConc n => ThreadId -> Threads n -> n (Threads n)
+ Test.DejaFu.Conc.Internal.Threading: kill :: (MonadConc n, HasCallStack) => ThreadId -> Threads n -> n (Threads n)
- Test.DejaFu.Conc.Internal.Threading: launch :: ThreadId -> ThreadId -> ((forall b. ModelConc n b -> ModelConc n b) -> Action n) -> Threads n -> Threads n
+ Test.DejaFu.Conc.Internal.Threading: launch :: HasCallStack => ThreadId -> ThreadId -> ((forall b. ModelConc n b -> ModelConc n b) -> Action n) -> Threads n -> Threads n
- Test.DejaFu.Conc.Internal.Threading: launch' :: MaskingState -> ThreadId -> ((forall b. ModelConc n b -> ModelConc n b) -> Action n) -> Threads n -> Threads n
+ Test.DejaFu.Conc.Internal.Threading: launch' :: HasCallStack => MaskingState -> ThreadId -> ((forall b. ModelConc n b -> ModelConc n b) -> Action n) -> Threads n -> Threads n
- Test.DejaFu.Conc.Internal.Threading: makeBound :: MonadConc n => ThreadId -> Threads n -> n (Threads n)
+ Test.DejaFu.Conc.Internal.Threading: makeBound :: (MonadConc n, HasCallStack) => ThreadId -> Threads n -> n (Threads n)
- Test.DejaFu.Conc.Internal.Threading: mask :: MaskingState -> ThreadId -> Threads n -> Threads n
+ Test.DejaFu.Conc.Internal.Threading: mask :: HasCallStack => MaskingState -> ThreadId -> Threads n -> Threads n
- Test.DejaFu.Conc.Internal.Threading: propagate :: SomeException -> ThreadId -> Threads n -> Maybe (Threads n)
+ Test.DejaFu.Conc.Internal.Threading: propagate :: HasCallStack => SomeException -> ThreadId -> Threads n -> Maybe (Threads n)
- Test.DejaFu.Conc.Internal.Threading: uncatching :: ThreadId -> Threads n -> Threads n
+ Test.DejaFu.Conc.Internal.Threading: uncatching :: HasCallStack => ThreadId -> Threads n -> Threads n
- Test.DejaFu.Internal: eadjust :: (Ord k, Show k) => String -> (v -> v) -> k -> Map k v -> Map k v
+ Test.DejaFu.Internal: eadjust :: (Ord k, Show k, HasCallStack) => (v -> v) -> k -> Map k v -> Map k v
- Test.DejaFu.Internal: efromJust :: String -> Maybe a -> a
+ Test.DejaFu.Internal: efromJust :: HasCallStack => Maybe a -> a
- Test.DejaFu.Internal: efromList :: String -> [a] -> NonEmpty a
+ Test.DejaFu.Internal: efromList :: HasCallStack => [a] -> NonEmpty a
- Test.DejaFu.Internal: eidx :: String -> [a] -> Int -> a
+ Test.DejaFu.Internal: eidx :: HasCallStack => [a] -> Int -> a
- Test.DejaFu.Internal: einsert :: (Ord k, Show k) => String -> k -> v -> Map k v -> Map k v
+ Test.DejaFu.Internal: einsert :: (Ord k, Show k, HasCallStack) => k -> v -> Map k v -> Map k v
- Test.DejaFu.Internal: elookup :: (Ord k, Show k) => String -> k -> Map k v -> v
+ Test.DejaFu.Internal: elookup :: (Ord k, Show k, HasCallStack) => k -> Map k v -> v
- Test.DejaFu.Internal: etail :: String -> [a] -> [a]
+ Test.DejaFu.Internal: etail :: HasCallStack => [a] -> [a]
- Test.DejaFu.Internal: fatal :: String -> String -> a
+ Test.DejaFu.Internal: fatal :: HasCallStack => String -> a
- Test.DejaFu.SCT.Internal: sct :: MonadConc n => Settings n a -> ([ThreadId] -> s) -> (s -> Maybe t) -> ((Scheduler g -> g -> n (Either Failure a, g, Trace)) -> s -> t -> n (s, Maybe (Either Failure a, Trace))) -> ConcT n a -> n [(Either Failure a, Trace)]
+ Test.DejaFu.SCT.Internal: sct :: (MonadConc n, HasCallStack) => Settings n a -> ([ThreadId] -> s) -> (s -> Maybe t) -> ((Scheduler g -> g -> n (Either Failure a, g, Trace)) -> s -> t -> n (s, Maybe (Either Failure a, Trace))) -> ConcT n a -> n [(Either Failure a, Trace)]
- Test.DejaFu.SCT.Internal: sct' :: MonadConc n => Settings n a -> s -> (s -> Maybe t) -> (s -> t -> n (s, Maybe (Either Failure a, Trace))) -> (forall x. Scheduler x -> x -> n (Either Failure a, x, Trace)) -> ThreadId -> CRefId -> n [(Either Failure a, Trace)]
+ Test.DejaFu.SCT.Internal: sct' :: (MonadConc n, HasCallStack) => Settings n a -> s -> (s -> Maybe t) -> (s -> t -> n (s, Maybe (Either Failure a, Trace))) -> (forall x. Scheduler x -> x -> n (Either Failure a, x, Trace)) -> ThreadId -> CRefId -> n [(Either Failure a, Trace)]
- Test.DejaFu.SCT.Internal: simplifyExecution :: MonadConc n => Settings n a -> (forall x. Scheduler x -> x -> n (Either Failure a, x, Trace)) -> ThreadId -> CRefId -> Either Failure a -> Trace -> n (Either Failure a, Trace)
+ Test.DejaFu.SCT.Internal: simplifyExecution :: (MonadConc n, HasCallStack) => Settings n a -> (forall x. Scheduler x -> x -> n (Either Failure a, x, Trace)) -> ThreadId -> CRefId -> Either Failure a -> Trace -> n (Either Failure a, Trace)
- Test.DejaFu.SCT.Internal.DPOR: backtrackAt :: (ThreadId -> BacktrackStep -> Bool) -> BacktrackFunc
+ Test.DejaFu.SCT.Internal.DPOR: backtrackAt :: HasCallStack => (ThreadId -> BacktrackStep -> Bool) -> BacktrackFunc
- Test.DejaFu.SCT.Internal.DPOR: dporSched :: MemType -> IncrementalBoundFunc k -> Scheduler (DPORSchedState k)
+ Test.DejaFu.SCT.Internal.DPOR: dporSched :: HasCallStack => MemType -> IncrementalBoundFunc k -> Scheduler (DPORSchedState k)
- Test.DejaFu.SCT.Internal.DPOR: incorporateBacktrackSteps :: [BacktrackStep] -> DPOR -> DPOR
+ Test.DejaFu.SCT.Internal.DPOR: incorporateBacktrackSteps :: HasCallStack => [BacktrackStep] -> DPOR -> DPOR
- Test.DejaFu.SCT.Internal.DPOR: incorporateTrace :: MemType -> Bool -> Trace -> DPOR -> DPOR
+ Test.DejaFu.SCT.Internal.DPOR: incorporateTrace :: HasCallStack => MemType -> Bool -> Trace -> DPOR -> DPOR
- Test.DejaFu.SCT.Internal.DPOR: validateDPOR :: String -> DPOR -> DPOR
+ Test.DejaFu.SCT.Internal.DPOR: validateDPOR :: HasCallStack => DPOR -> DPOR

Files

CHANGELOG.rst view
@@ -7,6 +7,24 @@ .. _PVP: https://pvp.haskell.org/  +1.5.0.0 - No More 7.10 (2018-03-28)+-----------------------------------++* Git: :tag:`dejafu-1.5.0.0`+* Hackage: :hackage:`dejafu-1.5.0.0`++Miscellaneous+~~~~~~~~~~~~~++* GHC 7.10 support is dropped.  Dependency lower bounds are:++    * :hackage:`base`: 4.9+    * :hackage:`concurrency`: 1.5+    * :hackage:`transformers`: 0.5++* The upper bound on :hackage:`concurrency` is 1.6.++ 1.4.0.0 (2018-03-17) -------------------- 
Test/DejaFu/Conc.hs view
@@ -57,6 +57,7 @@  import           Control.Exception                   (MaskingState(..)) import qualified Control.Monad.Catch                 as Ca+import           Control.Monad.Fail                  (MonadFail) import qualified Control.Monad.IO.Class              as IO import           Control.Monad.Trans.Class           (MonadTrans(..)) import qualified Data.Foldable                       as F@@ -74,18 +75,9 @@ import           Test.DejaFu.Types import           Test.DejaFu.Utils -#if MIN_VERSION_base(4,9,0)-import qualified Control.Monad.Fail                  as Fail-#endif- -- | @since 1.4.0.0 newtype ConcT n a = C { unC :: ModelConc n a }-  deriving (Functor, Applicative, Monad)--#if MIN_VERSION_base(4,9,0)-instance Fail.MonadFail (ConcT n) where-  fail = C . fail-#endif+  deriving (Functor, Applicative, Monad, MonadFail)  -- | A 'MonadConc' implementation using @IO@. --@@ -141,7 +133,10 @@    forkWithUnmaskN   n ma = toConc (AFork n (\umask -> runModelConc (unC $ ma $ wrap umask) (\_ -> AStop (pure ()))))   forkOnWithUnmaskN n _  = C.forkWithUnmaskN n-  forkOSN n ma = forkOSWithUnmaskN n (const ma)+  forkOSWithUnmaskN n ma+    | C.rtsSupportsBoundThreads =+      toConc (AForkOS n (\umask -> runModelConc (unC $ ma $ wrap umask) (\_ -> AStop (pure ()))))+    | otherwise = fail "RTS doesn't support multiple OS threads (use ghc -threaded when linking)"    isCurrentThreadBound = toConc AIsBound @@ -191,16 +186,6 @@    atomically = toConc . AAtom --- move this into the instance defn when forkOSWithUnmaskN is added to MonadConc in 2018-forkOSWithUnmaskN :: Applicative n-  => String-  -> ((forall a. ConcT n a -> ConcT n a) -> ConcT n ())-  -> ConcT n ThreadId-forkOSWithUnmaskN n ma-  | C.rtsSupportsBoundThreads =-    toConc (AForkOS n (\umask -> runModelConc (unC $ ma $ wrap umask) (\_ -> AStop (pure ()))))-  | otherwise = fail "RTS doesn't support multiple OS threads (use ghc -threaded when linking)"- -- | 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.@@ -233,7 +218,7 @@   -> n (Either Failure a, s, Trace) runConcurrent sched memtype s ma = do   res <- runConcurrency False sched memtype s initialIdSource 2 (unC ma)-  out <- efromJust "runConcurrent" <$> C.readCRef (finalRef res)+  out <- efromJust <$> C.readCRef (finalRef res)   pure ( out        , cSchedState (finalContext res)        , F.toList (finalTrace res)@@ -389,7 +374,7 @@   let restore = dcsRestore snapshot   let ref = dcsRef snapshot   res <- runConcurrencyWithSnapshot sched memtype context restore ref-  out <- efromJust "runWithDCSnapshot" <$> C.readCRef (finalRef res)+  out <- efromJust <$> C.readCRef (finalRef res)   pure ( out        , cSchedState (finalContext res)        , F.toList (finalTrace res)
Test/DejaFu/Conc/Internal.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-}@@ -8,7 +9,7 @@ -- License     : MIT -- Maintainer  : Michael Walker <mike@barrucadu.co.uk> -- Stability   : experimental--- Portability : MultiWayIf, RankNTypes, RecordWildCards+-- Portability : FlexibleContexts, MultiWayIf, RankNTypes, RecordWildCards -- -- Concurrent monads with a fixed scheduler: internal types and -- functions. This module is NOT considered to form part of the public@@ -28,6 +29,7 @@ import           Data.Monoid                         ((<>)) import           Data.Sequence                       (Seq, (<|)) import qualified Data.Sequence                       as Seq+import           GHC.Stack                           (HasCallStack)  import           Test.DejaFu.Conc.Internal.Common import           Test.DejaFu.Conc.Internal.Memory@@ -72,7 +74,7 @@ -- | 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.-runConcurrency :: C.MonadConc n+runConcurrency :: (C.MonadConc n, HasCallStack)   => Bool   -> Scheduler g   -> MemType@@ -97,7 +99,7 @@ -- main thread. -- -- Only a separate function because @ADontCheck@ needs it.-runConcurrency' :: C.MonadConc n+runConcurrency' :: (C.MonadConc n, HasCallStack)   => Bool   -> Scheduler g   -> MemType@@ -111,7 +113,7 @@   runThreads forSnapshot sched memtype ref ctx { cThreads = threads }  -- | Like 'runConcurrency' but starts from a snapshot.-runConcurrencyWithSnapshot :: C.MonadConc n+runConcurrencyWithSnapshot :: (C.MonadConc n, HasCallStack)   => Scheduler g   -> MemType   -> Context n g@@ -127,7 +129,7 @@   pure res  -- | Kill the remaining threads-killAllThreads :: C.MonadConc n => Context n g -> n ()+killAllThreads :: (C.MonadConc n, HasCallStack) => Context n g -> n () killAllThreads ctx =   let finalThreads = cThreads ctx   in mapM_ (`kill` finalThreads) (M.keys finalThreads)@@ -145,7 +147,7 @@   }  -- | Run a collection of threads, until there are no threads left.-runThreads :: C.MonadConc n+runThreads :: (C.MonadConc n, HasCallStack)   => Bool   -> Scheduler g   -> MemType@@ -189,7 +191,7 @@              Nothing -> die InternalError restore sofar prior ctx'            Nothing -> die Abort restore sofar prior ctx'     where-      (choice, g')  = scheduleThread sched prior (efromList "runThreads" runnable') (cSchedState ctx)+      (choice, g')  = scheduleThread sched prior (efromList runnable') (cSchedState ctx)       runnable'     = [(t, lookahead (_continuation a)) | (t, a) <- sortOn fst $ M.assocs runnable]       runnable      = M.filter (not . isBlocked) threadsc       threadsc      = addCommitThreads (cWriteBuf ctx) threads@@ -284,7 +286,7 @@ -- -- Note: the returned snapshot action will definitely not do the right -- thing with relaxed memory.-stepThread :: C.MonadConc n+stepThread :: (C.MonadConc n, HasCallStack)   => Bool   -- ^ Should we record a snapshot?   -> Bool@@ -321,7 +323,7 @@  -- check if the current thread is bound stepThread _ _ _ _ tid (AIsBound c) = \ctx@Context{..} -> do-  let isBound = isJust . _bound $ elookup "stepThread.AIsBound" tid cThreads+  let isBound = isJust . _bound $ elookup tid cThreads   pure ( Succeeded ctx { cThreads = goto (c isBound) tid cThreads }        , Single (IsCurrentThreadBound isBound)        , const (pure ())@@ -596,7 +598,7 @@ stepThread _ _ _ _ tid (AMasking m ma c) = \ctx@Context{..} -> pure $   let resetMask typ ms = ModelConc $ \k -> AResetMask typ True ms $ k ()       umask mb = resetMask True m' >> mb >>= \b -> resetMask False m >> pure b-      m' = _masking $ elookup "stepThread.AMasking" tid cThreads+      m' = _masking $ elookup tid cThreads       a  = runModelConc (ma umask) (AResetMask False False m' . c)   in ( Succeeded ctx { cThreads = goto a tid (mask m tid cThreads) }      , Single (SetMasking False m)@@ -632,7 +634,7 @@      | M.size (cThreads ctx) > 1 -> pure (Failed IllegalSubconcurrency, Single Subconcurrency, const (pure ()))      | otherwise -> do          res <- runConcurrency False sched memtype (cSchedState ctx) (cIdSource ctx) (cCaps ctx) ma-         out <- efromJust "stepThread.ASub" <$> C.readCRef (finalRef res)+         out <- efromJust <$> C.readCRef (finalRef res)          pure ( Succeeded ctx                 { cThreads    = goto (AStopSub (c out)) tid (cThreads ctx)                 , cIdSource   = cIdSource (finalContext res)@@ -660,7 +662,7 @@          threads' <- kill tid (cThreads ctx)          let dcCtx = ctx { cThreads = threads', cSchedState = lb }          res <- runConcurrency' forSnapshot dcSched SequentialConsistency dcCtx ma-         out <- efromJust "stepThread.ADontCheck" <$> C.readCRef (finalRef res)+         out <- efromJust <$> C.readCRef (finalRef res)          case out of            Right a -> do              let threads'' = launch' Unmasked tid (const (c a)) (cThreads (finalContext res))
Test/DejaFu/Conc/Internal/Common.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE RankNTypes #-} @@ -8,7 +7,7 @@ -- License     : MIT -- Maintainer  : Michael Walker <mike@barrucadu.co.uk> -- Stability   : experimental--- Portability : CPP, ExistentialQuantification, RankNTypes+-- Portability : ExistentialQuantification, RankNTypes -- -- Common types and utility functions for deterministic execution of -- 'MonadConc' implementations. This module is NOT considered to form@@ -17,14 +16,11 @@  import           Control.Exception             (Exception, MaskingState(..)) import qualified Control.Monad.Conc.Class      as C+import qualified Control.Monad.Fail            as Fail import           Data.Map.Strict               (Map) import           Test.DejaFu.Conc.Internal.STM (ModelSTM) import           Test.DejaFu.Types -#if MIN_VERSION_base(4,9,0)-import qualified Control.Monad.Fail            as Fail-#endif- -------------------------------------------------------------------------------- -- * The @ModelConc@ Monad @@ -51,11 +47,9 @@     return  = pure     m >>= k = ModelConc $ \c -> runModelConc m (\x -> runModelConc (k x) c) -#if MIN_VERSION_base(4,9,0)     fail = Fail.fail  instance Fail.MonadFail (ModelConc n) where-#endif     fail e = ModelConc $ \_ -> AThrow (MonadFailException e)  -- | An @MVar@ is modelled as a unique ID and a reference holding a
Test/DejaFu/Conc/Internal/Memory.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE BangPatterns #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE RecordWildCards #-}@@ -9,7 +10,7 @@ -- License     : MIT -- Maintainer  : Michael Walker <mike@barrucadu.co.uk> -- Stability   : experimental--- Portability : BangPatterns, GADTs, LambdaCase, RecordWildCards+-- Portability : BangPatterns, GADTs, FlexibleContexts, LambdaCase, RecordWildCards -- -- Operations over @CRef@s and @MVar@s. This module is NOT considered -- to form part of the public interface of this library.@@ -31,6 +32,7 @@ import           Data.Monoid                         ((<>)) import           Data.Sequence                       (Seq, ViewL(..), singleton,                                                       viewl, (><))+import           GHC.Stack                           (HasCallStack)  import           Test.DejaFu.Conc.Internal.Common import           Test.DejaFu.Conc.Internal.Threading@@ -174,13 +176,13 @@ tryPutIntoMVar = mutMVar NonBlocking  -- | Read from a @MVar@, blocking if empty.-readFromMVar :: C.MonadConc n+readFromMVar :: (C.MonadConc n, HasCallStack)   => ModelMVar n a   -> (a -> Action n)   -> ThreadId   -> Threads n   -> n (Bool, Threads n, [ThreadId], n ())-readFromMVar cvar c = seeMVar NonEmptying Blocking cvar (c . efromJust "readFromMVar")+readFromMVar cvar c = seeMVar NonEmptying Blocking cvar (c . efromJust)  -- | Try to read from a @MVar@, not blocking if empty. tryReadFromMVar :: C.MonadConc n@@ -192,13 +194,13 @@ tryReadFromMVar = seeMVar NonEmptying NonBlocking  -- | Take from a @MVar@, blocking if empty.-takeFromMVar :: C.MonadConc n+takeFromMVar :: (C.MonadConc n, HasCallStack)   => ModelMVar n a   -> (a -> Action n)   -> ThreadId   -> Threads n   -> n (Bool, Threads n, [ThreadId], n ())-takeFromMVar cvar c = seeMVar Emptying Blocking cvar (c . efromJust "takeFromMVar")+takeFromMVar cvar c = seeMVar Emptying Blocking cvar (c . efromJust)  -- | Try to take from a @MVar@, not blocking if empty. tryTakeFromMVar :: C.MonadConc n
Test/DejaFu/Conc/Internal/STM.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeFamilies #-}@@ -12,7 +11,7 @@ -- License     : MIT -- Maintainer  : Michael Walker <mike@barrucadu.co.uk> -- Stability   : experimental--- Portability : CPP, ExistentialQuantification, NoMonoLocalBinds, RecordWildCards, TypeFamilies+-- Portability : ExistentialQuantification, NoMonoLocalBinds, RecordWildCards, TypeFamilies -- -- 'MonadSTM' testing implementation, internal types and definitions. -- This module is NOT considered to form part of the public interface@@ -25,16 +24,13 @@ import           Control.Monad            (MonadPlus(..)) import           Control.Monad.Catch      (MonadCatch(..), MonadThrow(..)) import qualified Control.Monad.Conc.Class as C+import qualified Control.Monad.Fail       as Fail import qualified Control.Monad.STM.Class  as S import           Data.List                (nub)  import           Test.DejaFu.Internal import           Test.DejaFu.Types -#if MIN_VERSION_base(4,9,0)-import qualified Control.Monad.Fail       as Fail-#endif- -------------------------------------------------------------------------------- -- * The @ModelSTM@ monad @@ -56,11 +52,9 @@     return  = pure     m >>= k = ModelSTM $ \c -> runModelSTM m (\x -> runModelSTM (k x) c) -#if MIN_VERSION_base(4,9,0)     fail = Fail.fail  instance Fail.MonadFail (ModelSTM n) where-#endif     fail e = ModelSTM $ \_ -> SThrow (MonadFailException e)  instance MonadThrow (ModelSTM n) where
Test/DejaFu/Conc/Internal/Threading.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-}  -- |@@ -7,7 +8,7 @@ -- License     : MIT -- Maintainer  : Michael Walker <mike@barrucadu.co.uk> -- Stability   : experimental--- Portability : ExistentialQuantification, RankNTypes+-- Portability : ExistentialQuantification, FlexibleContexts, RankNTypes -- -- Operations and types for threads. This module is NOT considered to -- form part of the public interface of this library.@@ -21,6 +22,7 @@ import           Data.Map.Strict                  (Map) import qualified Data.Map.Strict                  as M import           Data.Maybe                       (isJust)+import           GHC.Stack                        (HasCallStack)  import           Test.DejaFu.Conc.Internal.Common import           Test.DejaFu.Internal@@ -84,9 +86,9 @@  -- | Propagate an exception upwards, finding the closest handler -- which can deal with it.-propagate :: SomeException -> ThreadId -> Threads n -> Maybe (Threads n)+propagate :: HasCallStack => SomeException -> ThreadId -> Threads n -> Maybe (Threads n) propagate e tid threads = raise <$> propagate' handlers where-  handlers = _handlers (elookup "propagate" tid threads)+  handlers = _handlers (elookup tid threads)    raise (act, hs) = except act hs tid threads @@ -100,53 +102,53 @@   (_masking thread == MaskedInterruptible && isJust (_blocking thread))  -- | Register a new exception handler.-catching :: Exception e => (e -> Action n) -> ThreadId -> Threads n -> Threads n-catching h = eadjust "catching" $ \thread ->+catching :: (Exception e, HasCallStack) => (e -> Action n) -> ThreadId -> Threads n -> Threads n+catching h = eadjust $ \thread ->   let ms0 = _masking thread       h'  = Handler $ \e ms -> (if ms /= ms0 then AResetMask False False ms0 else id) (h e)   in thread { _handlers = h' : _handlers thread }  -- | Remove the most recent exception handler.-uncatching :: ThreadId -> Threads n -> Threads n-uncatching = eadjust "uncatching" $ \thread ->-  thread { _handlers = etail "uncatching" (_handlers thread) }+uncatching :: HasCallStack => ThreadId -> Threads n -> Threads n+uncatching = eadjust $ \thread ->+  thread { _handlers = etail (_handlers thread) }  -- | Raise an exception in a thread.-except :: (MaskingState -> Action n) -> [Handler n] -> ThreadId -> Threads n -> Threads n-except actf hs = eadjust "except" $ \thread -> thread+except :: HasCallStack => (MaskingState -> Action n) -> [Handler n] -> ThreadId -> Threads n -> Threads n+except actf hs = eadjust $ \thread -> thread   { _continuation = actf (_masking thread)   , _handlers = hs   , _blocking = Nothing   }  -- | Set the masking state of a thread.-mask :: MaskingState -> ThreadId -> Threads n -> Threads n-mask ms = eadjust "mask" $ \thread -> thread { _masking = ms }+mask :: HasCallStack => MaskingState -> ThreadId -> Threads n -> Threads n+mask ms = eadjust $ \thread -> thread { _masking = ms }  -------------------------------------------------------------------------------- -- * Manipulating threads  -- | Replace the @Action@ of a thread.-goto :: Action n -> ThreadId -> Threads n -> Threads n-goto a = eadjust "goto" $ \thread -> thread { _continuation = a }+goto :: HasCallStack => Action n -> ThreadId -> Threads n -> Threads n+goto a = eadjust $ \thread -> thread { _continuation = a }  -- | Start a thread with the given ID, inheriting the masking state -- from the parent thread. This ID must not already be in use!-launch :: ThreadId -> ThreadId -> ((forall b. ModelConc n b -> ModelConc n b) -> Action n) -> Threads n -> Threads n+launch :: HasCallStack => ThreadId -> ThreadId -> ((forall b. ModelConc n b -> ModelConc n b) -> Action n) -> Threads n -> Threads n launch parent tid a threads = launch' ms tid a threads where-  ms = _masking (elookup "launch" parent threads)+  ms = _masking (elookup parent threads)  -- | Start a thread with the given ID and masking state. This must not already be in use!-launch' :: MaskingState -> ThreadId -> ((forall b. ModelConc n b -> ModelConc n b) -> Action n) -> Threads n -> Threads n-launch' ms tid a = einsert "launch'" tid thread where+launch' :: HasCallStack => MaskingState -> ThreadId -> ((forall b. ModelConc n b -> ModelConc n b) -> Action n) -> Threads n -> Threads n+launch' ms tid a = einsert tid thread where   thread = Thread (a umask) Nothing [] ms Nothing    umask mb = resetMask True Unmasked >> mb >>= \b -> resetMask False ms >> pure b   resetMask typ m = ModelConc $ \k -> AResetMask typ True m $ k ()  -- | Block a thread.-block :: BlockedOn -> ThreadId -> Threads n -> Threads n-block blockedOn = eadjust "block" $ \thread -> thread { _blocking = Just blockedOn }+block :: HasCallStack => BlockedOn -> ThreadId -> Threads n -> Threads n+block blockedOn = eadjust $ \thread -> thread { _blocking = Just blockedOn }  -- | Unblock all threads waiting on the appropriate block. For 'TVar' -- blocks, this will wake all threads waiting on at least one of the@@ -165,13 +167,13 @@ -- ** Bound threads  -- | Turn a thread into a bound thread.-makeBound :: C.MonadConc n => ThreadId -> Threads n -> n (Threads n)+makeBound :: (C.MonadConc n, HasCallStack) => ThreadId -> Threads n -> n (Threads n) makeBound tid threads = do     runboundIO <- C.newEmptyMVar     getboundIO <- C.newEmptyMVar     btid <- C.forkOSN ("bound worker for '" ++ show tid ++ "'") (go runboundIO getboundIO)     let bt = BoundThread runboundIO getboundIO btid-    pure (eadjust "makeBound" (\t -> t { _bound = Just bt }) tid threads)+    pure (eadjust (\t -> t { _bound = Just bt }) tid threads)   where     go runboundIO getboundIO = forever $ do       na <- C.takeMVar runboundIO@@ -180,9 +182,9 @@ -- | Kill a thread and remove it from the thread map. -- -- If the thread is bound, the worker thread is cleaned up.-kill :: C.MonadConc n => ThreadId -> Threads n -> n (Threads n)+kill :: (C.MonadConc n, HasCallStack) => ThreadId -> Threads n -> n (Threads n) kill tid threads = do-  let thread = elookup "kill" tid threads+  let thread = elookup tid threads   maybe (pure ()) (C.killThread . _boundTId) (_bound thread)   pure (M.delete tid threads) 
Test/DejaFu/Internal.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-}  -- |@@ -8,7 +9,7 @@ -- License     : MIT -- Maintainer  : Michael Walker <mike@barrucadu.co.uk> -- Stability   : experimental--- Portability : DeriveAnyClass, DeriveGeneric, GADTs+-- Portability : DeriveAnyClass, DeriveGeneric, FlexibleContexts, GADTs -- -- Internal types and functions used throughout DejaFu.  This module -- is NOT considered to form part of the public interface of this@@ -23,6 +24,7 @@ import           Data.Set                 (Set) import qualified Data.Set                 as S import           GHC.Generics             (Generic)+import           GHC.Stack                (HasCallStack, withFrozenCallStack) import           System.Random            (RandomGen)  import           Test.DejaFu.Types@@ -328,53 +330,53 @@  -- | 'tail' but with a better error message if it fails.  Use this -- only where it shouldn't fail!-etail :: String -> [a] -> [a]-etail _ (_:xs) = xs-etail src _ = fatal src "tail: empty list"+etail :: HasCallStack => [a] -> [a]+etail (_:xs) = xs+etail _ = withFrozenCallStack $ fatal "tail: empty list"  -- | '(!!)' but with a better error message if it fails.  Use this -- only where it shouldn't fail!-eidx :: String -> [a] -> Int -> a-eidx src xs i+eidx :: HasCallStack => [a] -> Int -> a+eidx xs i   | i < length xs = xs !! i-  | otherwise = fatal src "(!!): index too large"+  | otherwise = withFrozenCallStack $ fatal "(!!): index too large"  -- | 'fromJust' but with a better error message if it fails.  Use this -- only where it shouldn't fail!-efromJust :: String -> Maybe a -> a-efromJust _ (Just x) = x-efromJust src _ = fatal src "fromJust: Nothing"+efromJust :: HasCallStack => Maybe a -> a+efromJust (Just x) = x+efromJust _ = withFrozenCallStack $ fatal "fromJust: Nothing"  -- | 'fromList' but with a better error message if it fails.  Use this -- only where it shouldn't fail!-efromList :: String -> [a] -> NonEmpty a-efromList _ (x:xs) = x:|xs-efromList src _ = fatal src "fromList: empty list"+efromList :: HasCallStack => [a] -> NonEmpty a+efromList (x:xs) = x:|xs+efromList _ = withFrozenCallStack $ fatal "fromList: empty list"  -- | 'M.adjust' but which errors if the key is not present.  Use this -- only where it shouldn't fail!-eadjust :: (Ord k, Show k) => String -> (v -> v) -> k -> M.Map k v -> M.Map k v-eadjust src f k m = case M.lookup k m of+eadjust :: (Ord k, Show k, HasCallStack) => (v -> v) -> k -> M.Map k v -> M.Map k v+eadjust f k m = case M.lookup k m of   Just v -> M.insert k (f v) m-  Nothing -> fatal src ("adjust: key '" ++ show k ++ "' not found")+  Nothing -> withFrozenCallStack $ fatal ("adjust: key '" ++ show k ++ "' not found")  -- | 'M.insert' but which errors if the key is already present.  Use -- this only where it shouldn't fail!-einsert :: (Ord k, Show k) => String -> k -> v -> M.Map k v -> M.Map k v-einsert src k v m-  | M.member k m = fatal src ("insert: key '" ++ show k ++ "' already present")+einsert :: (Ord k, Show k, HasCallStack) => k -> v -> M.Map k v -> M.Map k v+einsert k v m+  | M.member k m = withFrozenCallStack $ fatal ("insert: key '" ++ show k ++ "' already present")   | otherwise = M.insert k v m  -- | 'M.lookup' but which errors if the key is not present.  Use this -- only where it shouldn't fail!-elookup :: (Ord k, Show k) => String -> k -> M.Map k v -> v-elookup src k =-  fromMaybe (fatal src ("lookup: key '" ++ show k ++ "' not found")) .+elookup :: (Ord k, Show k, HasCallStack) => k -> M.Map k v -> v+elookup k =+  fromMaybe (withFrozenCallStack $ fatal ("lookup: key '" ++ show k ++ "' not found")) .   M.lookup k  -- | 'error' but saying where it came from-fatal :: String -> String -> a-fatal src msg = error ("(dejafu: " ++ src ++ ") " ++ msg)+fatal :: HasCallStack => String -> a+fatal msg = withFrozenCallStack $ error ("(dejafu) " ++ msg)  ------------------------------------------------------------------------------- -- * Miscellaneous
Test/DejaFu/SCT.hs view
@@ -1,3 +1,5 @@+{-# OPTIONS_GHC -Wno-deprecations #-}+ -- | -- Module      : Test.DejaFu.SCT -- Copyright   : (c) 2015--2018 Michael Walker
Test/DejaFu/SCT/Internal.hs view
@@ -20,6 +20,7 @@ import qualified Data.IntMap.Strict               as I import           Data.List                        (find, mapAccumL) import           Data.Maybe                       (fromMaybe)+import           GHC.Stack                        (HasCallStack)  import           Test.DejaFu.Conc import           Test.DejaFu.Conc.Internal        (Context(..), DCSnapshot(..))@@ -34,7 +35,7 @@ -- * Exploration  -- | General-purpose SCT function.-sct :: MonadConc n+sct :: (MonadConc n, HasCallStack)   => Settings n a   -- ^ The SCT settings ('Way' is ignored)   -> ([ThreadId] -> s)@@ -75,11 +76,11 @@     runFull sched s = runConcurrent sched (_memtype settings) s conc     runSnap snap sched s = runWithDCSnapshot sched (_memtype settings) s snap -    debugFatal = if _debugFatal settings then fatal "sct" else debugPrint+    debugFatal = if _debugFatal settings then fatal else debugPrint     debugPrint = fromMaybe (const (pure ())) (_debugPrint settings)  -- | Like 'sct' but given a function to run the computation.-sct' :: MonadConc n+sct' :: (MonadConc n, HasCallStack)   => Settings n a   -- ^ The SCT settings ('Way' is ignored)   -> s@@ -95,7 +96,7 @@   -> CRefId   -- ^ The first available @CRefId@   -> n [(Either Failure a, Trace)]-sct' settings s0 sfun srun run nextTId nextCRId = go Nothing [] s0 where+sct' settings s0 sfun srun run nTId nCRId = go Nothing [] s0 where   go (Just res) _ _ | earlyExit res = pure []   go _ seen !s = case sfun s of     Just t -> srun s t >>= \case@@ -126,7 +127,7 @@   dosimplify res trace seen s     | not (_simplify settings) = ((res, trace) :) <$> go (Just res) seen s     | otherwise = do-        shrunk <- simplifyExecution settings run nextTId nextCRId res trace+        shrunk <- simplifyExecution settings run nTId nCRId res trace         (shrunk :) <$> go (Just res) seen s    earlyExit = fromMaybe (const False) (_earlyExit settings)@@ -146,7 +147,7 @@ -- Unlike shrinking in randomised property-testing tools like -- QuickCheck or Hedgehog, we only run the test case /once/, at the -- end, rather than after every simplification step.-simplifyExecution :: MonadConc n+simplifyExecution :: (MonadConc n, HasCallStack)   => Settings n a   -- ^ The SCT settings ('Way' is ignored)   -> (forall x. Scheduler x -> x -> n (Either Failure a, x, Trace))@@ -159,7 +160,7 @@   -- ^ The expected result   -> Trace   -> n (Either Failure a, Trace)-simplifyExecution settings run nextTId nextCRId res trace+simplifyExecution settings run nTId nCRId res trace     | tidTrace == simplifiedTrace = do         debugPrint ("Simplifying new result '" ++ p res ++ "': no simplification possible!")         pure (res, trace)@@ -176,9 +177,9 @@   where     tidTrace = toTIdTrace trace     simplifiedTrace = simplify (_memtype settings) tidTrace-    fixup = renumber (_memtype settings) (fromId nextTId) (fromId nextCRId)+    fixup = renumber (_memtype settings) (fromId nTId) (fromId nCRId) -    debugFatal = if _debugFatal settings then fatal "sct" else debugPrint+    debugFatal = if _debugFatal settings then fatal else debugPrint     debugPrint = fromMaybe (const (pure ())) (_debugPrint settings)     debugShow = fromMaybe (const "_") (_debugShow settings)     p = either show debugShow@@ -333,14 +334,14 @@   -- I can't help but feel there should be some generic programming   -- solution to this sort of thing (and to the many other functions   -- operating over @ThreadAction@s / @Lookahead@s)-  updateAction (tidmap, nexttid, cridmap, nextcrid) (Fork old) =-    let tidmap' = I.insert (fromId old) nexttid tidmap-        nexttid' = nexttid + 1-    in ((tidmap', nexttid', cridmap, nextcrid), Fork (toId nexttid))-  updateAction (tidmap, nexttid, cridmap, nextcrid) (ForkOS old) =-    let tidmap' = I.insert (fromId old) nexttid tidmap-        nexttid' = nexttid + 1-    in ((tidmap', nexttid', cridmap, nextcrid), ForkOS (toId nexttid))+  updateAction (tidmap, nTId, cridmap, nCRId) (Fork old) =+    let tidmap' = I.insert (fromId old) nTId tidmap+        nTId' = nTId + 1+    in ((tidmap', nTId', cridmap, nCRId), Fork (toId nTId))+  updateAction (tidmap, nTId, cridmap, nCRId) (ForkOS old) =+    let tidmap' = I.insert (fromId old) nTId tidmap+        nTId' = nTId + 1+    in ((tidmap', nTId', cridmap, nCRId), ForkOS (toId nTId))   updateAction s@(tidmap, _, _, _) (PutMVar mvid olds) =     (s, PutMVar mvid (map (renumbered tidmap) olds))   updateAction s@(tidmap, _, _, _) (TryPutMVar mvid b olds) =@@ -349,10 +350,10 @@     (s, TakeMVar mvid (map (renumbered tidmap) olds))   updateAction s@(tidmap, _, _, _) (TryTakeMVar mvid b olds) =     (s, TryTakeMVar mvid b (map (renumbered tidmap) olds))-  updateAction (tidmap, nexttid, cridmap, nextcrid) (NewCRef old) =-    let cridmap' = I.insert (fromId old) nextcrid cridmap-        nextcrid' = nextcrid + 1-    in ((tidmap, nexttid, cridmap', nextcrid'), NewCRef (toId nextcrid))+  updateAction (tidmap, nTId, cridmap, nCRId) (NewCRef old) =+    let cridmap' = I.insert (fromId old) nCRId cridmap+        nCRId' = nCRId + 1+    in ((tidmap, nTId, cridmap', nCRId'), NewCRef (toId nCRId))   updateAction s@(_, _, cridmap, _) (ReadCRef old) =     (s, ReadCRef (renumbered cridmap old))   updateAction s@(_, _, cridmap, _) (ReadCRefCas old) =
Test/DejaFu/SCT/Internal/DPOR.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ViewPatterns #-}  -- |@@ -8,7 +9,7 @@ -- License     : MIT -- Maintainer  : Michael Walker <mike@barrucadu.co.uk> -- Stability   : experimental--- Portability : DeriveAnyClass, DeriveGeneric, ViewPatterns+-- Portability : DeriveAnyClass, DeriveGeneric, FlexibleContexts, ViewPatterns -- -- Internal types and functions for SCT via dynamic partial-order -- reduction.  This module is NOT considered to form part of the@@ -31,6 +32,7 @@ import           Data.Set             (Set) import qualified Data.Set             as S import           GHC.Generics         (Generic)+import           GHC.Stack            (HasCallStack)  import           Test.DejaFu.Internal import           Test.DejaFu.Schedule (Scheduler(..))@@ -69,13 +71,13 @@ -- -- This is a reasonable thing to do, because if the state is corrupted -- then nothing sensible can happen anyway.-validateDPOR :: String -> DPOR -> DPOR-validateDPOR src dpor-    | not (todo `S.isSubsetOf` runnable) = fatal src "thread exists in todo set but not runnable set"-    | not (done `S.isSubsetOf` runnable) = fatal src "thread exists in done set but not runnable set"-    | not (taken `S.isSubsetOf` done) = fatal src "thread exists in taken set but not done set"-    | not (todo `disjoint` done) = fatal src "thread exists in both taken set and done set"-    | not (maybe True (`S.member` done) next) = fatal src "taken thread does not exist in done set"+validateDPOR :: HasCallStack => DPOR -> DPOR+validateDPOR dpor+    | not (todo `S.isSubsetOf` runnable) = fatal "thread exists in todo set but not runnable set"+    | not (done `S.isSubsetOf` runnable) = fatal "thread exists in done set but not runnable set"+    | not (taken `S.isSubsetOf` done) = fatal "thread exists in taken set but not done set"+    | not (todo `disjoint` done) = fatal "thread exists in both taken set and done set"+    | not (maybe True (`S.member` done) next) = fatal "taken thread does not exist in done set"     | otherwise = dpor   where     done = dporDone dpor@@ -151,8 +153,8 @@     sleeps = dporSleep dpor `M.union` dporTaken dpor  -- | Add a new trace to the stack.  This won't work if to-dos aren't explored depth-first.-incorporateTrace-  :: MemType+incorporateTrace :: HasCallStack+  => MemType   -> Bool   -- ^ Whether the \"to-do\" point which was used to create this new   -- execution was conservative or not.@@ -168,9 +170,9 @@     in case dporNext dpor of          Just (t, child)            | t == tid' ->-             validateDPOR "incorporateTrace (grow / Just)" $ dpor { dporNext = Just (tid', grow state' tid' rest child) }-           | hasTodos child -> fatal "incorporateTrace" "replacing child with todos!"-         _ -> validateDPOR "incorporateTrace (grow / Nothing)" $+             validateDPOR $ dpor { dporNext = Just (tid', grow state' tid' rest child) }+           | hasTodos child -> fatal "replacing child with todos!"+         _ -> validateDPOR $            let taken = M.insert tid' a (dporTaken dpor)                sleep = dporSleep dpor `M.union` dporTaken dpor            in dpor { dporTaken = if conservative then dporTaken dpor else taken@@ -178,13 +180,13 @@                    , dporNext  = Just (tid', subtree state' tid' sleep trc)                    , dporDone  = S.insert tid' (dporDone dpor)                    }-  grow _ _ [] _ = fatal "incorporateTrace" "trace exhausted without reading a to-do point!"+  grow _ _ [] _ = fatal "trace exhausted without reading a to-do point!"    -- check if there are to-do points in a tree   hasTodos dpor = not (M.null (dporTodo dpor)) || (case dporNext dpor of Just (_, dpor') -> hasTodos dpor'; _ -> False)    -- Construct a new subtree corresponding to a trace suffix.-  subtree state tid sleep ((_, _, a):rest) = validateDPOR "incorporateTrace (subtree)" $+  subtree state tid sleep ((_, _, a):rest) = validateDPOR $     let state' = updateDepState memtype state tid a         sleep' = M.filterWithKey (\t a' -> not $ dependent state' tid a t a') sleep     in DPOR@@ -205,7 +207,7 @@           ((d', _, a'):_) -> M.singleton (tidOf tid d') a'           [] -> M.empty         }-  subtree _ _ _ [] = fatal "incorporateTrace" "subtree suffix empty!"+  subtree _ _ _ [] = fatal "subtree suffix empty!"  -- | Produce a list of new backtracking points from an execution -- trace. These are then used to inform new \"to-do\" points in the@@ -299,8 +301,9 @@  -- | Add new backtracking points, if they have not already been -- visited and aren't in the sleep set.-incorporateBacktrackSteps :: [BacktrackStep] -> DPOR -> DPOR-incorporateBacktrackSteps (b:bs) dpor = validateDPOR "incorporateBacktrackSteps" dpor' where+incorporateBacktrackSteps :: HasCallStack+  => [BacktrackStep] -> DPOR -> DPOR+incorporateBacktrackSteps (b:bs) dpor = validateDPOR dpor' where   tid = bcktThreadid b    dpor' = dpor@@ -318,9 +321,9 @@    child = case dporNext dpor of     Just (t, d)-      | t /= tid -> fatal "incorporateBacktrackSteps" "incorporating wrong trace!"+      | t /= tid -> fatal "incorporating wrong trace!"       | otherwise -> incorporateBacktrackSteps bs d-    Nothing -> fatal "incorporateBacktrackSteps" "child is missing!"+    Nothing -> fatal "child is missing!" incorporateBacktrackSteps [] dpor = dpor  -------------------------------------------------------------------------------@@ -393,8 +396,8 @@ -- | Add a backtracking point. If the thread isn't runnable, add all -- runnable threads. If the backtracking point is already present, -- don't re-add it UNLESS this would make it conservative.-backtrackAt-  :: (ThreadId -> BacktrackStep -> Bool)+backtrackAt :: HasCallStack+  => (ThreadId -> BacktrackStep -> Bool)   -- ^ If this returns @True@, backtrack to all runnable threads,   -- rather than just the given thread.   -> BacktrackFunc@@ -423,7 +426,7 @@         ((i',c',t'):is') -> go i' bs (i'-i0-1) c' t' is'         [] -> bs   go i0 (b:bs) i c tid is = b : go i0 bs (i-1) c tid is-  go _ [] _ _ _ _ = fatal "backtrackAt" "ran out of schedule whilst backtracking!"+  go _ [] _ _ _ _ = fatal "ran out of schedule whilst backtracking!"    -- Backtrack to a single thread   backtrackTo tid c = M.insert tid c . bcktBacktracks@@ -439,8 +442,8 @@ -- the prior thread if it's (1) still runnable and (2) hasn't just -- yielded. Furthermore, threads which /will/ yield are ignored in -- preference of those which will not.-dporSched-  :: MemType+dporSched :: HasCallStack+  => MemType   -> IncrementalBoundFunc k   -- ^ Bound function: returns true if that schedule prefix terminated   -- with the lookahead decision fits within the bound.@@ -501,7 +504,7 @@     decision = decisionOf (fst <$> prior) (S.fromList tids)      -- Get the action of a thread-    action t = efromJust "dporSched.action" (lookup t threads')+    action t = efromJust (lookup t threads')      -- The runnable thread IDs     tids = map fst threads'
Test/DejaFu/Schedule.hs view
@@ -63,7 +63,7 @@   go _ threads g =     let threads' = map fst (toList threads)         (choice, g') = randomR (0, length threads' - 1) g-    in (Just $ eidx "randomSched" threads' choice, g')+    in (Just $ eidx threads' choice, g')  -- | A round-robin scheduler which, at every step, schedules the -- thread with the next 'ThreadId'.
dejafu.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                dejafu-version:             1.4.0.0+version:             1.5.0.0 synopsis:            A library for unit-testing concurrent programs.  description:@@ -33,7 +33,7 @@ source-repository this   type:     git   location: https://github.com/barrucadu/dejafu.git-  tag:      dejafu-1.4.0.0+  tag:      dejafu-1.5.0.0  library   exposed-modules:     Test.DejaFu@@ -58,17 +58,15 @@    -- other-modules:          -- other-extensions:    -  build-depends:       base              >=4.8 && <5-                     , concurrency       >=1.3 && <1.5+  build-depends:       base              >=4.9 && <5+                     , concurrency       >=1.5 && <1.6                      , containers        >=0.5 && <0.6                      , deepseq           >=1.1 && <2                      , exceptions        >=0.7 && <0.11                      , leancheck         >=0.6 && <0.8                      , profunctors       >=4.0 && <6.0                      , random            >=1.0 && <1.2-                     , transformers      >=0.4 && <0.6+                     , transformers      >=0.5 && <0.6   -- hs-source-dirs:         default-language:    Haskell2010   ghc-options:         -Wall-  if impl(ghc < 8.0.1)-    build-depends: semigroups >=0.16 && <0.19