packages feed

dejafu 0.5.0.2 → 0.5.1.0

raw patch · 6 files changed

+201/−11 lines, 6 filesdep +deepseqPVP ok

version bump matches the API change (PVP)

Dependencies added: deepseq

API changes (from Hackage documentation)

+ Test.DejaFu: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Test.DejaFu.Result a)
+ Test.DejaFu: instance GHC.Classes.Eq a => GHC.Classes.Eq (Test.DejaFu.Result a)
+ Test.DejaFu.Common: instance Control.DeepSeq.NFData Test.DejaFu.Common.ActionType
+ Test.DejaFu.Common: instance Control.DeepSeq.NFData Test.DejaFu.Common.CRefId
+ Test.DejaFu.Common: instance Control.DeepSeq.NFData Test.DejaFu.Common.Decision
+ Test.DejaFu.Common: instance Control.DeepSeq.NFData Test.DejaFu.Common.Failure
+ Test.DejaFu.Common: instance Control.DeepSeq.NFData Test.DejaFu.Common.IdSource
+ Test.DejaFu.Common: instance Control.DeepSeq.NFData Test.DejaFu.Common.Lookahead
+ Test.DejaFu.Common: instance Control.DeepSeq.NFData Test.DejaFu.Common.MVarId
+ Test.DejaFu.Common: instance Control.DeepSeq.NFData Test.DejaFu.Common.MemType
+ Test.DejaFu.Common: instance Control.DeepSeq.NFData Test.DejaFu.Common.TAction
+ Test.DejaFu.Common: instance Control.DeepSeq.NFData Test.DejaFu.Common.TVarId
+ Test.DejaFu.Common: instance Control.DeepSeq.NFData Test.DejaFu.Common.ThreadAction
+ Test.DejaFu.Common: instance Control.DeepSeq.NFData Test.DejaFu.Common.ThreadId
+ Test.DejaFu.Common: instance GHC.Classes.Eq Test.DejaFu.Common.IdSource
+ Test.DejaFu.Common: instance GHC.Classes.Ord Test.DejaFu.Common.IdSource
+ Test.DejaFu.Common: instance GHC.Show.Show Test.DejaFu.Common.IdSource
+ Test.DejaFu.SCT: instance Control.DeepSeq.NFData Test.DejaFu.SCT.Bounds
+ Test.DejaFu.SCT: instance Control.DeepSeq.NFData Test.DejaFu.SCT.FairBound
+ Test.DejaFu.SCT: instance Control.DeepSeq.NFData Test.DejaFu.SCT.LengthBound
+ Test.DejaFu.SCT: instance Control.DeepSeq.NFData Test.DejaFu.SCT.PreemptionBound
+ Test.DejaFu.SCT: instance Control.DeepSeq.NFData g => Control.DeepSeq.NFData (Test.DejaFu.SCT.Way g)
+ Test.DejaFu.SCT: resultsSet' :: (MonadRef r n, RandomGen g, Ord a, NFData a) => Way g -> MemType -> Conc n r a -> n (Set (Either Failure a))
+ Test.DejaFu.SCT: runSCT' :: (MonadRef r n, RandomGen g, NFData a) => Way g -> MemType -> Conc n r a -> n [(Either Failure a, Trace)]
+ Test.DejaFu.SCT.Internal: instance Control.DeepSeq.NFData Test.DejaFu.SCT.Internal.BacktrackStep
+ Test.DejaFu.SCT.Internal: instance Control.DeepSeq.NFData Test.DejaFu.SCT.Internal.DPOR
+ Test.DejaFu.SCT.Internal: instance Control.DeepSeq.NFData Test.DejaFu.SCT.Internal.DPORSchedState
+ Test.DejaFu.SCT.Internal: instance Control.DeepSeq.NFData Test.DejaFu.SCT.Internal.DepState
+ Test.DejaFu.SCT.Internal: instance Control.DeepSeq.NFData g => Control.DeepSeq.NFData (Test.DejaFu.SCT.Internal.RandSchedState g)
+ Test.DejaFu.SCT.Internal: instance GHC.Classes.Eq Test.DejaFu.SCT.Internal.BacktrackStep
+ Test.DejaFu.SCT.Internal: instance GHC.Classes.Eq Test.DejaFu.SCT.Internal.DPOR
+ Test.DejaFu.SCT.Internal: instance GHC.Classes.Eq Test.DejaFu.SCT.Internal.DPORSchedState
+ Test.DejaFu.SCT.Internal: instance GHC.Classes.Eq g => GHC.Classes.Eq (Test.DejaFu.SCT.Internal.RandSchedState g)
+ Test.DejaFu.SCT.Internal: instance GHC.Show.Show g => GHC.Show.Show (Test.DejaFu.SCT.Internal.RandSchedState g)
+ Test.DejaFu.STM.Internal: instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Test.DejaFu.STM.Internal.Result a)

