Skip to content

Commit b2e291d

Browse files
committed
io-sim-por: turn the how to into a markdown file
1 parent d521e9e commit b2e291d

File tree

1 file changed

+41
-27
lines changed

1 file changed

+41
-27
lines changed

io-sim/how-to-use-IOSimPOR.txt renamed to io-sim/how-to-use-IOSimPOR.md

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,28 @@ The IOSimPOR API
5151

5252
The common way to use IOSim is to call
5353

54-
runSimTrace :: forall a. (forall s. IOSim s a) -> Trace a
54+
```hs
55+
runSimTrace :: forall a. (forall s. IOSim s a) -> Trace a
56+
```
5557

5658
which returns a trace, and then express the property to test as a
5759
predicate on the trace. Since IOSimPOR explores many traces, then the
5860
property to test is given as a continuation instead, which is called
5961
for each trace generated. The common way to use IOSimPOR is thus
6062

61-
exploreSimTrace :: forall a test. (Testable test, Show a) =>
62-
(ExplorationOptions->ExplorationOptions) ->
63-
(forall s. IOSim s a) ->
64-
(Maybe (Trace a) -> Trace a -> test) ->
65-
Property
63+
```hs
64+
exploreSimTrace :: forall a test. (Testable test, Show a) =>
65+
(ExplorationOptions->ExplorationOptions) ->
66+
(forall s. IOSim s a) ->
67+
(Maybe (Trace a) -> Trace a -> test) ->
68+
Property
69+
```
6670

6771
The continuation is the last parameter, with type
6872

69-
Maybe (Trace a) -> Trace a -> test
73+
```hs
74+
Maybe (Trace a) -> Trace a -> test
75+
```
7076

7177
Here the second parameter of the continuation is the trace that the
7278
property should check. The first parameter simply provides information
@@ -77,7 +83,7 @@ reversing one race.
7783
IOSimPOR Options
7884
----------------
7985

80-
exploreSimTrace can be controlled by a number of options, which are
86+
`exploreSimTrace` can be controlled by a number of options, which are
8187
obtained by passing the function passed as the first parameter to a
8288
default set of options. Passing the identity function id as the first
8389
parameter uses the defaults.
@@ -121,7 +127,7 @@ The options are:
121127
intended pure computations always finish well within that
122128
time. Note that garbage collection pauses are not included in the
123129
time limit (which would otherwise need to be considerably longer
124-
than 100ms to accomodate them), provided the -T flag is supplied to
130+
than 100ms to accommodate them), provided the -T flag is supplied to
125131
the run-time system.
126132

127133
- the schedule control to replay, default Nothing, set by
@@ -139,6 +145,7 @@ IOSimPOR Statistics
139145
When a tested property passes, IOSimPOR displays some statistics about
140146
the schedules that were actually run. An example of this output is:
141147

148+
```
142149
Branching factor (5865 in total):
143150
45.51% 1
144151
43.00% 0
@@ -177,6 +184,7 @@ Race reversals per schedule (5865 in total):
177184
3.10% 3
178185
1.71% 0
179186
0.10% 4
187+
```
180188

181189
The first table shows us the branching factor at each point where
182190
IOSimPOR explored alternative schedules: in this case, in 43% of cases
@@ -215,7 +223,9 @@ threads drastically reduces the set of races that IOSimPOR needs to consider.
215223

216224
To start a system thread, a non-racy thread may call
217225

218-
exploreRaces :: MonadTest m => m ()
226+
```hs
227+
exploreRaces :: MonadTest m => m ()
228+
```
219229

220230
All threads forked (using forkIO) after such a call will be system
221231
threads. If there is no call to exploreRaces in a test, then all the
@@ -224,13 +234,13 @@ races---so it is necessary to include a call to exploreRaces somewhere
224234
in a test.
225235

