@@ -79,7 +79,7 @@ import Control.Monad.Class.MonadThrow hiding (getMaskingState)
79
79
import Control.Monad.Class.MonadTime
80
80
import Control.Monad.Class.MonadTimer
81
81
82
- import Control.Monad.IOSim.Types hiding ( Deschedule ( .. ))
82
+ import Control.Monad.IOSim.Types
83
83
import Control.Monad.IOSim.InternalTypes
84
84
85
85
--
@@ -201,15 +201,19 @@ schedule thread@Thread{
201
201
ForkFrame -> do
202
202
-- this thread is done
203
203
trace <- deschedule Terminated thread simstate
204
- return $ SimTrace time tid tlbl EventThreadFinished trace
204
+ return $ SimTrace time tid tlbl EventThreadFinished
205
+ $ SimTrace time tid tlbl (EventDeschedule Terminated )
206
+ $ trace
205
207
206
208
MaskFrame k maskst' ctl' -> do
207
209
-- pop the control stack, restore thread-local state
208
210
let thread' = thread { threadControl = ThreadControl (k x) ctl'
209
211
, threadMasking = maskst' }
210
212
-- but if we're now unmasked, check for any pending async exceptions
211
213
trace <- deschedule Interruptable thread' simstate
212
- return (SimTrace time tid tlbl (EventMask maskst') trace)
214
+ return $ SimTrace time tid tlbl (EventMask maskst')
215
+ $ SimTrace time tid tlbl (EventDeschedule Interruptable )
216
+ $ trace
213
217
214
218
CatchFrame _handler k ctl' -> do
215
219
-- pop the control stack and continue
@@ -235,8 +239,10 @@ schedule thread@Thread{
235
239
| otherwise -> do
236
240
-- An unhandled exception in any other thread terminates the thread
237
241
trace <- deschedule Terminated thread simstate
238
- return (SimTrace time tid tlbl (EventThrow e) $
239
- SimTrace time tid tlbl (EventThreadUnhandled e) trace)
242
+ return $ SimTrace time tid tlbl (EventThrow e)
243
+ $ SimTrace time tid tlbl (EventThreadUnhandled e)
244
+ $ SimTrace time tid tlbl (EventDeschedule Terminated )
245
+ $ trace
240
246
241
247
Catch action' handler k -> do
242
248
-- push the failure and success continuations onto the control stack
@@ -412,19 +418,18 @@ schedule thread@Thread{
412
418
-- that algorithms are not sensitive to the exact policy, so long
413
419
-- as it is a fair policy (all runnable threads eventually run).
414
420
trace <- deschedule Yield thread' simstate' { nextVid = nextVid' }
415
- return $
416
- SimTrace time tid tlbl (EventTxCommitted vids [nextVid.. pred nextVid']
417
- Nothing ) $
418
- traceMany
419
- [ (time, tid', tlbl', EventTxWakeup vids')
420
- | tid' <- unblocked
421
- , let tlbl' = lookupThreadLabel tid' threads
422
- , let Just vids' = Set. toList <$> Map. lookup tid' wokeby ] $
423
- traceMany
424
- [ (time, tid, tlbl, EventLog tr)
425
- | tr <- tvarTraces
426
- ]
427
- trace
421
+ return $ SimTrace time tid tlbl (EventTxCommitted
422
+ vids [nextVid.. pred nextVid'] Nothing )
423
+ $ traceMany
424
+ [ (time, tid', tlbl', EventTxWakeup vids')
425
+ | tid' <- unblocked
426
+ , let tlbl' = lookupThreadLabel tid' threads
427
+ , let Just vids' = Set. toList <$> Map. lookup tid' wokeby ]
428
+ $ traceMany
429
+ [ (time, tid, tlbl, EventLog tr)
430
+ | tr <- tvarTraces ]
431
+ $ SimTrace time tid tlbl (EventDeschedule Yield )
432
+ $ trace
428
433
429
434
StmTxAborted _read e -> do
430
435
-- schedule this thread to immediately raise the exception
@@ -436,7 +441,9 @@ schedule thread@Thread{
436
441
mapM_ (\ (SomeTVar tvar) -> blockThreadOnTVar tid tvar) read
437
442
vids <- traverse (\ (SomeTVar tvar) -> labelledTVarId tvar) read
438
443
trace <- deschedule Blocked thread simstate
439
- return $ SimTrace time tid tlbl (EventTxBlocked vids Nothing ) trace
444
+ return $ SimTrace time tid tlbl (EventTxBlocked vids Nothing )
445
+ $ SimTrace time tid tlbl (EventDeschedule Blocked )
446
+ $ trace
440
447
441
448
GetThreadId k -> do
442
449
let thread' = thread { threadControl = ThreadControl (k tid) ctl }
@@ -464,9 +471,11 @@ schedule thread@Thread{
464
471
trace <-
465
472
case maskst' of
466
473
-- If we're now unmasked then check for any pending async exceptions
467
- Unmasked -> deschedule Interruptable thread' simstate
474
+ Unmasked -> SimTrace time tid tlbl (EventDeschedule Interruptable )
475
+ <$> deschedule Interruptable thread' simstate
468
476
_ -> schedule thread' simstate
469
- return (SimTrace time tid tlbl (EventMask maskst') trace)
477
+ return $ SimTrace time tid tlbl (EventMask maskst')
478
+ $ trace
470
479
471
480
ThrowTo e tid' _ | tid' == tid -> do
472
481
-- Throw to ourself is equivalent to a synchronous throw,
@@ -489,6 +498,7 @@ schedule thread@Thread{
489
498
trace <- deschedule Blocked thread' simstate { threads = threads' }
490
499
return $ SimTrace time tid tlbl (EventThrowTo e tid')
491
500
$ SimTrace time tid tlbl EventThrowToBlocked
501
+ $ SimTrace time tid tlbl (EventDeschedule Blocked )
492
502
$ trace
493
503
else do
494
504
-- The target thread has async exceptions unmasked, or is masked but
@@ -525,8 +535,6 @@ threadInterruptible thread =
525
535
| otherwise -> False
526
536
MaskedUninterruptible -> False
527
537
528
- data Deschedule = Yield | Interruptable | Blocked | Terminated
529
-
530
538
deschedule :: Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a )
531
539
deschedule Yield thread simstate@ SimState {runqueue, threads} =
532
540
@@ -598,6 +606,9 @@ deschedule Terminated thread simstate@SimState{ curTime = time, threads } = do
598
606
, let tlbl' = lookupThreadLabel tid' threads ]
599
607
trace
600
608
609
+ deschedule Sleep _thread _simstate =
610
+ error " IOSim: impossible happend"
611
+
601
612
-- When there is no current running thread but the runqueue is non-empty then
602
613
-- schedule the next one to run.
603
614
reschedule :: SimState s a -> ST s (SimTrace a )
0 commit comments