HORIZON HASKELLDocslts/ghc-9.14.xd82dee82026-10-12Search names, modules, packages, or :: a typeCtrl K

GHC 9.14.1 · lts/ghc-9.14.x · d82dee8 · 2026-10-12

Moduleio-sim-1.8.0.1GHC2021

Control.Monad.IOSim

  • 19 types
  • 46 values
  • Packageio-sim-1.8.0.1
  • Exports73
  • LanguageGHC2021
  • LicenceApache-2.0
  • SourceTypes.hs

Simulation monad

2 declarations
newtypenewtype IOSim s a
#
Instances56Monad, Functor, MonadFix, MonadFail, Applicative, Alternative, …
  • Monad (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • Functor (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadFix (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadFail (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • Applicative (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • Alternative (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadPlus (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadCatch (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadMask (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadThrow (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • PrimMonad (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types

    This provides access to (almost) everything from the primitive package, but don't try to use the MVars as that will not work as expected.

  • MonadInspectMVar (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadLabelledMVar (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadMVar (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadTraceMVar (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadMask (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadEvaluate (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadCatch (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadInspectSTM (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadLabelledSTM (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadSTM (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadTraceSTM (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types

    This instance adds a trace when a variable was written, just after the stm transaction was committed.

    Traces the first value using dynamic tracing, like traceM does, i.e. with EventDynamic; the string is traced using EventSay.

  • MonadAsync (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadThrow (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadTimer (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadFork (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadThread (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadEventlog (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadST (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadSay (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadTest (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadMaskingState (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadMonotonicTimeNSec (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadTime (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadDelay (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadDelay (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadTimer (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • MonadMonotonicTime (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • Semigroup a => Semigroup (IOSim s a)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • Monoid a => Monoid (IOSim s a)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • NoThunks (IOSim s a)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types

    Just like the IO instance, we don't actually check anything here

  • NoThunks a => NoThunks (StrictTVar (IOSim s) a)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type PrimState (IOSim s) = sDefined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type InspectMVarMonad (IOSim s) = ST sDefined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type MVar (IOSim s) = MVarDefault (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type InspectMonadSTM (IOSim s) = ST sDefined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type STM (IOSim s) = STM sDefined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type TArray (IOSim s) = TArrayDefault (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type TBQueue (IOSim s) = TBQueueDefault (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type TChan (IOSim s) = TChanDefault (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type TMVar (IOSim s) = TMVarDefault (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type TQueue (IOSim s) = TQueueDefault (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type TVar (IOSim s) = TVar sDefined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type TSem (IOSim s) = TSemDefault (IOSim s)Defined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type Async (IOSim s) = Async sDefined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
  • type ThreadId (IOSim s) = IOSimThreadIdDefined in io-sim-1.8.0.1 · Control.Monad.IOSim.Types
typetype STMSim = STM
#

IOSim's STM monad, as IOSim it is parametrised by s, e.g. STMSim s a is monadic expression of type a.

Run simulation

valuerunSimOrThrow :: (forall s. IOSim s a) -> a
#

For quick experiments and tests it is often appropriate and convenient to simply throw failures as exceptions.

valuerunSimStrictShutdown :: (forall s. IOSim s a) -> Either Failure a
#

Like runSim but fail when the main thread terminates if there are other threads still running or blocked. If one is trying to follow a strict thread clean-up policy then this helps testing for that.

datadata Failure
#

Simulation terminated a failure.

Constructors

Instances2Show, Exception

QuickCheck Monadic combinators

valuemonadicIOSim
  1. :: (Testable a, forall s. Monad (m s))
  2. => (SimTrace Property -> Property)

    Allows to trace SimTrace in counterexamples. The simplest use case is to pass:

    either (\e -> counterexample (show e) False) id . traceResult False

    as monadicIOSim_ does.

  3. -> (forall s a1. m s a1 -> IOSim s a1)

    natural transformation from m to IOSim` s

  4. -> (forall s. PropertyM (m s) a)
  5. -> Property
#

A more general version of monadicIOSim_, which:

  • allows to run in monad stacks build on top of IOSim;

  • gives more control how to attach debugging information to failed tests.

Note, to use this combinator your monad needs to be defined as:

newtype M s a = M s { runM :: ReaderT State (IOSim s) a }

It's important that `M s` is a monad. For such a monad one you'll need provide a natural transformation: -- the state could also be created as an IOSim computation. nat :: forall s a. State -> M s a -> IOSim s a nat state m = runStateT (runM m) state

Explore races using IOSimPOR

IOSimPOR is a different interpreter of IOSim which has the ability to discover race conditions and replay the simulation using a schedule which reverts them. For extended documentation how to use it see here.

IOSimPOR only discovers races between events which happen in the same time slot. In IOSim and IOSimPOR time only moves explicitly through timer events, e.g. things like Control.Monad.Class.MonadTimer.SI.threadDelay, Control.Monad.Class.MonadTimer.SI.registerDelay or the Control.Monad.Class.MonadTimer.MonadTimeout.NonStandard API. The usual QuickCheck techniques can help explore different schedules of threads too.

valueexploreSimTrace
  1. :: Testable test
  2. => (ExplorationOptions -> ExplorationOptions)

    modify default exploration options

  3. -> (forall s. IOSim s a)

    a simulation to run

  4. -> (Maybe (SimTrace a) -> SimTrace a -> test)

    a callback which receives the previous trace (e.g. before reverting a race condition) and current trace

  5. -> Property
#

Execute a simulation, discover & revert races. Note that this will execute the simulation multiple times with different schedules, and thus it's much more costly than a simple runSimTrace (also the simulation environments has much more state to track and hence it is slower).

On property failure it will show the failing schedule (ScheduleControl) which can be passed to controlSimTrace to reproduce the failure without discovering the schedule.

datadata ScheduleMod
#

A schedule modification inserted at given execution step.

Constructors

Instances3Eq, Ord, Show
  • Eq ScheduleModDefined in io-sim-1.8.0.1 · Control.Monad.IOSimPOR.Types
  • Ord ScheduleModDefined in io-sim-1.8.0.1 · Control.Monad.IOSimPOR.Types
  • Show ScheduleModDefined in io-sim-1.8.0.1 · Control.Monad.IOSimPOR.Types
datadata ScheduleControl
#

Modified execution schedule.

Constructors

  • ControlDefault

    default scheduling mode

  • ControlAwait [ScheduleMod]

    if the current control is ControlAwait, the normal scheduling will proceed, until the thread found in the first ScheduleMod reaches the given step. At this point the thread is put to sleep, until after all the steps are followed.

  • ControlFollow [StepId] [ScheduleMod]

    follow the steps then continue with schedule modifications. This control is set by followControl when controlTargets returns true.

Instances3Eq, Ord, Show

Exploration options

datadata ExplorationOptions
#

Race exploration options.

Constructors

  • ExplorationOptions
    • explorationScheduleBound :: Int

      This is an upper bound on the number of schedules with race reversals that will be explored; a bound of zero means that the default schedule will be explored, but no others. Setting the bound to zero makes IOSimPOR behave rather like IOSim, in that only one schedule is explored, but (a) IOSimPOR is considerably slower, because it still collects information on potential races, and (b) the IOSimPOR schedule is different (based on priorities, in contrast to IOSim's round-robin), and plays better with shrinking.

      The default value is `100`.

    • explorationBranching :: Int

      The branching factor. This is the number of alternative schedules that IOSimPOR tries to run, per race reversal. With the default parameters, IOSimPOR will try to reverse the first 33 (100 div 3) races discovered using the default schedule, then (if 33 or more races are discovered), for each such reversed race, will run the reversal and try to reverse two more races in the resulting schedule. A high branching factor will explore more combinations of reversing fewer races, within the overall schedule bound. A branching factor of one will explore only schedules resulting from a single race reversal (unless there are fewer races available to be reversed than the schedule bound).

      The default value is `3`.

    • explorationStepTimelimit :: Maybe Int

      Limit on the computation time allowed per scheduling step, for catching infinite loops etc.

      The default value is Nothing.

    • explorationReplay :: Maybe ScheduleControl

      A schedule to replay.

      The default value is Nothing.

    • explorationDebugLevel :: Int

      Log detailed trace to stderr containing information on discovered races. The trace does not contain the result of the simulation, unless one will do that explicitly inside the simulation.

      level 0: don't show any output, level 1: show simulation trace with discovered schedules level 2: show simulation trace with discovered schedules and races

      NOTE: discovered schedules & races are not exposed to the user in the callback of exploreSimTrace or in the output of controlSimTrace.

Instances1Show

Lift ST computations

1 declaration

Simulation time

2 declarations
valueunshareClock :: IOSim s ()
#

Put the thread into a new wall clock domain, not shared with the parent thread. Changing the wall clock time in the new clock domain will not affect the other clock of other threads. All threads forked by this thread from this point onwards will share the new clock domain.

Simulation trace

19 declarations
datadata Trace a b
#

A cons list with polymorphic nil.

  • Trace Void a is an infinite stream

  • Trace () a is isomorphic to [a]

Usually used with a being a non empty sum type.

Constructors

Instances18Bifoldable, Bifunctor, Bitraversable, Monad, Functor, MonadFix, …
valuetraceResult
  1. :: Bool

    if True the simulation will fail if there are any threads which didn't terminated when the main thread terminated.

  2. -> SimTrace a

    simulation trace

  3. -> Either Failure a
#

Fold through the trace and return either Failure or a simulation result, i.e. the return value of the main thread.

datadata SimResult a
#

A result type of a simulation.

Constructors

Instances2Functor, Show
datadata SimEvent
#

Trace is a recursive data type, it is the trace of a IOSim computation. The trace will contain information about thread scheduling, blocking on TVars, and other internal state changes of IOSim. More importantly it also supports traces generated by the computation with say (which corresponds to using putStrLn in IO), traceEventM, or dynamically typed traces with traceM (which generalise the base library traceM)

It also contains information on discovered races.

See also: traceEvents, traceResult, selectTraceEvents, selectTraceEventsDynamic and printTraceEventsSay.

Instances3Show, Generic, Rep
datadata SimEventType
#

Events recorded by the simulation.

Constructors

Instances1Show
datadata IOSimThreadId
#

A thread id.

IOSimPOR: RacyThreadId indicates that this thread is taken into account when discovering races. A thread is marked as racy iff exploreRaces was executed in it or it's a thread forked by a racy thread.

Constructors

  • RacyThreadId [Int]

    A racy thread (IOSimPOR only), shown in the trace with curly braces, e.g. `Thread {2,3}`.

  • ThreadId [Int]

    A non racy thread. They have higher priority than racy threads in IOSimPOR scheduler.

Instances8Eq, Ord, Show, Generic, NFData, Hashable, …
datadata Labelled a
#

A labelled value.

For example labelThread or labelTVar will insert a label to IOSimThreadId (or TVarId).

Constructors

Instances6Functor, Eq, Ord, Show, Generic, Rep

Dynamic Tracing

valuetraceM :: Typeable a => a -> IOSim s ()
#

IOSim has the ability to store any Typeable value in its trace which can then be recovered with selectTraceEventsDynamic or selectTraceEventsDynamic'.

valuetraceSTM :: Typeable a => a -> STMSim s ()
#

Trace a value, in the same was as traceM does, but from the STM monad. This is primarily useful for debugging.

Pretty printers

valueppTrace :: Show a => SimTrace a -> String
#

Pretty print simulation trace.

Note: this is not a streaming function, it will evaluate the whole trace before printing it. If you need to print a very large trace, you might want to use

ppTrace show (ppSimEvent 0 0 0)
valueppDebug :: SimTrace a -> x -> x
#

Trace each event using trace; this is useful when a trace ends with a pure error, e.g. an assertion.

Selectors

list selectors

valueselectTraceEventsDynamic :: Typeable b => SimTrace a -> [b]
#

Select all the traced values matching the expected type. It relies on the sim's dynamic trace facility.

For convenience, it throws exceptions for abnormal sim termination.

trace selectors

IO printer

Eventlog

2 declarations

Low-level API

5 declarations