Files

Test/DejaFu.hs view
@@ -243,6 +243,7 @@   ) where  import Control.Arrow (first)+import Control.DeepSeq (NFData(..)) import Control.Monad (when, unless) import Control.Monad.Ref (MonadRef) import Control.Monad.ST (runST)@@ -398,7 +399,14 @@   -- ^ The failing cases, if any.   , _failureMsg   :: String   -- ^ A message to display on failure, if nonempty-  } deriving Show+  } deriving (Eq, Show)++instance NFData a => NFData (Result a) where+  rnf r = rnf ( _pass         r+              , _casesChecked r+              , _failures     r+              , _failureMsg   r+              )  -- | A failed result, taking the given list of failures. defaultFail :: [(Either Failure a, Trace)] -> Result a
Test/DejaFu/Common.hs view
@@ -60,6 +60,7 @@   , MemType(..)   ) where +import Control.DeepSeq (NFData(..)) import Control.Exception (MaskingState(..)) import Data.List (sort, nub, intercalate) import Data.List.NonEmpty (NonEmpty)@@ -81,6 +82,9 @@   show (ThreadId (Just n) _) = n   show (ThreadId Nothing  i) = show i +instance NFData ThreadId where+  rnf (ThreadId n i) = rnf (n, i)+ -- | Every @CRef@ has a unique identifier. data CRefId = CRefId (Maybe String) Int   deriving Eq@@ -92,6 +96,9 @@   show (CRefId (Just n) _) = n   show (CRefId Nothing  i) = show i +instance NFData CRefId where+  rnf (CRefId n i) = rnf (n, i)+ -- | Every @MVar@ has a unique identifier. data MVarId = MVarId (Maybe String) Int   deriving Eq@@ -103,6 +110,9 @@   show (MVarId (Just n) _) = n   show (MVarId Nothing  i) = show i +instance NFData MVarId where+  rnf (MVarId n i) = rnf (n, i)+ -- | Every @TVar@ has a unique identifier. data TVarId = TVarId (Maybe String) Int   deriving Eq@@ -114,6 +124,9 @@   show (TVarId (Just n) _) = n   show (TVarId Nothing  i) = show i +instance NFData TVarId where+  rnf (TVarId n i) = rnf (n, i)+ -- | The ID of the initial thread. initialThread :: ThreadId initialThread = ThreadId (Just "main") 0@@ -132,8 +145,19 @@   , _usedMVNames :: [String]   , _usedTVNames :: [String]   , _usedTNames  :: [String]-  }+  } deriving (Eq, Ord, Show) +instance NFData IdSource where+  rnf idsource = rnf ( _nextCRId idsource+                     , _nextMVId idsource+                     , _nextTVId idsource+                     , _nextTId  idsource+                     , _usedCRNames idsource+                     , _usedMVNames idsource+                     , _usedTVNames idsource+                     , _usedTNames  idsource+                     )+ -- | Get the next free 'CRefId'. nextCRId :: String -> IdSource -> (IdSource, CRefId) nextCRId name idsource = (newIdSource, newCRId) where@@ -264,6 +288,36 @@   -- ^ Stop executing an action with @subconcurrency@.   deriving (Eq, Show) +instance NFData ThreadAction where+  rnf (Fork t) = rnf t+  rnf (GetNumCapabilities c) = rnf c+  rnf (SetNumCapabilities c) = rnf c+  rnf (NewMVar m) = rnf m+  rnf (PutMVar m ts) = rnf (m, ts)+  rnf (BlockedPutMVar m) = rnf m+  rnf (TryPutMVar m b ts) = rnf (m, b, ts)+  rnf (ReadMVar m) = rnf m+  rnf (TryReadMVar m b) = rnf (m, b)+  rnf (BlockedReadMVar m) = rnf m+  rnf (TakeMVar m ts) = rnf (m, ts)+  rnf (BlockedTakeMVar m) = rnf m+  rnf (TryTakeMVar m b ts) = rnf (m, b, ts)+  rnf (NewCRef c) = rnf c+  rnf (ReadCRef c) = rnf c+  rnf (ReadCRefCas c) = rnf c+  rnf (ModCRef c) = rnf c+  rnf (ModCRefCas c) = rnf c+  rnf (WriteCRef c) = rnf c+  rnf (CasCRef c b) = rnf (c, b)+  rnf (CommitCRef t c) = rnf (t, c)+  rnf (STM tr ts) = rnf (tr, ts)+  rnf (BlockedSTM tr) = rnf tr+  rnf (ThrowTo t) = rnf t+  rnf (BlockedThrowTo t) = rnf t+  rnf (SetMasking b m) = b `seq` m `seq` ()+  rnf (ResetMasking b m) = b `seq` m `seq` ()+  rnf a = a `seq` ()+ -- | Check if a @ThreadAction@ immediately blocks. isBlock :: ThreadAction -> Bool isBlock (BlockedThrowTo  _) = True@@ -367,6 +421,26 @@   -- ^ Will stop executing an extion with @subconcurrency@.   deriving (Eq, Show) +instance NFData Lookahead where+  rnf (WillSetNumCapabilities c) = rnf c+  rnf (WillPutMVar m) = rnf m+  rnf (WillTryPutMVar m) = rnf m+  rnf (WillReadMVar m) = rnf m+  rnf (WillTryReadMVar m) = rnf m+  rnf (WillTakeMVar m) = rnf m+  rnf (WillTryTakeMVar m) = rnf m+  rnf (WillReadCRef c) = rnf c+  rnf (WillReadCRefCas c) = rnf c+  rnf (WillModCRef c) = rnf c+  rnf (WillModCRefCas c) = rnf c+  rnf (WillWriteCRef c) = rnf c+  rnf (WillCasCRef c) = rnf c+  rnf (WillCommitCRef t c) = rnf (t, c)+  rnf (WillThrowTo t) = rnf t+  rnf (WillSetMasking b m) = b `seq` m `seq` ()+  rnf (WillResetMasking b m) = b `seq` m `seq` ()+  rnf l = l `seq` ()+ -- | Convert a 'ThreadAction' into a 'Lookahead': \"rewind\" what has -- happened. 'Killed' has no 'Lookahead' counterpart. rewind :: ThreadAction -> Maybe Lookahead@@ -454,6 +528,17 @@   -- communication.   deriving (Eq, Show) +instance NFData ActionType where+  rnf (UnsynchronisedRead c) = rnf c+  rnf (UnsynchronisedWrite c) = rnf c+  rnf (PartiallySynchronisedCommit c) = rnf c+  rnf (PartiallySynchronisedWrite c) = rnf c+  rnf (PartiallySynchronisedModify c) = rnf c+  rnf (SynchronisedModify c) = rnf c+  rnf (SynchronisedRead m) = rnf m+  rnf (SynchronisedWrite m) = rnf m+  rnf a = a `seq` ()+ -- | Check if an action imposes a write barrier. isBarrier :: ActionType -> Bool isBarrier (SynchronisedModify _) = True@@ -547,6 +632,13 @@   -- ^ Terminate successfully and commit effects.   deriving (Eq, Show) +instance NFData TAction where+  rnf (TRead t) = rnf t+  rnf (TWrite t) = rnf t+  rnf (TOrElse tr mtr) = rnf (tr, mtr)+  rnf (TCatch tr mtr) = rnf (tr, mtr)+  rnf ta = ta `seq` ()+ ------------------------------------------------------------------------------- -- Traces @@ -569,6 +661,11 @@   -- ^ Pre-empt the running thread, and switch to another.   deriving (Eq, Show) +instance NFData Decision where+  rnf (Start t) = rnf t+  rnf (SwitchTo t) = rnf t+  rnf d = d `seq` ()+ -- | 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.@@ -646,6 +743,9 @@   -- multiple threads existed.   deriving (Eq, Show, Read, Ord, Enum, Bounded) +instance NFData Failure where+  rnf f = f `seq` ()+ -- | Pretty-print a failure showFail :: Failure -> String showFail Abort = "[abort]"@@ -676,6 +776,9 @@   -- are not necessarily committed in the same order that they are   -- created.   deriving (Eq, Show, Read, Ord, Enum, Bounded)++instance NFData MemType where+  rnf m = m `seq` ()  ------------------------------------------------------------------------------- -- Utilities
Test/DejaFu/SCT.hs view
@@ -13,7 +13,9 @@   ( -- * Running Concurrent Programs     Way(..)   , runSCT+  , runSCT'   , resultsSet+  , resultsSet'    -- * Bounded Partial-order Reduction @@ -88,6 +90,7 @@   , sctRandom   ) where +import Control.DeepSeq (NFData(..)) import Control.Monad.Ref (MonadRef) import Data.List (foldl') import qualified Data.Map.Strict as M@@ -112,6 +115,10 @@   -- PRNG.   deriving (Eq, Ord, Read, Show) +instance NFData g => NFData (Way g) where+  rnf (Systematically bs) = rnf bs+  rnf (Randomly g n) = rnf (g, n)+ -- | Explore possible executions of a concurrent program. -- -- * If the 'Way' is @Systematically@, 'sctBound' is used.@@ -128,6 +135,16 @@ runSCT (Systematically cb) memtype = sctBound memtype cb runSCT (Randomly g lim)    memtype = sctRandom memtype g lim +-- | A strict variant of 'runSCT'.+--+-- Demanding the result of this will force it to normal form, which+-- may be more efficient in some situations.+runSCT' :: (MonadRef r n, RandomGen g, NFData a)+  => Way g -> MemType -> Conc n r a -> n [(Either Failure a, Trace)]+runSCT' way memtype conc = do+  res <- runSCT way memtype conc+  rnf res `seq` pure res+ -- | Return the set of results of a concurrent program. resultsSet :: (MonadRef r n, RandomGen g, Ord a)   => Way g@@ -140,6 +157,16 @@ resultsSet way memtype conc =   S.fromList . map fst <$> runSCT way memtype conc +-- | A strict variant of 'resultsSet'.+--+-- Demanding the result of this will force it to normal form, which+-- may be more efficient in some situations.+resultsSet' :: (MonadRef r n, RandomGen g, Ord a, NFData a)+  => Way g -> MemType -> Conc n r a -> n (Set (Either Failure a))+resultsSet' way memtype conc = do+  res <- resultsSet' way memtype conc+  rnf res `seq` pure res+ ------------------------------------------------------------------------------- -- Combined Bounds @@ -149,6 +176,12 @@   , boundLength :: Maybe LengthBound   } deriving (Eq, Ord, Read, Show) +instance NFData Bounds where+  rnf bs = rnf ( boundPreemp bs+               , boundFair   bs+               , boundLength bs+               )+ -- | No bounds enabled. This forces the scheduler to just use -- partial-order reduction and sleep sets to prune the search -- space. This will /ONLY/ work if your computation always terminates!@@ -180,7 +213,7 @@ -- Pre-emption bounding  newtype PreemptionBound = PreemptionBound Int-  deriving (Enum, Eq, Ord, Num, Real, Integral, Read, Show)+  deriving (Enum, Eq, Ord, Num, Real, Integral, Read, Show, NFData)  -- | An SCT runner using a pre-emption bounding scheduler. sctPreBound :: MonadRef r n@@ -223,7 +256,7 @@ -- Fair bounding  newtype FairBound = FairBound Int-  deriving (Enum, Eq, Ord, Num, Real, Integral, Read, Show)+  deriving (Enum, Eq, Ord, Num, Real, Integral, Read, Show, NFData)  -- | An SCT runner using a fair bounding scheduler. sctFairBound :: MonadRef r n@@ -252,7 +285,7 @@ -- Length bounding  newtype LengthBound = LengthBound Int-  deriving (Enum, Eq, Ord, Num, Real, Integral, Read, Show)+  deriving (Enum, Eq, Ord, Num, Real, Integral, Read, Show, NFData)  -- | An SCT runner using a length bounding scheduler. sctLengthBound :: MonadRef r n
Test/DejaFu/SCT/Internal.hs view
@@ -11,6 +11,7 @@ -- interface of this library. module Test.DejaFu.SCT.Internal where +import Control.DeepSeq (NFData(..)) import Control.Exception (MaskingState(..)) import Data.Char (ord) import Data.Function (on)@@ -52,8 +53,17 @@   , dporAction   :: Maybe ThreadAction   -- ^ What happened at this step. This will be 'Nothing' at the root,   -- 'Just' everywhere else.-  } deriving Show+  } deriving (Eq, Show) +instance NFData DPOR where+  rnf dpor = rnf ( dporRunnable dpor+                 , dporTodo     dpor+                 , dporDone     dpor+                 , dporSleep    dpor+                 , dporTaken    dpor+                 , dporAction   dpor+                 )+ -- | One step of the execution, including information for backtracking -- purposes. This backtracking information is used to generate new -- schedules.@@ -71,8 +81,17 @@   -- alternatives were added conservatively due to the bound.   , bcktState      :: DepState   -- ^ Some domain-specific state at this point.-  } deriving Show+  } deriving (Eq, Show) +instance NFData BacktrackStep where+  rnf bs = rnf ( bcktThreadid   bs+               , bcktDecision   bs+               , bcktAction     bs+               , bcktRunnable   bs+               , bcktBacktracks bs+               , bcktState      bs+               )+ -- | Initial DPOR state, given an initial thread ID. This initial -- thread should exist and be runnable at the start of execution. initialState :: DPOR@@ -311,8 +330,17 @@   , schedDepState  :: DepState   -- ^ State used by the dependency function to determine when to   -- remove decisions from the sleep set.-  } deriving Show+  } deriving (Eq, Show) +instance NFData DPORSchedState where+  rnf s = rnf ( schedSleep     s+              , schedPrefix    s+              , schedBPoints   s+              , schedIgnore    s+              , schedBoundKill s+              , schedDepState  s+              )+ -- | Initial DPOR scheduler state for a given prefix initialDPORSchedState :: Map ThreadId ThreadAction   -- ^ The initial sleep set.@@ -499,8 +527,13 @@   -- ^ The thread weights: used in determining which to run.   , schedGen     :: g   -- ^ The random number generator.-  }+  } deriving (Eq, Show) +instance NFData g => NFData (RandSchedState g) where+  rnf s = rnf ( schedWeights s+              , schedGen     s+              )+ -- | Initial weighted random scheduler state. initialRandSchedState :: g -> RandSchedState g initialRandSchedState = RandSchedState M.empty@@ -540,6 +573,11 @@   -- provides compatibility with dpor-0.1, where the thread IDs are   -- not available.   } deriving (Eq, Show)++instance NFData DepState where+  rnf depstate = rnf ( depCRState depstate+                     , [(t, m `seq` ()) | (t, m) <- M.toList (depMaskState depstate)]+                     )  -- | Initial dependency state. initialDepState :: DepState
Test/DejaFu/STM/Internal.hs view
@@ -15,6 +15,7 @@ -- public interface of this library. module Test.DejaFu.STM.Internal where +import Control.DeepSeq (NFData(..)) import Control.Exception (Exception, SomeException, fromException, toException) import Control.Monad.Cont (Cont, runCont) import Control.Monad.Ref (MonadRef, newRef, readRef, writeRef)@@ -70,6 +71,12 @@   | Exception SomeException   -- ^ The transaction aborted by throwing an exception.   deriving Show++-- | This only reduces a 'SomeException' to WHNF.+instance NFData a => NFData (Result a) where+  rnf (Success tr1 tr2 a) = rnf (tr1, tr2, a)+  rnf (Retry tr) = rnf tr+  rnf (Exception e) = e `seq` ()  -- | Check if a 'Result' is a @Success@. isSTMSuccess :: Result a -> Bool
dejafu.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                dejafu-version:             0.5.0.2+version:             0.5.1.0 synopsis:            Systematic testing for Haskell concurrency.  description:@@ -74,7 +74,7 @@ source-repository this   type:     git   location: https://github.com/barrucadu/dejafu.git-  tag:      dejafu-0.5.0.2+  tag:      dejafu-0.5.1.0  library   exposed-modules:     Test.DejaFu@@ -96,6 +96,7 @@   build-depends:       base              >=4.8  && <5                      , concurrency       ==1.1.0.*                      , containers        >=0.5  && <0.6+                     , deepseq           >=1.1  && <2                      , exceptions        >=0.7  && <0.9                      , monad-loops       >=0.4  && <0.5                      , mtl               >=2.2  && <2.3