226236
IOSimPOR ThreadIds contain a list of small integers; the main thread
227-
contains the list [], its children are numbered [1], [2], [3] and so
228-
on, then threads forked by [2] are numbered [2,1], [2,2], [2,3] and so
229-
on. The id of a forked thread always extends its parent's id, and
230-
successively forked children of the same thread are numbered 1, 2, 3
231-
and so on. Thread Ids give us useful information for debugging; it is
232-
easy to see which thread forked which other, and relatively easy to
233-
map thread ids in debugging output to threads in the source code.
237+
contains the list `[]`, its children are numbered `[1]`, `[2]`, `[3]` and so
238+
on, then threads forked by `[2]` are numbered `[2,1]`, `[2,2]`, `[2,3]` and so
239+
on. The id of a forked thread always extends its parent's id, and successively
240+
forked children of the same thread are numbered 1, 2, 3 and so on. Thread Ids
241+
give us useful information for debugging; it is easy to see which thread forked
242+
which other, and relatively easy to map thread ids in debugging output to
243+
threads in the source code.
234244

235245
Except when reversing races, IOSimPOR schedules threads using
236246
priorities. Non-racy threads take priority over system threads, but
@@ -245,6 +255,7 @@ When IOSimPOR reverses races, this is done by using a 'schedule
245255
control'. The schedule control is displayed in the test output when a
246256
test fails. Here is an example:
247257

258+
```
248259
Schedule control:
249260
ControlAwait [ScheduleMod (ThreadId [4],0)
250261
ControlDefault
@@ -258,13 +269,14 @@ ThreadId [4] delayed at time Time 0s
258269
until after:
259270
ThreadId [2]
260271
ThreadId [3]
272+
```
261273
262274
The schedule control consists of one or more schedule modifications,
263275
each of which specifies that an event should be delayed until after a
264276
sequence of other events. The events consist of a thread id and a
265277
per-thread event number. The interpretation of the schedule
266278
modification above is that when the default scheduler would have
267-
performed the first event in thread [4] (that is, (ThreadId [4],0)),
279+
performed the first event in thread `[4]` (that is, (`ThreadId [4],0`)),
268280
then it should be delayed, and the list of events in the third field
269281
of the schedule modification should be performed first. In this case
270282
there is only one schedule modification, and so only one event is
@@ -274,35 +286,37 @@ the schedule control as an option to exploreSimTrace.
274286
275287
The final part of the output tells us how the schedule in the failing
276288
test differed from the schedule in the most similar passing test:
277-
namely, thread [4] was delayed (at simulated time 0) until after the
278-
events in threads [2] and [3]. Since the schedule control delays
279-
thread [4] until after steps in threads [1], [2] and [3], then we can
280-
conclude that the last passing test already delayed thread [4] until
281-
after the events in thread [1].
289+
namely, thread `[4]` was delayed (at simulated time 0) until after the
290+
events in threads `[2]` and `[3]`. Since the schedule control delays
291+
thread `[4]` until after steps in threads `[1]`, `[2]` and `[3]`, then we can
292+
conclude that the last passing test already delayed thread `[4]` until
293+
after the events in thread `[1]`.
282294
283295
Potential IOSimPOR Errors
284296
-------------------------
285297
286298
Most reported errors are a result of faults in the code under test,
287299
but if you see an error of the following form:
288300
301+
```
289302
Exception:
290303
Can't follow ControlFollow [(ThreadId [5],0)] []
291304
tid: ThreadId [5]
292305
tstep: 0
293306
runqueue: [ThreadId [3],ThreadId [2],ThreadId [1]]
307+
```
294308
295309
then the probable cause is a bug in IOSimPOR itself. The message
296310
indicates that IOSimPOR scheduler is trying to follow a schedule
297-
modification that specifies that thread [5] should run next, but this
298-
is impossible because thread [5] is not in the runqueue (the list of
311+
modification that specifies that thread `[5]` should run next, but this
312+
is impossible because thread `[5]` is not in the runqueue (the list of
299313
runnable threads). If you supplied a schedule control explicitly,
300314
using withReplay, then you may perhaps have supplied a schedule
301315
control that does not match the version of the code you are running:
302316
in this case the exception is your fault. But if this message appears
303317
while you are exploring races, then it indicates a problem in
304318
IOSimPOR's dependency analysis: IOSimPOR has constructed a schedule as
305-
a result of race reversal that tries to run thread [5] at this point,
306-
because the dependency analysis indicates that thread [5] ought to be
319+
a result of race reversal that tries to run thread `[5]` at this point,
320+
because the dependency analysis indicates that thread `[5]` ought to be
307321
runnable---but it is not. Best to consult Quviq at this point.
308322

0 commit comments

Comments
 (0)