@@ -133,6 +133,9 @@ import System.IO.Unsafe
133
133
import qualified Debug.Trace as Debug
134
134
135
135
136
+ -- | Select events according to the predicate function. It throws an error if
137
+ -- the simulation ends with 'Failure'.
138
+ --
136
139
selectTraceEvents
137
140
:: (Time -> SimEventType -> Maybe b )
138
141
-> SimTrace a
@@ -150,6 +153,9 @@ selectTraceEvents fn =
150
153
[]
151
154
. traceSelectTraceEvents fn
152
155
156
+ -- | Like 'selectTraceEvents', but it returns even if the simulation trace ends
157
+ -- with 'Failure'.
158
+ --
153
159
selectTraceEvents'
154
160
:: (Time -> SimEventType -> Maybe b )
155
161
-> SimTrace a
@@ -216,10 +222,10 @@ detachTraceRaces = Trace.filter (\a -> case a of
216
222
SimRacesFound {} -> False
217
223
_ -> True )
218
224
219
- -- | Select all the traced values matching the expected type. This relies on
220
- -- the sim's dynamic trace facility.
225
+ -- | Select all the traced values matching the expected type. It relies on the
226
+ -- sim's dynamic trace facility.
221
227
--
222
- -- For convenience, this throws exceptions for abnormal sim termination.
228
+ -- For convenience, it throws exceptions for abnormal sim termination.
223
229
--
224
230
selectTraceEventsDynamic :: forall a b . Typeable b => SimTrace a -> [b ]
225
231
selectTraceEventsDynamic = selectTraceEvents fn
@@ -228,7 +234,8 @@ selectTraceEventsDynamic = selectTraceEvents fn
228
234
fn _ (EventLog dyn) = fromDynamic dyn
229
235
fn _ _ = Nothing
230
236
231
- -- | Like 'selectTraceEventsDynamic' but also captures time of the trace event.
237
+ -- | Like 'selectTraceEventsDynamic' but it also captures time of the trace
238
+ -- event.
232
239
--
233
240
selectTraceEventsDynamicWithTime :: forall a b . Typeable b => SimTrace a -> [(Time , b )]
234
241
selectTraceEventsDynamicWithTime = selectTraceEvents fn
@@ -237,8 +244,8 @@ selectTraceEventsDynamicWithTime = selectTraceEvents fn
237
244
fn t (EventLog dyn) = (t,) <$> fromDynamic dyn
238
245
fn _ _ = Nothing
239
246
240
- -- | Like 'selectTraceEventsDynamic' but returns partial trace if an exception
241
- -- is found in it .
247
+ -- | Like 'selectTraceEventsDynamic' but it returns even if the simulation trace
248
+ -- ends with 'Failure' .
242
249
--
243
250
selectTraceEventsDynamic' :: forall a b . Typeable b => SimTrace a -> [b ]
244
251
selectTraceEventsDynamic' = selectTraceEvents' fn
@@ -247,7 +254,8 @@ selectTraceEventsDynamic' = selectTraceEvents' fn
247
254
fn _ (EventLog dyn) = fromDynamic dyn
248
255
fn _ _ = Nothing
249
256
250
- -- | Like `selectTraceEventsDynamic'` but also captures time of the trace event.
257
+ -- | Like `selectTraceEventsDynamic'` but it also captures time of the trace
258
+ -- event.
251
259
--
252
260
selectTraceEventsDynamicWithTime' :: forall a b . Typeable b => SimTrace a -> [(Time , b )]
253
261
selectTraceEventsDynamicWithTime' = selectTraceEvents' fn
@@ -258,7 +266,7 @@ selectTraceEventsDynamicWithTime' = selectTraceEvents' fn
258
266
259
267
-- | Get a trace of 'EventSay'.
260
268
--
261
- -- For convenience, this throws exceptions for abnormal sim termination.
269
+ -- For convenience, it throws exceptions for abnormal sim termination.
262
270
--
263
271
selectTraceEventsSay :: SimTrace a -> [String ]
264
272
selectTraceEventsSay = selectTraceEvents fn
@@ -267,7 +275,7 @@ selectTraceEventsSay = selectTraceEvents fn
267
275
fn _ (EventSay s) = Just s
268
276
fn _ _ = Nothing
269
277
270
- -- | Like 'selectTraceEventsSay' but also captures time of the trace event.
278
+ -- | Like 'selectTraceEventsSay' but it also captures time of the trace event.
271
279
--
272
280
selectTraceEventsSayWithTime :: SimTrace a -> [(Time , String )]
273
281
selectTraceEventsSayWithTime = selectTraceEvents fn
@@ -276,8 +284,8 @@ selectTraceEventsSayWithTime = selectTraceEvents fn
276
284
fn t (EventSay s) = Just (t, s)
277
285
fn _ _ = Nothing
278
286
279
- -- | Like 'selectTraceEventsSay' but return partial trace if an exception is
280
- -- found in it .
287
+ -- | Like 'selectTraceEventsSay' but it returns even if the simulation trace
288
+ -- ends with 'Failure' .
281
289
--
282
290
selectTraceEventsSay' :: SimTrace a -> [String ]
283
291
selectTraceEventsSay' = selectTraceEvents' fn
@@ -286,7 +294,7 @@ selectTraceEventsSay' = selectTraceEvents' fn
286
294
fn _ (EventSay s) = Just s
287
295
fn _ _ = Nothing
288
296
289
- -- | Like `selectTraceEventsSay'` but also captures time of the trace event.
297
+ -- | Like `selectTraceEventsSay'` but it also captures time of the trace event.
290
298
--
291
299
selectTraceEventsSayWithTime' :: SimTrace a -> [(Time , String )]
292
300
selectTraceEventsSayWithTime' = selectTraceEvents' fn
@@ -297,13 +305,13 @@ selectTraceEventsSayWithTime' = selectTraceEvents' fn
297
305
298
306
-- | Print all 'EventSay' to the console.
299
307
--
300
- -- For convenience, this throws exceptions for abnormal sim termination.
308
+ -- For convenience, it throws exceptions for abnormal sim termination.
301
309
--
302
310
printTraceEventsSay :: SimTrace a -> IO ()
303
311
printTraceEventsSay = mapM_ print . selectTraceEventsSay
304
312
305
313
306
- -- | The most general select function. It is a _total_ function.
314
+ -- | The most general select function. It is a /total function/ .
307
315
--
308
316
traceSelectTraceEvents
309
317
:: (Time -> SimEventType -> Maybe b )
@@ -324,7 +332,7 @@ traceSelectTraceEvents fn = bifoldr ( \ v _acc -> Nil v )
324
332
)
325
333
undefined -- it is ignored
326
334
327
- -- | Select dynamic events. It is a _total_ function.
335
+ -- | Select dynamic events. It is a /total function/ .
328
336
--
329
337
traceSelectTraceEventsDynamic :: forall a b . Typeable b
330
338
=> SimTrace a -> Trace (SimResult a ) b
@@ -335,7 +343,7 @@ traceSelectTraceEventsDynamic = traceSelectTraceEvents fn
335
343
fn _ _ = Nothing
336
344
337
345
338
- -- | Select say events. It is a _total_ function.
346
+ -- | Select say events. It is a /total function/ .
339
347
--
340
348
traceSelectTraceEventsSay :: forall a . SimTrace a -> Trace (SimResult a ) String
341
349
traceSelectTraceEventsSay = traceSelectTraceEvents fn
@@ -417,7 +425,7 @@ runSimOrThrow mainAction =
417
425
runSimStrictShutdown :: forall a . (forall s . IOSim s a ) -> Either Failure a
418
426
runSimStrictShutdown mainAction = traceResult True (runSimTrace mainAction)
419
427
420
- -- | Fold through the trace and return either a 'Failure' or the simulation
428
+ -- | Fold through the trace and return either 'Failure' or a simulation
421
429
-- result, i.e. the return value of the main thread.
422
430
--
423
431
traceResult :: Bool
@@ -502,19 +510,18 @@ runSimTrace mainAction = runST (runSimTraceST mainAction)
502
510
-- slot. In /IOSim/ and /IOSimPOR/ time only moves explicitly through timer
503
511
-- events, e.g. things like `Control.Monad.Class.MonadTimer.SI.threadDelay`,
504
512
-- `Control.Monad.Class.MonadTimer.SI.registerDelay` or the
505
- -- `Control.Monad.Class.MonadTimer.NonStandard. MonadTimeout` API. The usual
513
+ -- `Control.Monad.Class.MonadTimer.MonadTimeout.NonStandard ` API. The usual
506
514
-- QuickCheck techniques can help explore different schedules of
507
515
-- threads too.
508
516
509
517
-- | Execute a simulation, discover & revert races. Note that this will execute
510
518
-- the simulation multiple times with different schedules, and thus it's much
511
519
-- more costly than a simple `runSimTrace` (also the simulation environments has
512
- -- much more state to track and hence is slower).
520
+ -- much more state to track and hence it is slower).
513
521
--
514
522
-- On property failure it will show the failing schedule (`ScheduleControl`)
515
- -- which can be plugged to `controlSimTrace`.
516
- --
517
- -- Note: `exploreSimTrace` evaluates each schedule in parallel (using `par`).
523
+ -- which can be passed to `controlSimTrace` to reproduce the failure without
524
+ -- discovering the schedule.
518
525
--
519
526
exploreSimTrace
520
527
:: forall a test . Testable test
@@ -533,8 +540,6 @@ exploreSimTrace optsf main k =
533
540
-- | An 'ST' version of 'exploreSimTrace'. The callback also receives
534
541
-- 'ScheduleControl'. This is mostly useful for testing /IOSimPOR/ itself.
535
542
--
536
- -- Note: `exploreSimTraceST` evaluates each schedule sequentially.
537
- --
538
543
exploreSimTraceST
539
544
:: forall s a test . Testable test
540
545
=> (ExplorationOptions -> ExplorationOptions )
@@ -689,15 +694,15 @@ raceReversals ControlDefault = 0
689
694
raceReversals (ControlAwait mods) = length mods
690
695
raceReversals ControlFollow {} = error " Impossible: raceReversals ControlFollow{}"
691
696
692
- -- compareTraces is given (maybe) a passing trace and a failing trace,
697
+ -- `compareTracesST` is given (maybe) a passing trace and a failing trace,
693
698
-- and identifies the point at which they diverge, where it inserts a
694
699
-- "sleep" event for the thread that is delayed in the failing case,
695
700
-- and a "wake" event before its next action. It also returns the
696
701
-- identity and time of the sleeping thread. Since we expect the trace
697
702
-- to be consumed lazily (and perhaps only partially), and since the
698
703
-- sleeping thread is not of interest unless the trace is consumed
699
704
-- this far, then we collect its identity only if it is reached using
700
- -- unsafePerformIO.
705
+ -- ` unsafePerformIO` .
701
706
702
707
-- TODO: return StepId
703
708
compareTracesST :: forall a b s .
0 commit comments