{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTSyntax #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wno-orphans #-}
{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
module Control.Monad.IOSim.Internal
( IOSim (..)
, SimM
, runIOSim
, runSimTraceST
, traceM
, traceSTM
, STM
, STMSim
, SimSTM
, setCurrentTime
, unshareClock
, TimeoutException (..)
, EventlogEvent (..)
, EventlogMarker (..)
, ThreadId
, ThreadLabel
, Labelled (..)
, SimTrace
, Trace.Trace (SimTrace, Trace, TraceMainReturn, TraceMainException, TraceDeadlock)
, SimEvent (..)
, SimResult (..)
, SimEventType (..)
, TraceEvent
, ppTrace
, ppTrace_
, ppSimEvent
, liftST
, execReadTVar
) where
import Prelude hiding (read)
import Data.Dynamic
import Data.Foldable (toList, traverse_)
import qualified Data.List as List
import qualified Data.List.Trace as Trace
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.Maybe (mapMaybe)
import Data.OrdPSQ (OrdPSQ)
import qualified Data.OrdPSQ as PSQ
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Time (UTCTime (..), fromGregorian)
import Deque.Strict (Deque)
import qualified Deque.Strict as Deque
import GHC.Exts (fromList)
import Control.Exception (NonTermination (..), assert, throw)
import Control.Monad (join)
import Control.Monad (when)
import Control.Monad.ST.Lazy
import Control.Monad.ST.Lazy.Unsafe (unsafeIOToST, unsafeInterleaveST)
import Data.STRef.Lazy
import Control.Monad.Class.MonadSTM hiding (STM, TVar)
import Control.Monad.Class.MonadThrow hiding (getMaskingState)
import Control.Monad.Class.MonadTime
import Control.Monad.Class.MonadTimer
import Control.Monad.IOSim.InternalTypes
import Control.Monad.IOSim.Types hiding (SimEvent (SimPOREvent),
Trace (SimPORTrace))
import Control.Monad.IOSim.Types (SimEvent)
data Thread s a = Thread {
Thread s a -> ThreadId
threadId :: !ThreadId,
Thread s a -> ThreadControl s a
threadControl :: !(ThreadControl s a),
Thread s a -> Bool
threadBlocked :: !Bool,
Thread s a -> MaskingState
threadMasking :: !MaskingState,
Thread s a -> [(SomeException, Labelled ThreadId)]
threadThrowTo :: ![(SomeException, Labelled ThreadId)],
Thread s a -> ClockId
threadClockId :: !ClockId,
Thread s a -> Maybe ThreadLabel
threadLabel :: Maybe ThreadLabel,
Thread s a -> Int
threadNextTId :: !Int
}
labelledTVarId :: TVar s a -> ST s (Labelled TVarId)
labelledTVarId :: TVar s a -> ST s (Labelled TVarId)
labelledTVarId TVar { TVarId
tvarId :: forall s a. TVar s a -> TVarId
tvarId :: TVarId
tvarId, STRef s (Maybe ThreadLabel)
tvarLabel :: forall s a. TVar s a -> STRef s (Maybe ThreadLabel)
tvarLabel :: STRef s (Maybe ThreadLabel)
tvarLabel } = (TVarId -> Maybe ThreadLabel -> Labelled TVarId
forall a. a -> Maybe ThreadLabel -> Labelled a
Labelled TVarId
tvarId) (Maybe ThreadLabel -> Labelled TVarId)
-> ST s (Maybe ThreadLabel) -> ST s (Labelled TVarId)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> STRef s (Maybe ThreadLabel) -> ST s (Maybe ThreadLabel)
forall s a. STRef s a -> ST s a
readSTRef STRef s (Maybe ThreadLabel)
tvarLabel
labelledThreads :: Map ThreadId (Thread s a) -> [Labelled ThreadId]
labelledThreads :: Map ThreadId (Thread s a) -> [Labelled ThreadId]
labelledThreads Map ThreadId (Thread s a)
threadMap =
(Thread s a -> [Labelled ThreadId] -> [Labelled ThreadId])
-> [Labelled ThreadId]
-> Map ThreadId (Thread s a)
-> [Labelled ThreadId]
forall a b k. (a -> b -> b) -> b -> Map k a -> b
Map.foldr'
(\Thread { ThreadId
threadId :: ThreadId
threadId :: forall s a. Thread s a -> ThreadId
threadId, Maybe ThreadLabel
threadLabel :: Maybe ThreadLabel
threadLabel :: forall s a. Thread s a -> Maybe ThreadLabel
threadLabel } ![Labelled ThreadId]
acc -> ThreadId -> Maybe ThreadLabel -> Labelled ThreadId
forall a. a -> Maybe ThreadLabel -> Labelled a
Labelled ThreadId
threadId Maybe ThreadLabel
threadLabel Labelled ThreadId -> [Labelled ThreadId] -> [Labelled ThreadId]
forall a. a -> [a] -> [a]
: [Labelled ThreadId]
acc)
[] Map ThreadId (Thread s a)
threadMap
data TimerVars s = TimerVars !(TVar s TimeoutState) !(TVar s Bool)
data SimState s a = SimState {
SimState s a -> Deque ThreadId
runqueue :: !(Deque ThreadId),
SimState s a -> Map ThreadId (Thread s a)
threads :: !(Map ThreadId (Thread s a)),
SimState s a -> Time
curTime :: !Time,
SimState s a -> OrdPSQ TimeoutId Time (TimerVars s)
timers :: !(OrdPSQ TimeoutId Time (TimerVars s)),
SimState s a -> Map ClockId UTCTime
clocks :: !(Map ClockId UTCTime),
SimState s a -> TVarId
nextVid :: !TVarId,
SimState s a -> TimeoutId
nextTmid :: !TimeoutId
}
initialState :: SimState s a
initialState :: SimState s a
initialState =
SimState :: forall s a.
Deque ThreadId
-> Map ThreadId (Thread s a)
-> Time
-> OrdPSQ TimeoutId Time (TimerVars s)
-> Map ClockId UTCTime
-> TVarId
-> TimeoutId
-> SimState s a
SimState {
runqueue :: Deque ThreadId
runqueue = Deque ThreadId
forall a. Monoid a => a
mempty,
threads :: Map ThreadId (Thread s a)
threads = Map ThreadId (Thread s a)
forall k a. Map k a
Map.empty,
curTime :: Time
curTime = DiffTime -> Time
Time DiffTime
0,
timers :: OrdPSQ TimeoutId Time (TimerVars s)
timers = OrdPSQ TimeoutId Time (TimerVars s)
forall k p v. OrdPSQ k p v
PSQ.empty,
clocks :: Map ClockId UTCTime
clocks = ClockId -> UTCTime -> Map ClockId UTCTime
forall k a. k -> a -> Map k a
Map.singleton ([Int] -> ClockId
ClockId []) UTCTime
epoch1970,
nextVid :: TVarId
nextVid = Int -> TVarId
TVarId Int
0,
nextTmid :: TimeoutId
nextTmid = Int -> TimeoutId
TimeoutId Int
0
}
where
epoch1970 :: UTCTime
epoch1970 = Day -> DiffTime -> UTCTime
UTCTime (Integer -> Int -> Int -> Day
fromGregorian Integer
1970 Int
1 Int
1) DiffTime
0
invariant :: Maybe (Thread s a) -> SimState s a -> Bool
invariant :: Maybe (Thread s a) -> SimState s a -> Bool
invariant (Just Thread s a
running) simstate :: SimState s a
simstate@SimState{Deque ThreadId
runqueue :: Deque ThreadId
runqueue :: forall s a. SimState s a -> Deque ThreadId
runqueue,Map ThreadId (Thread s a)
threads :: Map ThreadId (Thread s a)
threads :: forall s a. SimState s a -> Map ThreadId (Thread s a)
threads,Map ClockId UTCTime
clocks :: Map ClockId UTCTime
clocks :: forall s a. SimState s a -> Map ClockId UTCTime
clocks} =
Bool -> Bool
not (Thread s a -> Bool
forall s a. Thread s a -> Bool
threadBlocked Thread s a
running)
Bool -> Bool -> Bool
&& Thread s a -> ThreadId
forall s a. Thread s a -> ThreadId
threadId Thread s a
running ThreadId -> Map ThreadId (Thread s a) -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.notMember` Map ThreadId (Thread s a)
threads
Bool -> Bool -> Bool
&& Thread s a -> ThreadId
forall s a. Thread s a -> ThreadId
threadId Thread s a
running ThreadId -> [ThreadId] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`List.notElem` Deque ThreadId -> [ThreadId]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Deque ThreadId
runqueue
Bool -> Bool -> Bool
&& Thread s a -> ClockId
forall s a. Thread s a -> ClockId
threadClockId Thread s a
running ClockId -> Map ClockId UTCTime -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map ClockId UTCTime
clocks
Bool -> Bool -> Bool
&& Maybe (Thread s a) -> SimState s a -> Bool
forall s a. Maybe (Thread s a) -> SimState s a -> Bool
invariant Maybe (Thread s a)
forall a. Maybe a
Nothing SimState s a
simstate
invariant Maybe (Thread s a)
Nothing SimState{Deque ThreadId
runqueue :: Deque ThreadId
runqueue :: forall s a. SimState s a -> Deque ThreadId
runqueue,Map ThreadId (Thread s a)
threads :: Map ThreadId (Thread s a)
threads :: forall s a. SimState s a -> Map ThreadId (Thread s a)
threads,Map ClockId UTCTime
clocks :: Map ClockId UTCTime
clocks :: forall s a. SimState s a -> Map ClockId UTCTime
clocks} =
(ThreadId -> Bool) -> Deque ThreadId -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (ThreadId -> Map ThreadId (Thread s a) -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map ThreadId (Thread s a)
threads) Deque ThreadId
runqueue
Bool -> Bool -> Bool
&& [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ Thread s a -> Bool
forall s a. Thread s a -> Bool
threadBlocked Thread s a
t Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== (Thread s a -> ThreadId
forall s a. Thread s a -> ThreadId
threadId Thread s a
t ThreadId -> Deque ThreadId -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` Deque ThreadId
runqueue)
| Thread s a
t <- Map ThreadId (Thread s a) -> [Thread s a]
forall k a. Map k a -> [a]
Map.elems Map ThreadId (Thread s a)
threads ]
Bool -> Bool -> Bool
&& Deque ThreadId -> [ThreadId]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Deque ThreadId
runqueue [ThreadId] -> [ThreadId] -> Bool
forall a. Eq a => a -> a -> Bool
== [ThreadId] -> [ThreadId]
forall a. Eq a => [a] -> [a]
List.nub (Deque ThreadId -> [ThreadId]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Deque ThreadId
runqueue)
Bool -> Bool -> Bool
&& [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ Thread s a -> ClockId
forall s a. Thread s a -> ClockId
threadClockId Thread s a
t ClockId -> Map ClockId UTCTime -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map ClockId UTCTime
clocks
| Thread s a
t <- Map ThreadId (Thread s a) -> [Thread s a]
forall k a. Map k a -> [a]
Map.elems Map ThreadId (Thread s a)
threads ]
timeSinceEpoch :: Time -> NominalDiffTime
timeSinceEpoch :: Time -> NominalDiffTime
timeSinceEpoch (Time DiffTime
t) = Rational -> NominalDiffTime
forall a. Fractional a => Rational -> a
fromRational (DiffTime -> Rational
forall a. Real a => a -> Rational
toRational DiffTime
t)
schedule :: Thread s a -> SimState s a -> ST s (SimTrace a)
schedule :: Thread s a -> SimState s a -> ST s (SimTrace a)
schedule !thread :: Thread s a
thread@Thread{
threadId :: forall s a. Thread s a -> ThreadId
threadId = ThreadId
tid,
threadControl :: forall s a. Thread s a -> ThreadControl s a
threadControl = ThreadControl SimA s b
action ControlStack s b a
ctl,
threadMasking :: forall s a. Thread s a -> MaskingState
threadMasking = MaskingState
maskst,
threadLabel :: forall s a. Thread s a -> Maybe ThreadLabel
threadLabel = Maybe ThreadLabel
tlbl
}
!simstate :: SimState s a
simstate@SimState {
Deque ThreadId
runqueue :: Deque ThreadId
runqueue :: forall s a. SimState s a -> Deque ThreadId
runqueue,
Map ThreadId (Thread s a)
threads :: Map ThreadId (Thread s a)
threads :: forall s a. SimState s a -> Map ThreadId (Thread s a)
threads,
OrdPSQ TimeoutId Time (TimerVars s)
timers :: OrdPSQ TimeoutId Time (TimerVars s)
timers :: forall s a. SimState s a -> OrdPSQ TimeoutId Time (TimerVars s)
timers,
Map ClockId UTCTime
clocks :: Map ClockId UTCTime
clocks :: forall s a. SimState s a -> Map ClockId UTCTime
clocks,
TVarId
nextVid :: TVarId
nextVid :: forall s a. SimState s a -> TVarId
nextVid, TimeoutId
nextTmid :: TimeoutId
nextTmid :: forall s a. SimState s a -> TimeoutId
nextTmid,
curTime :: forall s a. SimState s a -> Time
curTime = Time
time
} =
Bool -> ST s (SimTrace a) -> ST s (SimTrace a)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Maybe (Thread s a) -> SimState s a -> Bool
forall s a. Maybe (Thread s a) -> SimState s a -> Bool
invariant (Thread s a -> Maybe (Thread s a)
forall a. a -> Maybe a
Just Thread s a
thread) SimState s a
simstate) (ST s (SimTrace a) -> ST s (SimTrace a))
-> ST s (SimTrace a) -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$
case SimA s b
action of
Return b
x -> {-# SCC "schedule.Return" #-}
case ControlStack s b a
ctl of
ControlStack s b a
MainFrame ->
SimTrace b -> ST s (SimTrace b)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace b -> ST s (SimTrace b))
-> SimTrace b -> ST s (SimTrace b)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace b
-> SimTrace b
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl SimEventType
EventThreadFinished
(SimTrace b -> SimTrace b) -> SimTrace b -> SimTrace b
forall a b. (a -> b) -> a -> b
$ Time -> b -> [Labelled ThreadId] -> SimTrace b
forall a. Time -> a -> [Labelled ThreadId] -> SimTrace a
TraceMainReturn Time
time b
x (Map ThreadId (Thread s a) -> [Labelled ThreadId]
forall s a. Map ThreadId (Thread s a) -> [Labelled ThreadId]
labelledThreads Map ThreadId (Thread s a)
threads)
ControlStack s b a
ForkFrame -> do
!SimTrace a
trace <- Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a.
Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
deschedule Deschedule
Terminated Thread s a
thread SimState s a
simstate
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl SimEventType
EventThreadFinished
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (Deschedule -> SimEventType
EventDeschedule Deschedule
Terminated)
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ SimTrace a
trace
MaskFrame b -> SimA s c
k MaskingState
maskst' ControlStack s c a
ctl' -> do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s c -> ControlStack s c a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (b -> SimA s c
k b
x) ControlStack s c a
ctl'
, threadMasking :: MaskingState
threadMasking = MaskingState
maskst' }
!SimTrace a
trace <- Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a.
Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
deschedule Deschedule
Interruptable Thread s a
thread' SimState s a
simstate
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (MaskingState -> SimEventType
EventMask MaskingState
maskst')
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (Deschedule -> SimEventType
EventDeschedule Deschedule
Interruptable)
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ SimTrace a
trace
CatchFrame e -> SimA s b
_handler b -> SimA s c
k ControlStack s c a
ctl' -> do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s c -> ControlStack s c a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (b -> SimA s c
k b
x) ControlStack s c a
ctl' }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
Throw SomeException
e -> {-# SCC "schedule.Throw" #-}
case SomeException -> Thread s a -> Either Bool (Thread s a)
forall s a. SomeException -> Thread s a -> Either Bool (Thread s a)
unwindControlStack SomeException
e Thread s a
thread of
Right thread' :: Thread s a
thread'@Thread { threadMasking :: forall s a. Thread s a -> MaskingState
threadMasking = MaskingState
maskst' } -> do
SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (SomeException -> SimEventType
EventThrow SomeException
e) (SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (MaskingState -> SimEventType
EventMask MaskingState
maskst') SimTrace a
trace)
Left Bool
isMain
| Bool
isMain ->
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (SomeException -> SimEventType
EventThrow SomeException
e) (SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (SomeException -> SimEventType
EventThreadUnhandled SomeException
e) (SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$
Time -> SomeException -> [Labelled ThreadId] -> SimTrace a
forall a.
Time -> SomeException -> [Labelled ThreadId] -> SimTrace a
TraceMainException Time
time SomeException
e (Map ThreadId (Thread s a) -> [Labelled ThreadId]
forall s a. Map ThreadId (Thread s a) -> [Labelled ThreadId]
labelledThreads Map ThreadId (Thread s a)
threads))
| Bool
otherwise -> do
!SimTrace a
trace <- Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a.
Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
deschedule Deschedule
Terminated Thread s a
thread SimState s a
simstate
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (SomeException -> SimEventType
EventThrow SomeException
e)
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (SomeException -> SimEventType
EventThreadUnhandled SomeException
e)
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (Deschedule -> SimEventType
EventDeschedule Deschedule
Terminated)
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ SimTrace a
trace
Catch SimA s a
action' e -> SimA s a
handler a -> SimA s b
k ->
{-# SCC "schedule.Catch" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s a -> ControlStack s a a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s a
action'
((e -> SimA s a)
-> (a -> SimA s b) -> ControlStack s b a -> ControlStack s a a
forall e s b c a.
Exception e =>
(e -> SimA s b)
-> (b -> SimA s c) -> ControlStack s c a -> ControlStack s b a
CatchFrame e -> SimA s a
handler a -> SimA s b
k ControlStack s b a
ctl) }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
Evaluate a
expr a -> SimA s b
k ->
{-# SCC "schedule.Evaulate" #-} do
Either SomeException a
mbWHNF <- IO (Either SomeException a) -> ST s (Either SomeException a)
forall a s. IO a -> ST s a
unsafeIOToST (IO (Either SomeException a) -> ST s (Either SomeException a))
-> IO (Either SomeException a) -> ST s (Either SomeException a)
forall a b. (a -> b) -> a -> b
$ IO a -> IO (Either SomeException a)
forall (m :: * -> *) e a.
(MonadCatch m, Exception e) =>
m a -> m (Either e a)
try (IO a -> IO (Either SomeException a))
-> IO a -> IO (Either SomeException a)
forall a b. (a -> b) -> a -> b
$ a -> IO a
forall (m :: * -> *) a. MonadEvaluate m => a -> m a
evaluate a
expr
case Either SomeException a
mbWHNF of
Left SomeException
e -> do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (SomeException -> SimA s b
forall s a. SomeException -> SimA s a
Throw SomeException
e) ControlStack s b a
ctl }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
Right a
whnf -> do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (a -> SimA s b
k a
whnf) ControlStack s b a
ctl }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
Say ThreadLabel
msg SimA s b
k ->
{-# SCC "schedule.Say" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl }
SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (ThreadLabel -> SimEventType
EventSay ThreadLabel
msg) SimTrace a
trace)
Output Dynamic
x SimA s b
k ->
{-# SCC "schedule.Output" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl }
SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (Dynamic -> SimEventType
EventLog Dynamic
x) SimTrace a
trace)
LiftST ST s a
st a -> SimA s b
k ->
{-# SCC "schedule.LiftST" #-} do
a
x <- ST s a -> ST s a
forall s a. ST s a -> ST s a
strictToLazyST ST s a
st
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (a -> SimA s b
k a
x) ControlStack s b a
ctl }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
GetMonoTime Time -> SimA s b
k ->
{-# SCC "schedule.GetMonoTime" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (Time -> SimA s b
k Time
time) ControlStack s b a
ctl }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
GetWallTime UTCTime -> SimA s b
k ->
{-# SCC "schedule.GetWallTime" #-} do
let !clockid :: ClockId
clockid = Thread s a -> ClockId
forall s a. Thread s a -> ClockId
threadClockId Thread s a
thread
!clockoff :: UTCTime
clockoff = Map ClockId UTCTime
clocks Map ClockId UTCTime -> ClockId -> UTCTime
forall k a. Ord k => Map k a -> k -> a
Map.! ClockId
clockid
!walltime :: UTCTime
walltime = Time -> NominalDiffTime
timeSinceEpoch Time
time NominalDiffTime -> UTCTime -> UTCTime
`addUTCTime` UTCTime
clockoff
!thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (UTCTime -> SimA s b
k UTCTime
walltime) ControlStack s b a
ctl }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
SetWallTime UTCTime
walltime' SimA s b
k ->
{-# SCC "schedule.SetWallTime" #-} do
let !clockid :: ClockId
clockid = Thread s a -> ClockId
forall s a. Thread s a -> ClockId
threadClockId Thread s a
thread
!clockoff :: UTCTime
clockoff = Map ClockId UTCTime
clocks Map ClockId UTCTime -> ClockId -> UTCTime
forall k a. Ord k => Map k a -> k -> a
Map.! ClockId
clockid
!walltime :: UTCTime
walltime = Time -> NominalDiffTime
timeSinceEpoch Time
time NominalDiffTime -> UTCTime -> UTCTime
`addUTCTime` UTCTime
clockoff
!clockoff' :: UTCTime
clockoff' = NominalDiffTime -> UTCTime -> UTCTime
addUTCTime (UTCTime -> UTCTime -> NominalDiffTime
diffUTCTime UTCTime
walltime' UTCTime
walltime) UTCTime
clockoff
!thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl }
!simstate' :: SimState s a
simstate' = SimState s a
simstate { clocks :: Map ClockId UTCTime
clocks = ClockId -> UTCTime -> Map ClockId UTCTime -> Map ClockId UTCTime
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert ClockId
clockid UTCTime
clockoff' Map ClockId UTCTime
clocks }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate'
UnshareClock SimA s b
k ->
{-# SCC "schedule.UnshareClock" #-} do
let !clockid :: ClockId
clockid = Thread s a -> ClockId
forall s a. Thread s a -> ClockId
threadClockId Thread s a
thread
!clockoff :: UTCTime
clockoff = Map ClockId UTCTime
clocks Map ClockId UTCTime -> ClockId -> UTCTime
forall k a. Ord k => Map k a -> k -> a
Map.! ClockId
clockid
!clockid' :: ClockId
clockid' = let ThreadId [Int]
i = ThreadId
tid in [Int] -> ClockId
ClockId [Int]
i
!thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl
, threadClockId :: ClockId
threadClockId = ClockId
clockid' }
!simstate' :: SimState s a
simstate' = SimState s a
simstate { clocks :: Map ClockId UTCTime
clocks = ClockId -> UTCTime -> Map ClockId UTCTime -> Map ClockId UTCTime
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert ClockId
clockid' UTCTime
clockoff Map ClockId UTCTime
clocks }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate'
NewTimeout DiffTime
d Timeout (IOSim s) -> SimA s b
k | DiffTime
d DiffTime -> DiffTime -> Bool
forall a. Ord a => a -> a -> Bool
< DiffTime
0 ->
{-# SCC "schedule.NewTimeout.1" #-} do
let !t :: Timeout (IOSim s)
t = TimeoutId -> Timeout (IOSim s)
forall s. TimeoutId -> Timeout (IOSim s)
NegativeTimeout TimeoutId
nextTmid
!expiry :: Time
expiry = DiffTime
d DiffTime -> Time -> Time
`addTime` Time
time
!thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (Timeout (IOSim s) -> SimA s b
k Timeout (IOSim s)
t) ControlStack s b a
ctl }
SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate { nextTmid :: TimeoutId
nextTmid = TimeoutId -> TimeoutId
forall a. Enum a => a -> a
succ TimeoutId
nextTmid }
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (TimeoutId -> TVarId -> Time -> SimEventType
EventTimerCreated TimeoutId
nextTmid TVarId
nextVid Time
expiry) (SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (TimeoutId -> SimEventType
EventTimerCancelled TimeoutId
nextTmid) (SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$
SimTrace a
trace)
NewTimeout DiffTime
d Timeout (IOSim s) -> SimA s b
k ->
{-# SCC "schedule.NewTimeout.2" #-} do
!TVar s TimeoutState
tvar <- TVarId
-> Maybe ThreadLabel -> TimeoutState -> ST s (TVar s TimeoutState)
forall a s. TVarId -> Maybe ThreadLabel -> a -> ST s (TVar s a)
execNewTVar TVarId
nextVid
(ThreadLabel -> Maybe ThreadLabel
forall a. a -> Maybe a
Just (ThreadLabel -> Maybe ThreadLabel)
-> ThreadLabel -> Maybe ThreadLabel
forall a b. (a -> b) -> a -> b
$ ThreadLabel
"<<timeout-state " ThreadLabel -> ThreadLabel -> ThreadLabel
forall a. [a] -> [a] -> [a]
++ Int -> ThreadLabel
forall a. Show a => a -> ThreadLabel
show (TimeoutId -> Int
unTimeoutId TimeoutId
nextTmid) ThreadLabel -> ThreadLabel -> ThreadLabel
forall a. [a] -> [a] -> [a]
++ ThreadLabel
">>")
TimeoutState
TimeoutPending
!TVar s Bool
tvar' <- TVarId -> Maybe ThreadLabel -> Bool -> ST s (TVar s Bool)
forall a s. TVarId -> Maybe ThreadLabel -> a -> ST s (TVar s a)
execNewTVar (TVarId -> TVarId
forall a. Enum a => a -> a
succ TVarId
nextVid)
(ThreadLabel -> Maybe ThreadLabel
forall a. a -> Maybe a
Just (ThreadLabel -> Maybe ThreadLabel)
-> ThreadLabel -> Maybe ThreadLabel
forall a b. (a -> b) -> a -> b
$ ThreadLabel
"<<timeout " ThreadLabel -> ThreadLabel -> ThreadLabel
forall a. [a] -> [a] -> [a]
++ Int -> ThreadLabel
forall a. Show a => a -> ThreadLabel
show (TimeoutId -> Int
unTimeoutId TimeoutId
nextTmid) ThreadLabel -> ThreadLabel -> ThreadLabel
forall a. [a] -> [a] -> [a]
++ ThreadLabel
">>")
Bool
False
let !expiry :: Time
expiry = DiffTime
d DiffTime -> Time -> Time
`addTime` Time
time
!t :: Timeout (IOSim s)
t = TVar s TimeoutState
-> TVar s Bool -> TimeoutId -> Timeout (IOSim s)
forall s.
TVar s TimeoutState
-> TVar s Bool -> TimeoutId -> Timeout (IOSim s)
Timeout TVar s TimeoutState
tvar TVar s Bool
tvar' TimeoutId
nextTmid
!timers' :: OrdPSQ TimeoutId Time (TimerVars s)
timers' = TimeoutId
-> Time
-> TimerVars s
-> OrdPSQ TimeoutId Time (TimerVars s)
-> OrdPSQ TimeoutId Time (TimerVars s)
forall k p v.
(Ord k, Ord p) =>
k -> p -> v -> OrdPSQ k p v -> OrdPSQ k p v
PSQ.insert TimeoutId
nextTmid Time
expiry (TVar s TimeoutState -> TVar s Bool -> TimerVars s
forall s. TVar s TimeoutState -> TVar s Bool -> TimerVars s
TimerVars TVar s TimeoutState
tvar TVar s Bool
tvar') OrdPSQ TimeoutId Time (TimerVars s)
timers
!thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (Timeout (IOSim s) -> SimA s b
k Timeout (IOSim s)
t) ControlStack s b a
ctl }
!SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate { timers :: OrdPSQ TimeoutId Time (TimerVars s)
timers = OrdPSQ TimeoutId Time (TimerVars s)
timers'
, nextVid :: TVarId
nextVid = TVarId -> TVarId
forall a. Enum a => a -> a
succ (TVarId -> TVarId
forall a. Enum a => a -> a
succ TVarId
nextVid)
, nextTmid :: TimeoutId
nextTmid = TimeoutId -> TimeoutId
forall a. Enum a => a -> a
succ TimeoutId
nextTmid }
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (TimeoutId -> TVarId -> Time -> SimEventType
EventTimerCreated TimeoutId
nextTmid TVarId
nextVid Time
expiry) SimTrace a
trace)
UpdateTimeout (Timeout _tvar _tvar' tmid) DiffTime
d SimA s b
k | DiffTime
d DiffTime -> DiffTime -> Bool
forall a. Ord a => a -> a -> Bool
< DiffTime
0 ->
{-# SCC "schedule.UpdateTimeout" #-} do
let !timers' :: OrdPSQ TimeoutId Time (TimerVars s)
timers' = TimeoutId
-> OrdPSQ TimeoutId Time (TimerVars s)
-> OrdPSQ TimeoutId Time (TimerVars s)
forall k p v. (Ord k, Ord p) => k -> OrdPSQ k p v -> OrdPSQ k p v
PSQ.delete TimeoutId
tmid OrdPSQ TimeoutId Time (TimerVars s)
timers
!thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl }
SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate { timers :: OrdPSQ TimeoutId Time (TimerVars s)
timers = OrdPSQ TimeoutId Time (TimerVars s)
timers' }
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (TimeoutId -> SimEventType
EventTimerCancelled TimeoutId
tmid) SimTrace a
trace)
UpdateTimeout (Timeout _tvar _tvar' tmid) DiffTime
d SimA s b
k ->
{-# SCC "schedule.UpdateTimeout" #-} do
let updateTimeout_ :: Maybe (Time, TimerVars s) -> ((), Maybe (Time, TimerVars s))
updateTimeout_ Maybe (Time, TimerVars s)
Nothing = ((), Maybe (Time, TimerVars s)
forall a. Maybe a
Nothing)
updateTimeout_ (Just (Time
_p, TimerVars s
v)) = ((), (Time, TimerVars s) -> Maybe (Time, TimerVars s)
forall a. a -> Maybe a
Just (Time
expiry, TimerVars s
v))
!expiry :: Time
expiry = DiffTime
d DiffTime -> Time -> Time
`addTime` Time
time
!timers' :: OrdPSQ TimeoutId Time (TimerVars s)
timers' = ((), OrdPSQ TimeoutId Time (TimerVars s))
-> OrdPSQ TimeoutId Time (TimerVars s)
forall a b. (a, b) -> b
snd ((Maybe (Time, TimerVars s) -> ((), Maybe (Time, TimerVars s)))
-> TimeoutId
-> OrdPSQ TimeoutId Time (TimerVars s)
-> ((), OrdPSQ TimeoutId Time (TimerVars s))
forall k p v b.
(Ord k, Ord p) =>
(Maybe (p, v) -> (b, Maybe (p, v)))
-> k -> OrdPSQ k p v -> (b, OrdPSQ k p v)
PSQ.alter Maybe (Time, TimerVars s) -> ((), Maybe (Time, TimerVars s))
updateTimeout_ TimeoutId
tmid OrdPSQ TimeoutId Time (TimerVars s)
timers)
!thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl }
SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate { timers :: OrdPSQ TimeoutId Time (TimerVars s)
timers = OrdPSQ TimeoutId Time (TimerVars s)
timers' }
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (TimeoutId -> Time -> SimEventType
EventTimerUpdated TimeoutId
tmid Time
expiry) SimTrace a
trace)
UpdateTimeout (NegativeTimeout _tmid) DiffTime
_d SimA s b
k ->
{-# SCC "schedule.UpdateTimeout" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
CancelTimeout (Timeout tvar _tvar' tmid) SimA s b
k ->
{-# SCC "schedule.CancelTimeout" #-} do
let !timers' :: OrdPSQ TimeoutId Time (TimerVars s)
timers' = TimeoutId
-> OrdPSQ TimeoutId Time (TimerVars s)
-> OrdPSQ TimeoutId Time (TimerVars s)
forall k p v. (Ord k, Ord p) => k -> OrdPSQ k p v -> OrdPSQ k p v
PSQ.delete TimeoutId
tmid OrdPSQ TimeoutId Time (TimerVars s)
timers
!thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl }
![SomeTVar s]
written <- StmA s () -> ST s [SomeTVar s]
forall s. StmA s () -> ST s [SomeTVar s]
execAtomically' (STM s () -> StmA s ()
forall s a. STM s a -> StmA s a
runSTM (STM s () -> StmA s ()) -> STM s () -> StmA s ()
forall a b. (a -> b) -> a -> b
$ TVar (IOSim s) TimeoutState -> TimeoutState -> STM (IOSim s) ()
forall (m :: * -> *) a. MonadSTM m => TVar m a -> a -> STM m ()
writeTVar TVar (IOSim s) TimeoutState
TVar s TimeoutState
tvar TimeoutState
TimeoutCancelled)
(![ThreadId]
wakeup, Map ThreadId (Set (Labelled TVarId))
wokeby) <- [SomeTVar s]
-> ST s ([ThreadId], Map ThreadId (Set (Labelled TVarId)))
forall s.
[SomeTVar s]
-> ST s ([ThreadId], Map ThreadId (Set (Labelled TVarId)))
threadsUnblockedByWrites [SomeTVar s]
written
(SomeTVar s -> ST s ()) -> [SomeTVar s] -> ST s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(SomeTVar TVar s a
var) -> TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
unblockAllThreadsFromTVar TVar s a
var) [SomeTVar s]
written
let ([ThreadId]
unblocked,
SimState s a
simstate') = [ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
forall s a.
[ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
unblockThreads [ThreadId]
wakeup SimState s a
simstate
SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate' { timers :: OrdPSQ TimeoutId Time (TimerVars s)
timers = OrdPSQ TimeoutId Time (TimerVars s)
timers' }
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (TimeoutId -> SimEventType
EventTimerCancelled TimeoutId
tmid)
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ [(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
forall a.
[(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
traceMany
[ (Time
time, ThreadId
tid', Maybe ThreadLabel
tlbl', [Labelled TVarId] -> SimEventType
EventTxWakeup [Labelled TVarId]
vids)
| ThreadId
tid' <- [ThreadId]
unblocked
, let tlbl' :: Maybe ThreadLabel
tlbl' = ThreadId -> Map ThreadId (Thread s a) -> Maybe ThreadLabel
forall s a.
ThreadId -> Map ThreadId (Thread s a) -> Maybe ThreadLabel
lookupThreadLabel ThreadId
tid' Map ThreadId (Thread s a)
threads
, let Just [Labelled TVarId]
vids = Set (Labelled TVarId) -> [Labelled TVarId]
forall a. Set a -> [a]
Set.toList (Set (Labelled TVarId) -> [Labelled TVarId])
-> Maybe (Set (Labelled TVarId)) -> Maybe [Labelled TVarId]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreadId
-> Map ThreadId (Set (Labelled TVarId))
-> Maybe (Set (Labelled TVarId))
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ThreadId
tid' Map ThreadId (Set (Labelled TVarId))
wokeby ]
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ SimTrace a
trace
CancelTimeout (NegativeTimeout _tmid) SimA s b
k ->
{-# SCC "schedule.CancelTimeout" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
Fork IOSim s ()
a ThreadId -> SimA s b
k ->
{-# SCC "schedule.Fork" #-} do
let !nextId :: Int
nextId = Thread s a -> Int
forall s a. Thread s a -> Int
threadNextTId Thread s a
thread
!tid' :: ThreadId
tid' = ThreadId -> Int -> ThreadId
childThreadId ThreadId
tid Int
nextId
!thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (ThreadId -> SimA s b
k ThreadId
tid') ControlStack s b a
ctl
, threadNextTId :: Int
threadNextTId = Int -> Int
forall a. Enum a => a -> a
succ Int
nextId }
!thread'' :: Thread s a
thread'' = Thread :: forall s a.
ThreadId
-> ThreadControl s a
-> Bool
-> MaskingState
-> [(SomeException, Labelled ThreadId)]
-> ClockId
-> Maybe ThreadLabel
-> Int
-> Thread s a
Thread { threadId :: ThreadId
threadId = ThreadId
tid'
, threadControl :: ThreadControl s a
threadControl = SimA s () -> ControlStack s () a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (IOSim s () -> SimA s ()
forall s a. IOSim s a -> SimA s a
runIOSim IOSim s ()
a)
ControlStack s () a
forall s a. ControlStack s () a
ForkFrame
, threadBlocked :: Bool
threadBlocked = Bool
False
, threadMasking :: MaskingState
threadMasking = Thread s a -> MaskingState
forall s a. Thread s a -> MaskingState
threadMasking Thread s a
thread
, threadThrowTo :: [(SomeException, Labelled ThreadId)]
threadThrowTo = []
, threadClockId :: ClockId
threadClockId = Thread s a -> ClockId
forall s a. Thread s a -> ClockId
threadClockId Thread s a
thread
, threadLabel :: Maybe ThreadLabel
threadLabel = Maybe ThreadLabel
forall a. Maybe a
Nothing
, threadNextTId :: Int
threadNextTId = Int
1
}
!threads' :: Map ThreadId (Thread s a)
threads' = ThreadId
-> Thread s a
-> Map ThreadId (Thread s a)
-> Map ThreadId (Thread s a)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert ThreadId
tid' Thread s a
thread'' Map ThreadId (Thread s a)
threads
SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate { runqueue :: Deque ThreadId
runqueue = ThreadId -> Deque ThreadId -> Deque ThreadId
forall a. a -> Deque a -> Deque a
Deque.snoc ThreadId
tid' Deque ThreadId
runqueue
, threads :: Map ThreadId (Thread s a)
threads = Map ThreadId (Thread s a)
threads' }
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (ThreadId -> SimEventType
EventThreadForked ThreadId
tid') SimTrace a
trace)
Atomically STM s a
a a -> SimA s b
k ->
{-# SCC "schedule.Atomically" #-} Time
-> ThreadId
-> Maybe ThreadLabel
-> TVarId
-> StmA s a
-> (StmTxResult s a -> ST s (SimTrace a))
-> ST s (SimTrace a)
forall s a c.
Time
-> ThreadId
-> Maybe ThreadLabel
-> TVarId
-> StmA s a
-> (StmTxResult s a -> ST s (SimTrace c))
-> ST s (SimTrace c)
execAtomically Time
time ThreadId
tid Maybe ThreadLabel
tlbl TVarId
nextVid (STM s a -> StmA s a
forall s a. STM s a -> StmA s a
runSTM STM s a
a) ((StmTxResult s a -> ST s (SimTrace a)) -> ST s (SimTrace a))
-> (StmTxResult s a -> ST s (SimTrace a)) -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ \StmTxResult s a
res ->
case StmTxResult s a
res of
StmTxCommitted a
x [SomeTVar s]
written [SomeTVar s]
_read [SomeTVar s]
created
[Dynamic]
tvarDynamicTraces [ThreadLabel]
tvarStringTraces TVarId
nextVid' -> do
(![ThreadId]
wakeup, Map ThreadId (Set (Labelled TVarId))
wokeby) <- [SomeTVar s]
-> ST s ([ThreadId], Map ThreadId (Set (Labelled TVarId)))
forall s.
[SomeTVar s]
-> ST s ([ThreadId], Map ThreadId (Set (Labelled TVarId)))
threadsUnblockedByWrites [SomeTVar s]
written
!()
_ <- (SomeTVar s -> ST s ()) -> [SomeTVar s] -> ST s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(SomeTVar TVar s a
tvar) -> TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
unblockAllThreadsFromTVar TVar s a
tvar) [SomeTVar s]
written
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (a -> SimA s b
k a
x) ControlStack s b a
ctl }
([ThreadId]
unblocked,
SimState s a
simstate') = [ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
forall s a.
[ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
unblockThreads [ThreadId]
wakeup SimState s a
simstate
[Labelled TVarId]
written' <- (SomeTVar s -> ST s (Labelled TVarId))
-> [SomeTVar s] -> ST s [Labelled TVarId]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (\(SomeTVar TVar s a
tvar) -> TVar s a -> ST s (Labelled TVarId)
forall s a. TVar s a -> ST s (Labelled TVarId)
labelledTVarId TVar s a
tvar) [SomeTVar s]
written
[Labelled TVarId]
created' <- (SomeTVar s -> ST s (Labelled TVarId))
-> [SomeTVar s] -> ST s [Labelled TVarId]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (\(SomeTVar TVar s a
tvar) -> TVar s a -> ST s (Labelled TVarId)
forall s a. TVar s a -> ST s (Labelled TVarId)
labelledTVarId TVar s a
tvar) [SomeTVar s]
created
!SimTrace a
trace <- Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a.
Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
deschedule Deschedule
Yield Thread s a
thread' SimState s a
simstate' { nextVid :: TVarId
nextVid = TVarId
nextVid' }
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl ([Labelled TVarId]
-> [Labelled TVarId] -> Maybe Effect -> SimEventType
EventTxCommitted
[Labelled TVarId]
written' [Labelled TVarId]
created' Maybe Effect
forall a. Maybe a
Nothing)
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ [(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
forall a.
[(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
traceMany
[ (Time
time, ThreadId
tid', Maybe ThreadLabel
tlbl', [Labelled TVarId] -> SimEventType
EventTxWakeup [Labelled TVarId]
vids')
| ThreadId
tid' <- [ThreadId]
unblocked
, let tlbl' :: Maybe ThreadLabel
tlbl' = ThreadId -> Map ThreadId (Thread s a) -> Maybe ThreadLabel
forall s a.
ThreadId -> Map ThreadId (Thread s a) -> Maybe ThreadLabel
lookupThreadLabel ThreadId
tid' Map ThreadId (Thread s a)
threads
, let Just [Labelled TVarId]
vids' = Set (Labelled TVarId) -> [Labelled TVarId]
forall a. Set a -> [a]
Set.toList (Set (Labelled TVarId) -> [Labelled TVarId])
-> Maybe (Set (Labelled TVarId)) -> Maybe [Labelled TVarId]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreadId
-> Map ThreadId (Set (Labelled TVarId))
-> Maybe (Set (Labelled TVarId))
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ThreadId
tid' Map ThreadId (Set (Labelled TVarId))
wokeby ]
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ [(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
forall a.
[(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
traceMany
[ (Time
time, ThreadId
tid, Maybe ThreadLabel
tlbl, Dynamic -> SimEventType
EventLog Dynamic
tr)
| Dynamic
tr <- [Dynamic]
tvarDynamicTraces ]
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ [(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
forall a.
[(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
traceMany
[ (Time
time, ThreadId
tid, Maybe ThreadLabel
tlbl, ThreadLabel -> SimEventType
EventSay ThreadLabel
str)
| ThreadLabel
str <- [ThreadLabel]
tvarStringTraces ]
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl ([ThreadId] -> SimEventType
EventUnblocked [ThreadId]
unblocked)
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (Deschedule -> SimEventType
EventDeschedule Deschedule
Yield)
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ SimTrace a
trace
StmTxAborted [SomeTVar s]
_read SomeException
e -> do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (SomeException -> SimA s b
forall s a. SomeException -> SimA s a
Throw SomeException
e) ControlStack s b a
ctl }
!SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (Maybe Effect -> SimEventType
EventTxAborted Maybe Effect
forall a. Maybe a
Nothing) SimTrace a
trace
StmTxBlocked [SomeTVar s]
read -> do
!()
_ <- (SomeTVar s -> ST s ()) -> [SomeTVar s] -> ST s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(SomeTVar TVar s a
tvar) -> ThreadId -> TVar s a -> ST s ()
forall s a. ThreadId -> TVar s a -> ST s ()
blockThreadOnTVar ThreadId
tid TVar s a
tvar) [SomeTVar s]
read
[Labelled TVarId]
vids <- (SomeTVar s -> ST s (Labelled TVarId))
-> [SomeTVar s] -> ST s [Labelled TVarId]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (\(SomeTVar TVar s a
tvar) -> TVar s a -> ST s (Labelled TVarId)
forall s a. TVar s a -> ST s (Labelled TVarId)
labelledTVarId TVar s a
tvar) [SomeTVar s]
read
!SimTrace a
trace <- Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a.
Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
deschedule Deschedule
Blocked Thread s a
thread SimState s a
simstate
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl ([Labelled TVarId] -> Maybe Effect -> SimEventType
EventTxBlocked [Labelled TVarId]
vids Maybe Effect
forall a. Maybe a
Nothing)
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (Deschedule -> SimEventType
EventDeschedule Deschedule
Blocked)
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ SimTrace a
trace
GetThreadId ThreadId -> SimA s b
k ->
{-# SCC "schedule.GetThreadId" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (ThreadId -> SimA s b
k ThreadId
tid) ControlStack s b a
ctl }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
LabelThread ThreadId
tid' ThreadLabel
l SimA s b
k | ThreadId
tid' ThreadId -> ThreadId -> Bool
forall a. Eq a => a -> a -> Bool
== ThreadId
tid ->
{-# SCC "schedule.LabelThread" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl
, threadLabel :: Maybe ThreadLabel
threadLabel = ThreadLabel -> Maybe ThreadLabel
forall a. a -> Maybe a
Just ThreadLabel
l }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
LabelThread ThreadId
tid' ThreadLabel
l SimA s b
k ->
{-# SCC "schedule.LabelThread" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl }
threads' :: Map ThreadId (Thread s a)
threads' = (Thread s a -> Thread s a)
-> ThreadId
-> Map ThreadId (Thread s a)
-> Map ThreadId (Thread s a)
forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
Map.adjust (\Thread s a
t -> Thread s a
t { threadLabel :: Maybe ThreadLabel
threadLabel = ThreadLabel -> Maybe ThreadLabel
forall a. a -> Maybe a
Just ThreadLabel
l }) ThreadId
tid' Map ThreadId (Thread s a)
threads
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate { threads :: Map ThreadId (Thread s a)
threads = Map ThreadId (Thread s a)
threads' }
GetMaskState MaskingState -> SimA s b
k ->
{-# SCC "schedule.GetMaskState" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (MaskingState -> SimA s b
k MaskingState
maskst) ControlStack s b a
ctl }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
SetMaskState MaskingState
maskst' IOSim s a
action' a -> SimA s b
k ->
{-# SCC "schedule.SetMaskState" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s a -> ControlStack s a a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl
(IOSim s a -> SimA s a
forall s a. IOSim s a -> SimA s a
runIOSim IOSim s a
action')
((a -> SimA s b)
-> MaskingState -> ControlStack s b a -> ControlStack s a a
forall b s c a.
(b -> SimA s c)
-> MaskingState -> ControlStack s c a -> ControlStack s b a
MaskFrame a -> SimA s b
k MaskingState
maskst ControlStack s b a
ctl)
, threadMasking :: MaskingState
threadMasking = MaskingState
maskst' }
!SimTrace a
trace <-
case MaskingState
maskst' of
MaskingState
Unmasked -> Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (Deschedule -> SimEventType
EventDeschedule Deschedule
Interruptable)
(SimTrace a -> SimTrace a)
-> ST s (SimTrace a) -> ST s (SimTrace a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a.
Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
deschedule Deschedule
Interruptable Thread s a
thread' SimState s a
simstate
MaskingState
_ -> Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (MaskingState -> SimEventType
EventMask MaskingState
maskst')
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ SimTrace a
trace
ThrowTo SomeException
e ThreadId
tid' SimA s b
_ | ThreadId
tid' ThreadId -> ThreadId -> Bool
forall a. Eq a => a -> a -> Bool
== ThreadId
tid ->
{-# SCC "schedule.ThrowTo" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (SomeException -> SimA s b
forall s a. SomeException -> SimA s a
Throw SomeException
e) ControlStack s b a
ctl }
SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (SomeException -> ThreadId -> SimEventType
EventThrowTo SomeException
e ThreadId
tid) SimTrace a
trace)
ThrowTo SomeException
e ThreadId
tid' SimA s b
k ->
{-# SCC "schedule.ThrowTo" #-} do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl }
willBlock :: Bool
willBlock = case ThreadId -> Map ThreadId (Thread s a) -> Maybe (Thread s a)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ThreadId
tid' Map ThreadId (Thread s a)
threads of
Just Thread s a
t -> Bool -> Bool
not (Thread s a -> Bool
forall s a. Thread s a -> Bool
threadInterruptible Thread s a
t)
Maybe (Thread s a)
_ -> Bool
False
if Bool
willBlock
then do
let adjustTarget :: Thread s a -> Thread s a
adjustTarget Thread s a
t = Thread s a
t { threadThrowTo :: [(SomeException, Labelled ThreadId)]
threadThrowTo = (SomeException
e, ThreadId -> Maybe ThreadLabel -> Labelled ThreadId
forall a. a -> Maybe ThreadLabel -> Labelled a
Labelled ThreadId
tid Maybe ThreadLabel
tlbl) (SomeException, Labelled ThreadId)
-> [(SomeException, Labelled ThreadId)]
-> [(SomeException, Labelled ThreadId)]
forall a. a -> [a] -> [a]
: Thread s a -> [(SomeException, Labelled ThreadId)]
forall s a. Thread s a -> [(SomeException, Labelled ThreadId)]
threadThrowTo Thread s a
t }
threads' :: Map ThreadId (Thread s a)
threads' = (Thread s a -> Thread s a)
-> ThreadId
-> Map ThreadId (Thread s a)
-> Map ThreadId (Thread s a)
forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
Map.adjust Thread s a -> Thread s a
adjustTarget ThreadId
tid' Map ThreadId (Thread s a)
threads
!SimTrace a
trace <- Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a.
Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
deschedule Deschedule
Blocked Thread s a
thread' SimState s a
simstate { threads :: Map ThreadId (Thread s a)
threads = Map ThreadId (Thread s a)
threads' }
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (SomeException -> ThreadId -> SimEventType
EventThrowTo SomeException
e ThreadId
tid')
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl SimEventType
EventThrowToBlocked
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (Deschedule -> SimEventType
EventDeschedule Deschedule
Blocked)
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ SimTrace a
trace
else do
let adjustTarget :: Thread s a -> Thread s a
adjustTarget t :: Thread s a
t@Thread{ threadControl :: forall s a. Thread s a -> ThreadControl s a
threadControl = ThreadControl SimA s b
_ ControlStack s b a
ctl' } =
Thread s a
t { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (SomeException -> SimA s b
forall s a. SomeException -> SimA s a
Throw SomeException
e) ControlStack s b a
ctl'
, threadBlocked :: Bool
threadBlocked = Bool
False
}
simstate' :: SimState s a
simstate'@SimState { threads :: forall s a. SimState s a -> Map ThreadId (Thread s a)
threads = Map ThreadId (Thread s a)
threads' }
= ([ThreadId], SimState s a) -> SimState s a
forall a b. (a, b) -> b
snd ([ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
forall s a.
[ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
unblockThreads [ThreadId
tid'] SimState s a
simstate)
threads'' :: Map ThreadId (Thread s a)
threads'' = (Thread s a -> Thread s a)
-> ThreadId
-> Map ThreadId (Thread s a)
-> Map ThreadId (Thread s a)
forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
Map.adjust Thread s a -> Thread s a
adjustTarget ThreadId
tid' Map ThreadId (Thread s a)
threads'
simstate'' :: SimState s a
simstate'' = SimState s a
simstate' { threads :: Map ThreadId (Thread s a)
threads = Map ThreadId (Thread s a)
threads'' }
SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate''
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (SomeException -> ThreadId -> SimEventType
EventThrowTo SomeException
e ThreadId
tid')
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ SimTrace a
trace
YieldSim SimA s b
k -> do
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl }
Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a.
Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
deschedule Deschedule
Yield Thread s a
thread' SimState s a
simstate
ExploreRaces SimA s b
k ->
{-# SCC "schedule.ExploreRaces" #-}
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread{ threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k ControlStack s b a
ctl } SimState s a
simstate
Fix x -> IOSim s x
f x -> SimA s b
k ->
{-# SCC "schedule.Fix" #-} do
STRef s x
r <- x -> ST s (STRef s x)
forall a s. a -> ST s (STRef s a)
newSTRef (NonTermination -> x
forall a e. Exception e => e -> a
throw NonTermination
NonTermination)
x
x <- ST s x -> ST s x
forall s a. ST s a -> ST s a
unsafeInterleaveST (ST s x -> ST s x) -> ST s x -> ST s x
forall a b. (a -> b) -> a -> b
$ STRef s x -> ST s x
forall s a. STRef s a -> ST s a
readSTRef STRef s x
r
let k' :: SimA s b
k' = IOSim s x -> forall r. (x -> SimA s r) -> SimA s r
forall s a. IOSim s a -> forall r. (a -> SimA s r) -> SimA s r
unIOSim (x -> IOSim s x
f x
x) ((x -> SimA s b) -> SimA s b) -> (x -> SimA s b) -> SimA s b
forall a b. (a -> b) -> a -> b
$ \x
x' ->
ST s () -> (() -> SimA s b) -> SimA s b
forall s a b. ST s a -> (a -> SimA s b) -> SimA s b
LiftST (ST s () -> ST s ()
forall s a. ST s a -> ST s a
lazyToStrictST (STRef s x -> x -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s x
r x
x')) (\() -> x -> SimA s b
k x
x')
thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl SimA s b
k' ControlStack s b a
ctl }
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate
threadInterruptible :: Thread s a -> Bool
threadInterruptible :: Thread s a -> Bool
threadInterruptible Thread s a
thread =
case Thread s a -> MaskingState
forall s a. Thread s a -> MaskingState
threadMasking Thread s a
thread of
MaskingState
Unmasked -> Bool
True
MaskingState
MaskedInterruptible
| Thread s a -> Bool
forall s a. Thread s a -> Bool
threadBlocked Thread s a
thread -> Bool
True
| Bool
otherwise -> Bool
False
MaskingState
MaskedUninterruptible -> Bool
False
deschedule :: Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
deschedule :: Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
deschedule Deschedule
Yield !Thread s a
thread !simstate :: SimState s a
simstate@SimState{Deque ThreadId
runqueue :: Deque ThreadId
runqueue :: forall s a. SimState s a -> Deque ThreadId
runqueue, Map ThreadId (Thread s a)
threads :: Map ThreadId (Thread s a)
threads :: forall s a. SimState s a -> Map ThreadId (Thread s a)
threads} =
{-# SCC "deschedule.Yield" #-}
let runqueue' :: Deque ThreadId
runqueue' = ThreadId -> Deque ThreadId -> Deque ThreadId
forall a. a -> Deque a -> Deque a
Deque.snoc (Thread s a -> ThreadId
forall s a. Thread s a -> ThreadId
threadId Thread s a
thread) Deque ThreadId
runqueue
threads' :: Map ThreadId (Thread s a)
threads' = ThreadId
-> Thread s a
-> Map ThreadId (Thread s a)
-> Map ThreadId (Thread s a)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (Thread s a -> ThreadId
forall s a. Thread s a -> ThreadId
threadId Thread s a
thread) Thread s a
thread Map ThreadId (Thread s a)
threads in
SimState s a -> ST s (SimTrace a)
forall s a. SimState s a -> ST s (SimTrace a)
reschedule SimState s a
simstate { runqueue :: Deque ThreadId
runqueue = Deque ThreadId
runqueue', threads :: Map ThreadId (Thread s a)
threads = Map ThreadId (Thread s a)
threads' }
deschedule Deschedule
Interruptable !thread :: Thread s a
thread@Thread {
threadId :: forall s a. Thread s a -> ThreadId
threadId = ThreadId
tid,
threadControl :: forall s a. Thread s a -> ThreadControl s a
threadControl = ThreadControl SimA s b
_ ControlStack s b a
ctl,
threadMasking :: forall s a. Thread s a -> MaskingState
threadMasking = MaskingState
Unmasked,
threadThrowTo :: forall s a. Thread s a -> [(SomeException, Labelled ThreadId)]
threadThrowTo = (SomeException
e, Labelled ThreadId
tid') : [(SomeException, Labelled ThreadId)]
etids,
threadLabel :: forall s a. Thread s a -> Maybe ThreadLabel
threadLabel = Maybe ThreadLabel
tlbl
}
!simstate :: SimState s a
simstate@SimState{ curTime :: forall s a. SimState s a -> Time
curTime = Time
time, Map ThreadId (Thread s a)
threads :: Map ThreadId (Thread s a)
threads :: forall s a. SimState s a -> Map ThreadId (Thread s a)
threads } =
{-# SCC "deschedule.Interruptable.Unmasked" #-}
let thread' :: Thread s a
thread' = Thread s a
thread { threadControl :: ThreadControl s a
threadControl = SimA s b -> ControlStack s b a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (SomeException -> SimA s b
forall s a. SomeException -> SimA s a
Throw SomeException
e) ControlStack s b a
ctl
, threadMasking :: MaskingState
threadMasking = MaskingState
MaskedInterruptible
, threadThrowTo :: [(SomeException, Labelled ThreadId)]
threadThrowTo = [(SomeException, Labelled ThreadId)]
etids }
([ThreadId]
unblocked,
SimState s a
simstate') = [ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
forall s a.
[ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
unblockThreads [Labelled ThreadId -> ThreadId
forall a. Labelled a -> a
l_labelled Labelled ThreadId
tid'] SimState s a
simstate
in do
SimTrace a
trace <- Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread' SimState s a
simstate'
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (Labelled ThreadId -> SimEventType
EventThrowToUnmasked Labelled ThreadId
tid')
(SimTrace a -> SimTrace a) -> SimTrace a -> SimTrace a
forall a b. (a -> b) -> a -> b
$ [(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
forall a.
[(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
traceMany [ (Time
time, ThreadId
tid'', Maybe ThreadLabel
tlbl'', SimEventType
EventThrowToWakeup)
| ThreadId
tid'' <- [ThreadId]
unblocked
, let tlbl'' :: Maybe ThreadLabel
tlbl'' = ThreadId -> Map ThreadId (Thread s a) -> Maybe ThreadLabel
forall s a.
ThreadId -> Map ThreadId (Thread s a) -> Maybe ThreadLabel
lookupThreadLabel ThreadId
tid'' Map ThreadId (Thread s a)
threads ]
SimTrace a
trace
deschedule Deschedule
Interruptable !Thread s a
thread !SimState s a
simstate =
{-# SCC "deschedule.Interruptable.Masked" #-}
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread SimState s a
simstate
deschedule Deschedule
Blocked !thread :: Thread s a
thread@Thread { threadThrowTo :: forall s a. Thread s a -> [(SomeException, Labelled ThreadId)]
threadThrowTo = (SomeException, Labelled ThreadId)
_ : [(SomeException, Labelled ThreadId)]
_
, threadMasking :: forall s a. Thread s a -> MaskingState
threadMasking = MaskingState
maskst } !SimState s a
simstate
| MaskingState
maskst MaskingState -> MaskingState -> Bool
forall a. Eq a => a -> a -> Bool
/= MaskingState
MaskedUninterruptible =
{-# SCC "deschedule.Interruptable.Blocked.1" #-}
Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a.
Deschedule -> Thread s a -> SimState s a -> ST s (SimTrace a)
deschedule Deschedule
Interruptable Thread s a
thread { threadMasking :: MaskingState
threadMasking = MaskingState
Unmasked } SimState s a
simstate
deschedule Deschedule
Blocked !Thread s a
thread !simstate :: SimState s a
simstate@SimState{Map ThreadId (Thread s a)
threads :: Map ThreadId (Thread s a)
threads :: forall s a. SimState s a -> Map ThreadId (Thread s a)
threads} =
{-# SCC "deschedule.Interruptable.Blocked.2" #-}
let thread' :: Thread s a
thread' = Thread s a
thread { threadBlocked :: Bool
threadBlocked = Bool
True }
threads' :: Map ThreadId (Thread s a)
threads' = ThreadId
-> Thread s a
-> Map ThreadId (Thread s a)
-> Map ThreadId (Thread s a)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (Thread s a -> ThreadId
forall s a. Thread s a -> ThreadId
threadId Thread s a
thread') Thread s a
thread' Map ThreadId (Thread s a)
threads in
SimState s a -> ST s (SimTrace a)
forall s a. SimState s a -> ST s (SimTrace a)
reschedule SimState s a
simstate { threads :: Map ThreadId (Thread s a)
threads = Map ThreadId (Thread s a)
threads' }
deschedule Deschedule
Terminated !Thread s a
thread !simstate :: SimState s a
simstate@SimState{ curTime :: forall s a. SimState s a -> Time
curTime = Time
time, Map ThreadId (Thread s a)
threads :: Map ThreadId (Thread s a)
threads :: forall s a. SimState s a -> Map ThreadId (Thread s a)
threads } =
{-# SCC "deschedule.Terminated" #-}
let !wakeup :: [ThreadId]
wakeup = ((SomeException, Labelled ThreadId) -> ThreadId)
-> [(SomeException, Labelled ThreadId)] -> [ThreadId]
forall a b. (a -> b) -> [a] -> [b]
map (Labelled ThreadId -> ThreadId
forall a. Labelled a -> a
l_labelled (Labelled ThreadId -> ThreadId)
-> ((SomeException, Labelled ThreadId) -> Labelled ThreadId)
-> (SomeException, Labelled ThreadId)
-> ThreadId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SomeException, Labelled ThreadId) -> Labelled ThreadId
forall a b. (a, b) -> b
snd) ([(SomeException, Labelled ThreadId)]
-> [(SomeException, Labelled ThreadId)]
forall a. [a] -> [a]
reverse (Thread s a -> [(SomeException, Labelled ThreadId)]
forall s a. Thread s a -> [(SomeException, Labelled ThreadId)]
threadThrowTo Thread s a
thread))
([ThreadId]
unblocked,
!SimState s a
simstate') = [ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
forall s a.
[ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
unblockThreads [ThreadId]
wakeup SimState s a
simstate
in do
!SimTrace a
trace <- SimState s a -> ST s (SimTrace a)
forall s a. SimState s a -> ST s (SimTrace a)
reschedule SimState s a
simstate'
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ [(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
forall a.
[(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
traceMany
[ (Time
time, ThreadId
tid', Maybe ThreadLabel
tlbl', SimEventType
EventThrowToWakeup)
| ThreadId
tid' <- [ThreadId]
unblocked
, let tlbl' :: Maybe ThreadLabel
tlbl' = ThreadId -> Map ThreadId (Thread s a) -> Maybe ThreadLabel
forall s a.
ThreadId -> Map ThreadId (Thread s a) -> Maybe ThreadLabel
lookupThreadLabel ThreadId
tid' Map ThreadId (Thread s a)
threads ]
SimTrace a
trace
deschedule Deschedule
Sleep Thread s a
_thread SimState s a
_simstate =
ThreadLabel -> ST s (SimTrace a)
forall a. (?callStack::CallStack) => ThreadLabel -> a
error ThreadLabel
"IOSim: impossible happend"
reschedule :: SimState s a -> ST s (SimTrace a)
reschedule :: SimState s a -> ST s (SimTrace a)
reschedule !simstate :: SimState s a
simstate@SimState{ Deque ThreadId
runqueue :: Deque ThreadId
runqueue :: forall s a. SimState s a -> Deque ThreadId
runqueue, Map ThreadId (Thread s a)
threads :: Map ThreadId (Thread s a)
threads :: forall s a. SimState s a -> Map ThreadId (Thread s a)
threads }
| Just (!ThreadId
tid, Deque ThreadId
runqueue') <- Deque ThreadId -> Maybe (ThreadId, Deque ThreadId)
forall a. Deque a -> Maybe (a, Deque a)
Deque.uncons Deque ThreadId
runqueue =
{-# SCC "reschedule.Just" #-}
Bool -> ST s (SimTrace a) -> ST s (SimTrace a)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Maybe (Thread s a) -> SimState s a -> Bool
forall s a. Maybe (Thread s a) -> SimState s a -> Bool
invariant Maybe (Thread s a)
forall a. Maybe a
Nothing SimState s a
simstate) (ST s (SimTrace a) -> ST s (SimTrace a))
-> ST s (SimTrace a) -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$
let thread :: Thread s a
thread = Map ThreadId (Thread s a)
threads Map ThreadId (Thread s a) -> ThreadId -> Thread s a
forall k a. Ord k => Map k a -> k -> a
Map.! ThreadId
tid in
Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
thread SimState s a
simstate { runqueue :: Deque ThreadId
runqueue = Deque ThreadId
runqueue'
, threads :: Map ThreadId (Thread s a)
threads = ThreadId -> Map ThreadId (Thread s a) -> Map ThreadId (Thread s a)
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete ThreadId
tid Map ThreadId (Thread s a)
threads }
reschedule !simstate :: SimState s a
simstate@SimState{ Map ThreadId (Thread s a)
threads :: Map ThreadId (Thread s a)
threads :: forall s a. SimState s a -> Map ThreadId (Thread s a)
threads, OrdPSQ TimeoutId Time (TimerVars s)
timers :: OrdPSQ TimeoutId Time (TimerVars s)
timers :: forall s a. SimState s a -> OrdPSQ TimeoutId Time (TimerVars s)
timers, curTime :: forall s a. SimState s a -> Time
curTime = Time
time } =
{-# SCC "reschedule.Nothing" #-}
Bool -> ST s (SimTrace a) -> ST s (SimTrace a)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Maybe (Thread s a) -> SimState s a -> Bool
forall s a. Maybe (Thread s a) -> SimState s a -> Bool
invariant Maybe (Thread s a)
forall a. Maybe a
Nothing SimState s a
simstate) (ST s (SimTrace a) -> ST s (SimTrace a))
-> ST s (SimTrace a) -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$
case OrdPSQ TimeoutId Time (TimerVars s)
-> Maybe
([TimeoutId], Time, [TimerVars s],
OrdPSQ TimeoutId Time (TimerVars s))
forall k p a.
(Ord k, Ord p) =>
OrdPSQ k p a -> Maybe ([k], p, [a], OrdPSQ k p a)
removeMinimums OrdPSQ TimeoutId Time (TimerVars s)
timers of
Maybe
([TimeoutId], Time, [TimerVars s],
OrdPSQ TimeoutId Time (TimerVars s))
Nothing -> SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Time -> [Labelled ThreadId] -> SimTrace a
forall a. Time -> [Labelled ThreadId] -> SimTrace a
TraceDeadlock Time
time (Map ThreadId (Thread s a) -> [Labelled ThreadId]
forall s a. Map ThreadId (Thread s a) -> [Labelled ThreadId]
labelledThreads Map ThreadId (Thread s a)
threads))
Just ([TimeoutId]
tmids, !Time
time', ![TimerVars s]
fired, !OrdPSQ TimeoutId Time (TimerVars s)
timers') -> Bool -> ST s (SimTrace a) -> ST s (SimTrace a)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert (Time
time' Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
>= Time
time) (ST s (SimTrace a) -> ST s (SimTrace a))
-> ST s (SimTrace a) -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$ do
![SomeTVar s]
written <- StmA s () -> ST s [SomeTVar s]
forall s. StmA s () -> ST s [SomeTVar s]
execAtomically' (STM s () -> StmA s ()
forall s a. STM s a -> StmA s a
runSTM (STM s () -> StmA s ()) -> STM s () -> StmA s ()
forall a b. (a -> b) -> a -> b
$ (TimerVars s -> STM s ()) -> [TimerVars s] -> STM s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ TimerVars s -> STM s ()
forall (m :: * -> *) s.
(MonadSTM m, TVar m ~ TVar s) =>
TimerVars s -> STM m ()
timeoutAction [TimerVars s]
fired)
([ThreadId]
wakeup, Map ThreadId (Set (Labelled TVarId))
wokeby) <- [SomeTVar s]
-> ST s ([ThreadId], Map ThreadId (Set (Labelled TVarId)))
forall s.
[SomeTVar s]
-> ST s ([ThreadId], Map ThreadId (Set (Labelled TVarId)))
threadsUnblockedByWrites [SomeTVar s]
written
!()
_ <- (SomeTVar s -> ST s ()) -> [SomeTVar s] -> ST s ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (\(SomeTVar TVar s a
tvar) -> TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
unblockAllThreadsFromTVar TVar s a
tvar) [SomeTVar s]
written
let ([ThreadId]
unblocked,
SimState s a
simstate') = [ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
forall s a.
[ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
unblockThreads [ThreadId]
wakeup SimState s a
simstate
!SimTrace a
trace <- SimState s a -> ST s (SimTrace a)
forall s a. SimState s a -> ST s (SimTrace a)
reschedule SimState s a
simstate' { curTime :: Time
curTime = Time
time'
, timers :: OrdPSQ TimeoutId Time (TimerVars s)
timers = OrdPSQ TimeoutId Time (TimerVars s)
timers' }
SimTrace a -> ST s (SimTrace a)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace a -> ST s (SimTrace a))
-> SimTrace a -> ST s (SimTrace a)
forall a b. (a -> b) -> a -> b
$
[(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
forall a.
[(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
traceMany ([ (Time
time', [Int] -> ThreadId
ThreadId [-Int
1], ThreadLabel -> Maybe ThreadLabel
forall a. a -> Maybe a
Just ThreadLabel
"timer", TimeoutId -> SimEventType
EventTimerExpired TimeoutId
tmid)
| TimeoutId
tmid <- [TimeoutId]
tmids ]
[(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> [(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> [(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
forall a. [a] -> [a] -> [a]
++ [ (Time
time', ThreadId
tid', Maybe ThreadLabel
tlbl', [Labelled TVarId] -> SimEventType
EventTxWakeup [Labelled TVarId]
vids)
| ThreadId
tid' <- [ThreadId]
unblocked
, let tlbl' :: Maybe ThreadLabel
tlbl' = ThreadId -> Map ThreadId (Thread s a) -> Maybe ThreadLabel
forall s a.
ThreadId -> Map ThreadId (Thread s a) -> Maybe ThreadLabel
lookupThreadLabel ThreadId
tid' Map ThreadId (Thread s a)
threads
, let Just [Labelled TVarId]
vids = Set (Labelled TVarId) -> [Labelled TVarId]
forall a. Set a -> [a]
Set.toList (Set (Labelled TVarId) -> [Labelled TVarId])
-> Maybe (Set (Labelled TVarId)) -> Maybe [Labelled TVarId]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreadId
-> Map ThreadId (Set (Labelled TVarId))
-> Maybe (Set (Labelled TVarId))
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ThreadId
tid' Map ThreadId (Set (Labelled TVarId))
wokeby ])
SimTrace a
trace
where
timeoutAction :: TimerVars s -> STM m ()
timeoutAction (TimerVars TVar s TimeoutState
var TVar s Bool
bvar) = do
TimeoutState
x <- TVar m TimeoutState -> STM m TimeoutState
forall (m :: * -> *) a. MonadSTM m => TVar m a -> STM m a
readTVar TVar m TimeoutState
TVar s TimeoutState
var
case TimeoutState
x of
TimeoutState
TimeoutPending -> TVar m TimeoutState -> TimeoutState -> STM m ()
forall (m :: * -> *) a. MonadSTM m => TVar m a -> a -> STM m ()
writeTVar TVar m TimeoutState
TVar s TimeoutState
var TimeoutState
TimeoutFired
STM m () -> STM m () -> STM m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TVar m Bool -> Bool -> STM m ()
forall (m :: * -> *) a. MonadSTM m => TVar m a -> a -> STM m ()
writeTVar TVar m Bool
TVar s Bool
bvar Bool
True
TimeoutState
TimeoutFired -> ThreadLabel -> STM m ()
forall a. (?callStack::CallStack) => ThreadLabel -> a
error ThreadLabel
"MonadTimer(Sim): invariant violation"
TimeoutState
TimeoutCancelled -> () -> STM m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
unblockThreads :: [ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
unblockThreads :: [ThreadId] -> SimState s a -> ([ThreadId], SimState s a)
unblockThreads ![ThreadId]
wakeup !simstate :: SimState s a
simstate@SimState {Deque ThreadId
runqueue :: Deque ThreadId
runqueue :: forall s a. SimState s a -> Deque ThreadId
runqueue, Map ThreadId (Thread s a)
threads :: Map ThreadId (Thread s a)
threads :: forall s a. SimState s a -> Map ThreadId (Thread s a)
threads} =
([ThreadId]
unblocked, SimState s a
simstate {
runqueue :: Deque ThreadId
runqueue = Deque ThreadId
runqueue Deque ThreadId -> Deque ThreadId -> Deque ThreadId
forall a. Semigroup a => a -> a -> a
<> [Item (Deque ThreadId)] -> Deque ThreadId
forall l. IsList l => [Item l] -> l
fromList [Item (Deque ThreadId)]
[ThreadId]
unblocked,
threads :: Map ThreadId (Thread s a)
threads = Map ThreadId (Thread s a)
threads'
})
where
!unblocked :: [ThreadId]
unblocked = [ ThreadId
tid
| ThreadId
tid <- [ThreadId]
wakeup
, case ThreadId -> Map ThreadId (Thread s a) -> Maybe (Thread s a)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ThreadId
tid Map ThreadId (Thread s a)
threads of
Just Thread { threadBlocked :: forall s a. Thread s a -> Bool
threadBlocked = Bool
True } -> Bool
True
Maybe (Thread s a)
_ -> Bool
False
]
!threads' :: Map ThreadId (Thread s a)
threads' = (Map ThreadId (Thread s a)
-> ThreadId -> Map ThreadId (Thread s a))
-> Map ThreadId (Thread s a)
-> [ThreadId]
-> Map ThreadId (Thread s a)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
List.foldl'
((ThreadId
-> Map ThreadId (Thread s a) -> Map ThreadId (Thread s a))
-> Map ThreadId (Thread s a)
-> ThreadId
-> Map ThreadId (Thread s a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((Thread s a -> Thread s a)
-> ThreadId
-> Map ThreadId (Thread s a)
-> Map ThreadId (Thread s a)
forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
Map.adjust (\Thread s a
t -> Thread s a
t { threadBlocked :: Bool
threadBlocked = Bool
False })))
Map ThreadId (Thread s a)
threads [ThreadId]
unblocked
unwindControlStack :: forall s a.
SomeException
-> Thread s a
-> Either Bool (Thread s a)
unwindControlStack :: SomeException -> Thread s a -> Either Bool (Thread s a)
unwindControlStack SomeException
e Thread s a
thread =
case Thread s a -> ThreadControl s a
forall s a. Thread s a -> ThreadControl s a
threadControl Thread s a
thread of
ThreadControl SimA s b
_ ControlStack s b a
ctl -> MaskingState -> ControlStack s b a -> Either Bool (Thread s a)
forall s' c.
MaskingState -> ControlStack s' c a -> Either Bool (Thread s' a)
unwind (Thread s a -> MaskingState
forall s a. Thread s a -> MaskingState
threadMasking Thread s a
thread) ControlStack s b a
ctl
where
unwind :: forall s' c. MaskingState
-> ControlStack s' c a -> Either Bool (Thread s' a)
unwind :: MaskingState -> ControlStack s' c a -> Either Bool (Thread s' a)
unwind MaskingState
_ ControlStack s' c a
MainFrame = Bool -> Either Bool (Thread s' a)
forall a b. a -> Either a b
Left Bool
True
unwind MaskingState
_ ControlStack s' c a
ForkFrame = Bool -> Either Bool (Thread s' a)
forall a b. a -> Either a b
Left Bool
False
unwind MaskingState
_ (MaskFrame c -> SimA s' c
_k MaskingState
maskst' ControlStack s' c a
ctl) = MaskingState -> ControlStack s' c a -> Either Bool (Thread s' a)
forall s' c.
MaskingState -> ControlStack s' c a -> Either Bool (Thread s' a)
unwind MaskingState
maskst' ControlStack s' c a
ctl
unwind MaskingState
maskst (CatchFrame e -> SimA s' c
handler c -> SimA s' c
k ControlStack s' c a
ctl) =
case SomeException -> Maybe e
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
e of
Maybe e
Nothing -> MaskingState -> ControlStack s' c a -> Either Bool (Thread s' a)
forall s' c.
MaskingState -> ControlStack s' c a -> Either Bool (Thread s' a)
unwind MaskingState
maskst ControlStack s' c a
ctl
Just e
e' -> Thread s' a -> Either Bool (Thread s' a)
forall a b. b -> Either a b
Right Thread s a
thread {
threadControl :: ThreadControl s' a
threadControl = SimA s' c -> ControlStack s' c a -> ThreadControl s' a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (e -> SimA s' c
handler e
e')
((c -> SimA s' c)
-> MaskingState -> ControlStack s' c a -> ControlStack s' c a
forall b s c a.
(b -> SimA s c)
-> MaskingState -> ControlStack s c a -> ControlStack s b a
MaskFrame c -> SimA s' c
k MaskingState
maskst ControlStack s' c a
ctl),
threadMasking :: MaskingState
threadMasking = MaskingState -> MaskingState
atLeastInterruptibleMask MaskingState
maskst
}
atLeastInterruptibleMask :: MaskingState -> MaskingState
atLeastInterruptibleMask :: MaskingState -> MaskingState
atLeastInterruptibleMask MaskingState
Unmasked = MaskingState
MaskedInterruptible
atLeastInterruptibleMask MaskingState
ms = MaskingState
ms
removeMinimums :: (Ord k, Ord p)
=> OrdPSQ k p a
-> Maybe ([k], p, [a], OrdPSQ k p a)
removeMinimums :: OrdPSQ k p a -> Maybe ([k], p, [a], OrdPSQ k p a)
removeMinimums = \OrdPSQ k p a
psq ->
case OrdPSQ k p a -> Maybe (k, p, a, OrdPSQ k p a)
forall k p v.
(Ord k, Ord p) =>
OrdPSQ k p v -> Maybe (k, p, v, OrdPSQ k p v)
PSQ.minView OrdPSQ k p a
psq of
Maybe (k, p, a, OrdPSQ k p a)
Nothing -> Maybe ([k], p, [a], OrdPSQ k p a)
forall a. Maybe a
Nothing
Just (k
k, p
p, a
x, OrdPSQ k p a
psq') -> ([k], p, [a], OrdPSQ k p a) -> Maybe ([k], p, [a], OrdPSQ k p a)
forall a. a -> Maybe a
Just ([k] -> p -> [a] -> OrdPSQ k p a -> ([k], p, [a], OrdPSQ k p a)
forall a b a.
(Ord a, Ord b) =>
[a] -> b -> [a] -> OrdPSQ a b a -> ([a], b, [a], OrdPSQ a b a)
collectAll [k
k] p
p [a
x] OrdPSQ k p a
psq')
where
collectAll :: [a] -> b -> [a] -> OrdPSQ a b a -> ([a], b, [a], OrdPSQ a b a)
collectAll ![a]
ks !b
p ![a]
xs !OrdPSQ a b a
psq =
case OrdPSQ a b a -> Maybe (a, b, a, OrdPSQ a b a)
forall k p v.
(Ord k, Ord p) =>
OrdPSQ k p v -> Maybe (k, p, v, OrdPSQ k p v)
PSQ.minView OrdPSQ a b a
psq of
Just (a
k, b
p', a
x, OrdPSQ a b a
psq')
| b
p b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== b
p' -> [a] -> b -> [a] -> OrdPSQ a b a -> ([a], b, [a], OrdPSQ a b a)
collectAll (a
ka -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
ks) b
p (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
xs) OrdPSQ a b a
psq'
Maybe (a, b, a, OrdPSQ a b a)
_ -> ([a] -> [a]
forall a. [a] -> [a]
reverse [a]
ks, b
p, [a] -> [a]
forall a. [a] -> [a]
reverse [a]
xs, OrdPSQ a b a
psq)
traceMany :: [(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
traceMany :: [(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
traceMany [] SimTrace a
trace = SimTrace a
trace
traceMany ((Time
time, ThreadId
tid, Maybe ThreadLabel
tlbl, SimEventType
event):[(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
ts) SimTrace a
trace =
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl SimEventType
event ([(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
forall a.
[(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
-> SimTrace a -> SimTrace a
traceMany [(Time, ThreadId, Maybe ThreadLabel, SimEventType)]
ts SimTrace a
trace)
lookupThreadLabel :: ThreadId -> Map ThreadId (Thread s a) -> Maybe ThreadLabel
lookupThreadLabel :: ThreadId -> Map ThreadId (Thread s a) -> Maybe ThreadLabel
lookupThreadLabel ThreadId
tid Map ThreadId (Thread s a)
threads = Maybe (Maybe ThreadLabel) -> Maybe ThreadLabel
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (Thread s a -> Maybe ThreadLabel
forall s a. Thread s a -> Maybe ThreadLabel
threadLabel (Thread s a -> Maybe ThreadLabel)
-> Maybe (Thread s a) -> Maybe (Maybe ThreadLabel)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ThreadId -> Map ThreadId (Thread s a) -> Maybe (Thread s a)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ThreadId
tid Map ThreadId (Thread s a)
threads)
runSimTraceST :: forall s a. IOSim s a -> ST s (SimTrace a)
runSimTraceST :: IOSim s a -> ST s (SimTrace a)
runSimTraceST IOSim s a
mainAction = Thread s a -> SimState s a -> ST s (SimTrace a)
forall s a. Thread s a -> SimState s a -> ST s (SimTrace a)
schedule Thread s a
mainThread SimState s a
forall s a. SimState s a
initialState
where
mainThread :: Thread s a
mainThread =
Thread :: forall s a.
ThreadId
-> ThreadControl s a
-> Bool
-> MaskingState
-> [(SomeException, Labelled ThreadId)]
-> ClockId
-> Maybe ThreadLabel
-> Int
-> Thread s a
Thread {
threadId :: ThreadId
threadId = [Int] -> ThreadId
ThreadId [],
threadControl :: ThreadControl s a
threadControl = SimA s a -> ControlStack s a a -> ThreadControl s a
forall s b a. SimA s b -> ControlStack s b a -> ThreadControl s a
ThreadControl (IOSim s a -> SimA s a
forall s a. IOSim s a -> SimA s a
runIOSim IOSim s a
mainAction) ControlStack s a a
forall s a. ControlStack s a a
MainFrame,
threadBlocked :: Bool
threadBlocked = Bool
False,
threadMasking :: MaskingState
threadMasking = MaskingState
Unmasked,
threadThrowTo :: [(SomeException, Labelled ThreadId)]
threadThrowTo = [],
threadClockId :: ClockId
threadClockId = [Int] -> ClockId
ClockId [],
threadLabel :: Maybe ThreadLabel
threadLabel = ThreadLabel -> Maybe ThreadLabel
forall a. a -> Maybe a
Just ThreadLabel
"main",
threadNextTId :: Int
threadNextTId = Int
1
}
execAtomically :: forall s a c.
Time
-> ThreadId
-> Maybe ThreadLabel
-> TVarId
-> StmA s a
-> (StmTxResult s a -> ST s (SimTrace c))
-> ST s (SimTrace c)
execAtomically :: Time
-> ThreadId
-> Maybe ThreadLabel
-> TVarId
-> StmA s a
-> (StmTxResult s a -> ST s (SimTrace c))
-> ST s (SimTrace c)
execAtomically !Time
time !ThreadId
tid !Maybe ThreadLabel
tlbl !TVarId
nextVid0 StmA s a
action0 StmTxResult s a -> ST s (SimTrace c)
k0 =
StmStack s a a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s a
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s a a
forall s a. StmStack s a a
AtomicallyFrame Map TVarId (SomeTVar s)
forall k a. Map k a
Map.empty Map TVarId (SomeTVar s)
forall k a. Map k a
Map.empty [] [] TVarId
nextVid0 StmA s a
action0
where
go :: forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go :: StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go !StmStack s b a
ctl !Map TVarId (SomeTVar s)
read !Map TVarId (SomeTVar s)
written ![SomeTVar s]
writtenSeq ![SomeTVar s]
createdSeq !TVarId
nextVid StmA s b
action = Bool -> ST s (SimTrace c) -> ST s (SimTrace c)
forall a. (?callStack::CallStack) => Bool -> a -> a
assert Bool
localInvariant (ST s (SimTrace c) -> ST s (SimTrace c))
-> ST s (SimTrace c) -> ST s (SimTrace c)
forall a b. (a -> b) -> a -> b
$
case StmA s b
action of
ReturnStm b
x ->
{-# SCC "execAtomically.go.ReturnStm" #-}
case StmStack s b a
ctl of
StmStack s b a
AtomicallyFrame -> do
![TraceValue]
ds <- (SomeTVar s -> ST s TraceValue)
-> [SomeTVar s] -> ST s [TraceValue]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (\(SomeTVar TVar s a
tvar) -> TVar s a -> Bool -> ST s TraceValue
forall s a. TVar s a -> Bool -> ST s TraceValue
traceTVarST TVar s a
tvar Bool
True) [SomeTVar s]
createdSeq
![TraceValue]
ds' <- Map TVarId TraceValue -> [TraceValue]
forall k a. Map k a -> [a]
Map.elems (Map TVarId TraceValue -> [TraceValue])
-> ST s (Map TVarId TraceValue) -> ST s [TraceValue]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (SomeTVar s -> ST s TraceValue)
-> Map TVarId (SomeTVar s) -> ST s (Map TVarId TraceValue)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse
(\(SomeTVar TVar s a
tvar) -> do
TraceValue
tr <- TVar s a -> Bool -> ST s TraceValue
forall s a. TVar s a -> Bool -> ST s TraceValue
traceTVarST TVar s a
tvar Bool
False
!()
_ <- TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
commitTVar TVar s a
tvar
[a]
undos <- TVar s a -> ST s [a]
forall s a. TVar s a -> ST s [a]
readTVarUndos TVar s a
tvar
Bool -> ST s TraceValue -> ST s TraceValue
forall a. (?callStack::CallStack) => Bool -> a -> a
assert ([a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [a]
undos) (ST s TraceValue -> ST s TraceValue)
-> ST s TraceValue -> ST s TraceValue
forall a b. (a -> b) -> a -> b
$ TraceValue -> ST s TraceValue
forall (m :: * -> *) a. Monad m => a -> m a
return TraceValue
tr
) Map TVarId (SomeTVar s)
written
StmTxResult s a -> ST s (SimTrace c)
k0 (StmTxResult s a -> ST s (SimTrace c))
-> StmTxResult s a -> ST s (SimTrace c)
forall a b. (a -> b) -> a -> b
$ b
-> [SomeTVar s]
-> [SomeTVar s]
-> [SomeTVar s]
-> [Dynamic]
-> [ThreadLabel]
-> TVarId
-> StmTxResult s b
forall s a.
a
-> [SomeTVar s]
-> [SomeTVar s]
-> [SomeTVar s]
-> [Dynamic]
-> [ThreadLabel]
-> TVarId
-> StmTxResult s a
StmTxCommitted b
x ([SomeTVar s] -> [SomeTVar s]
forall a. [a] -> [a]
reverse [SomeTVar s]
writtenSeq)
[]
([SomeTVar s] -> [SomeTVar s]
forall a. [a] -> [a]
reverse [SomeTVar s]
createdSeq)
((TraceValue -> Maybe Dynamic) -> [TraceValue] -> [Dynamic]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (\TraceValue { Maybe tr
traceDynamic :: ()
traceDynamic :: Maybe tr
traceDynamic }
-> tr -> Dynamic
forall a. Typeable a => a -> Dynamic
toDyn (tr -> Dynamic) -> Maybe tr -> Maybe Dynamic
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe tr
traceDynamic)
([TraceValue] -> [Dynamic]) -> [TraceValue] -> [Dynamic]
forall a b. (a -> b) -> a -> b
$ [TraceValue]
ds [TraceValue] -> [TraceValue] -> [TraceValue]
forall a. [a] -> [a] -> [a]
++ [TraceValue]
ds')
((TraceValue -> Maybe ThreadLabel) -> [TraceValue] -> [ThreadLabel]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe TraceValue -> Maybe ThreadLabel
traceString ([TraceValue] -> [ThreadLabel]) -> [TraceValue] -> [ThreadLabel]
forall a b. (a -> b) -> a -> b
$ [TraceValue]
ds [TraceValue] -> [TraceValue] -> [TraceValue]
forall a. [a] -> [a] -> [a]
++ [TraceValue]
ds')
TVarId
nextVid
OrElseLeftFrame StmA s b
_b b -> StmA s b
k Map TVarId (SomeTVar s)
writtenOuter [SomeTVar s]
writtenOuterSeq [SomeTVar s]
createdOuterSeq StmStack s b a
ctl' -> do
!()
_ <- (SomeTVar s -> ST s ()) -> Map TVarId (SomeTVar s) -> ST s ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (\(SomeTVar TVar s a
tvar) -> TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
commitTVar TVar s a
tvar)
(Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s) -> Map TVarId (SomeTVar s)
forall k a b. Ord k => Map k a -> Map k b -> Map k a
Map.intersection Map TVarId (SomeTVar s)
written Map TVarId (SomeTVar s)
writtenOuter)
let written' :: Map TVarId (SomeTVar s)
written' = Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s) -> Map TVarId (SomeTVar s)
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union Map TVarId (SomeTVar s)
written Map TVarId (SomeTVar s)
writtenOuter
writtenSeq' :: [SomeTVar s]
writtenSeq' = (SomeTVar s -> Bool) -> [SomeTVar s] -> [SomeTVar s]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(SomeTVar TVar s a
tvar) ->
TVar s a -> TVarId
forall s a. TVar s a -> TVarId
tvarId TVar s a
tvar TVarId -> Map TVarId (SomeTVar s) -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.notMember` Map TVarId (SomeTVar s)
writtenOuter)
[SomeTVar s]
writtenSeq
[SomeTVar s] -> [SomeTVar s] -> [SomeTVar s]
forall a. [a] -> [a] -> [a]
++ [SomeTVar s]
writtenOuterSeq
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl' Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
written' [SomeTVar s]
writtenSeq' [SomeTVar s]
createdOuterSeq TVarId
nextVid (b -> StmA s b
k b
x)
OrElseRightFrame b -> StmA s b
k Map TVarId (SomeTVar s)
writtenOuter [SomeTVar s]
writtenOuterSeq [SomeTVar s]
createdOuterSeq StmStack s b a
ctl' -> do
!()
_ <- (SomeTVar s -> ST s ()) -> Map TVarId (SomeTVar s) -> ST s ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (\(SomeTVar TVar s a
tvar) -> TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
commitTVar TVar s a
tvar)
(Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s) -> Map TVarId (SomeTVar s)
forall k a b. Ord k => Map k a -> Map k b -> Map k a
Map.intersection Map TVarId (SomeTVar s)
written Map TVarId (SomeTVar s)
writtenOuter)
let written' :: Map TVarId (SomeTVar s)
written' = Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s) -> Map TVarId (SomeTVar s)
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union Map TVarId (SomeTVar s)
written Map TVarId (SomeTVar s)
writtenOuter
writtenSeq' :: [SomeTVar s]
writtenSeq' = (SomeTVar s -> Bool) -> [SomeTVar s] -> [SomeTVar s]
forall a. (a -> Bool) -> [a] -> [a]
filter (\(SomeTVar TVar s a
tvar) ->
TVar s a -> TVarId
forall s a. TVar s a -> TVarId
tvarId TVar s a
tvar TVarId -> Map TVarId (SomeTVar s) -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.notMember` Map TVarId (SomeTVar s)
writtenOuter)
[SomeTVar s]
writtenSeq
[SomeTVar s] -> [SomeTVar s] -> [SomeTVar s]
forall a. [a] -> [a] -> [a]
++ [SomeTVar s]
writtenOuterSeq
createdSeq' :: [SomeTVar s]
createdSeq' = [SomeTVar s]
createdSeq [SomeTVar s] -> [SomeTVar s] -> [SomeTVar s]
forall a. [a] -> [a] -> [a]
++ [SomeTVar s]
createdOuterSeq
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl' Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
written' [SomeTVar s]
writtenSeq' [SomeTVar s]
createdSeq' TVarId
nextVid (b -> StmA s b
k b
x)
ThrowStm SomeException
e ->
{-# SCC "execAtomically.go.ThrowStm" #-} do
!()
_ <- (SomeTVar s -> ST s ()) -> Map TVarId (SomeTVar s) -> ST s ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (\(SomeTVar TVar s a
tvar) -> TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
revertTVar TVar s a
tvar) Map TVarId (SomeTVar s)
written
StmTxResult s a -> ST s (SimTrace c)
k0 (StmTxResult s a -> ST s (SimTrace c))
-> StmTxResult s a -> ST s (SimTrace c)
forall a b. (a -> b) -> a -> b
$ [SomeTVar s] -> SomeException -> StmTxResult s a
forall s a. [SomeTVar s] -> SomeException -> StmTxResult s a
StmTxAborted [] (SomeException -> SomeException
forall e. Exception e => e -> SomeException
toException SomeException
e)
StmA s b
Retry ->
{-# SCC "execAtomically.go.Retry" #-}
case StmStack s b a
ctl of
StmStack s b a
AtomicallyFrame -> do
!()
_ <- (SomeTVar s -> ST s ()) -> Map TVarId (SomeTVar s) -> ST s ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (\(SomeTVar TVar s a
tvar) -> TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
revertTVar TVar s a
tvar) Map TVarId (SomeTVar s)
written
StmTxResult s a -> ST s (SimTrace c)
k0 (StmTxResult s a -> ST s (SimTrace c))
-> StmTxResult s a -> ST s (SimTrace c)
forall a b. (a -> b) -> a -> b
$! [SomeTVar s] -> StmTxResult s a
forall s a. [SomeTVar s] -> StmTxResult s a
StmTxBlocked ([SomeTVar s] -> StmTxResult s a)
-> [SomeTVar s] -> StmTxResult s a
forall a b. (a -> b) -> a -> b
$! (Map TVarId (SomeTVar s) -> [SomeTVar s]
forall k a. Map k a -> [a]
Map.elems Map TVarId (SomeTVar s)
read)
OrElseLeftFrame StmA s b
b b -> StmA s b
k Map TVarId (SomeTVar s)
writtenOuter [SomeTVar s]
writtenOuterSeq [SomeTVar s]
createdOuterSeq StmStack s b a
ctl' ->
{-# SCC "execAtomically.go.OrElseLeftFrame" #-} do
!()
_ <- (SomeTVar s -> ST s ()) -> Map TVarId (SomeTVar s) -> ST s ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (\(SomeTVar TVar s a
tvar) -> TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
revertTVar TVar s a
tvar) Map TVarId (SomeTVar s)
written
let ctl'' :: StmStack s b a
ctl'' = (b -> StmA s b)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> StmStack s b a
-> StmStack s b a
forall a s b c.
(a -> StmA s b)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> StmStack s b c
-> StmStack s a c
OrElseRightFrame b -> StmA s b
k Map TVarId (SomeTVar s)
writtenOuter [SomeTVar s]
writtenOuterSeq [SomeTVar s]
createdOuterSeq StmStack s b a
ctl'
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl'' Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
forall k a. Map k a
Map.empty [] [] TVarId
nextVid StmA s b
b
OrElseRightFrame b -> StmA s b
_k Map TVarId (SomeTVar s)
writtenOuter [SomeTVar s]
writtenOuterSeq [SomeTVar s]
createdOuterSeq StmStack s b a
ctl' ->
{-# SCC "execAtomically.go.OrElseRightFrame" #-} do
!()
_ <- (SomeTVar s -> ST s ()) -> Map TVarId (SomeTVar s) -> ST s ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (\(SomeTVar TVar s a
tvar) -> TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
revertTVar TVar s a
tvar) Map TVarId (SomeTVar s)
written
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl' Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
writtenOuter [SomeTVar s]
writtenOuterSeq [SomeTVar s]
createdOuterSeq TVarId
nextVid StmA s b
forall s b. StmA s b
Retry
OrElse StmA s a
a StmA s a
b a -> StmA s b
k ->
{-# SCC "execAtomically.go.OrElse" #-} do
let ctl' :: StmStack s a a
ctl' = StmA s a
-> (a -> StmA s b)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> StmStack s b a
-> StmStack s a a
forall s a b c.
StmA s a
-> (a -> StmA s b)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> StmStack s b c
-> StmStack s a c
OrElseLeftFrame StmA s a
b a -> StmA s b
k Map TVarId (SomeTVar s)
written [SomeTVar s]
writtenSeq [SomeTVar s]
createdSeq StmStack s b a
ctl
StmStack s a a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s a
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s a a
ctl' Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
forall k a. Map k a
Map.empty [] [] TVarId
nextVid StmA s a
a
NewTVar !Maybe ThreadLabel
mbLabel x
x TVar s x -> StmA s b
k ->
{-# SCC "execAtomically.go.NewTVar" #-} do
!TVar s x
v <- TVarId -> Maybe ThreadLabel -> x -> ST s (TVar s x)
forall a s. TVarId -> Maybe ThreadLabel -> a -> ST s (TVar s a)
execNewTVar TVarId
nextVid Maybe ThreadLabel
mbLabel x
x
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
written [SomeTVar s]
writtenSeq (TVar s x -> SomeTVar s
forall s a. TVar s a -> SomeTVar s
SomeTVar TVar s x
v SomeTVar s -> [SomeTVar s] -> [SomeTVar s]
forall a. a -> [a] -> [a]
: [SomeTVar s]
createdSeq) (TVarId -> TVarId
forall a. Enum a => a -> a
succ TVarId
nextVid) (TVar s x -> StmA s b
k TVar s x
v)
LabelTVar !ThreadLabel
label TVar s a
tvar StmA s b
k ->
{-# SCC "execAtomically.go.LabelTVar" #-} do
!()
_ <- STRef s (Maybe ThreadLabel) -> Maybe ThreadLabel -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef (TVar s a -> STRef s (Maybe ThreadLabel)
forall s a. TVar s a -> STRef s (Maybe ThreadLabel)
tvarLabel TVar s a
tvar) (Maybe ThreadLabel -> ST s ()) -> Maybe ThreadLabel -> ST s ()
forall a b. (a -> b) -> a -> b
$! (ThreadLabel -> Maybe ThreadLabel
forall a. a -> Maybe a
Just ThreadLabel
label)
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
written [SomeTVar s]
writtenSeq [SomeTVar s]
createdSeq TVarId
nextVid StmA s b
k
TraceTVar TVar s a
tvar Maybe a -> a -> ST s TraceValue
f StmA s b
k ->
{-# SCC "execAtomically.go.TraceTVar" #-} do
!()
_ <- STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
-> Maybe (Maybe a -> a -> ST s TraceValue) -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef (TVar s a -> STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
forall s a.
TVar s a -> STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
tvarTrace TVar s a
tvar) ((Maybe a -> a -> ST s TraceValue)
-> Maybe (Maybe a -> a -> ST s TraceValue)
forall a. a -> Maybe a
Just Maybe a -> a -> ST s TraceValue
f)
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
written [SomeTVar s]
writtenSeq [SomeTVar s]
createdSeq TVarId
nextVid StmA s b
k
ReadTVar TVar s a
v a -> StmA s b
k
| TVar s a -> TVarId
forall s a. TVar s a -> TVarId
tvarId TVar s a
v TVarId -> Map TVarId (SomeTVar s) -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map TVarId (SomeTVar s)
read ->
{-# SCC "execAtomically.go.ReadTVar" #-} do
a
x <- TVar s a -> ST s a
forall s a. TVar s a -> ST s a
execReadTVar TVar s a
v
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
written [SomeTVar s]
writtenSeq [SomeTVar s]
createdSeq TVarId
nextVid (a -> StmA s b
k a
x)
| Bool
otherwise ->
{-# SCC "execAtomically.go.ReadTVar" #-} do
a
x <- TVar s a -> ST s a
forall s a. TVar s a -> ST s a
execReadTVar TVar s a
v
let read' :: Map TVarId (SomeTVar s)
read' = TVarId
-> SomeTVar s -> Map TVarId (SomeTVar s) -> Map TVarId (SomeTVar s)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (TVar s a -> TVarId
forall s a. TVar s a -> TVarId
tvarId TVar s a
v) (TVar s a -> SomeTVar s
forall s a. TVar s a -> SomeTVar s
SomeTVar TVar s a
v) Map TVarId (SomeTVar s)
read
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl Map TVarId (SomeTVar s)
read' Map TVarId (SomeTVar s)
written [SomeTVar s]
writtenSeq [SomeTVar s]
createdSeq TVarId
nextVid (a -> StmA s b
k a
x)
WriteTVar TVar s a
v a
x StmA s b
k
| TVar s a -> TVarId
forall s a. TVar s a -> TVarId
tvarId TVar s a
v TVarId -> Map TVarId (SomeTVar s) -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map TVarId (SomeTVar s)
written ->
{-# SCC "execAtomically.go.WriteTVar" #-} do
!()
_ <- TVar s a -> a -> ST s ()
forall s a. TVar s a -> a -> ST s ()
execWriteTVar TVar s a
v a
x
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
written [SomeTVar s]
writtenSeq [SomeTVar s]
createdSeq TVarId
nextVid StmA s b
k
| Bool
otherwise ->
{-# SCC "execAtomically.go.WriteTVar" #-} do
!()
_ <- TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
saveTVar TVar s a
v
!()
_ <- TVar s a -> a -> ST s ()
forall s a. TVar s a -> a -> ST s ()
execWriteTVar TVar s a
v a
x
let written' :: Map TVarId (SomeTVar s)
written' = TVarId
-> SomeTVar s -> Map TVarId (SomeTVar s) -> Map TVarId (SomeTVar s)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (TVar s a -> TVarId
forall s a. TVar s a -> TVarId
tvarId TVar s a
v) (TVar s a -> SomeTVar s
forall s a. TVar s a -> SomeTVar s
SomeTVar TVar s a
v) Map TVarId (SomeTVar s)
written
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
written' (TVar s a -> SomeTVar s
forall s a. TVar s a -> SomeTVar s
SomeTVar TVar s a
v SomeTVar s -> [SomeTVar s] -> [SomeTVar s]
forall a. a -> [a] -> [a]
: [SomeTVar s]
writtenSeq) [SomeTVar s]
createdSeq TVarId
nextVid StmA s b
k
SayStm ThreadLabel
msg StmA s b
k ->
{-# SCC "execAtomically.go.SayStm" #-} do
SimTrace c
trace <- StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
written [SomeTVar s]
writtenSeq [SomeTVar s]
createdSeq TVarId
nextVid StmA s b
k
SimTrace c -> ST s (SimTrace c)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace c -> ST s (SimTrace c))
-> SimTrace c -> ST s (SimTrace c)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace c
-> SimTrace c
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (ThreadLabel -> SimEventType
EventSay ThreadLabel
msg) SimTrace c
trace
OutputStm Dynamic
x StmA s b
k ->
{-# SCC "execAtomically.go.OutputStm" #-} do
SimTrace c
trace <- StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
forall b.
StmStack s b a
-> Map TVarId (SomeTVar s)
-> Map TVarId (SomeTVar s)
-> [SomeTVar s]
-> [SomeTVar s]
-> TVarId
-> StmA s b
-> ST s (SimTrace c)
go StmStack s b a
ctl Map TVarId (SomeTVar s)
read Map TVarId (SomeTVar s)
written [SomeTVar s]
writtenSeq [SomeTVar s]
createdSeq TVarId
nextVid StmA s b
k
SimTrace c -> ST s (SimTrace c)
forall (m :: * -> *) a. Monad m => a -> m a
return (SimTrace c -> ST s (SimTrace c))
-> SimTrace c -> ST s (SimTrace c)
forall a b. (a -> b) -> a -> b
$ Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace c
-> SimTrace c
forall a.
Time
-> ThreadId
-> Maybe ThreadLabel
-> SimEventType
-> SimTrace a
-> SimTrace a
SimTrace Time
time ThreadId
tid Maybe ThreadLabel
tlbl (Dynamic -> SimEventType
EventLog Dynamic
x) SimTrace c
trace
where
localInvariant :: Bool
localInvariant =
Map TVarId (SomeTVar s) -> Set TVarId
forall k a. Map k a -> Set k
Map.keysSet Map TVarId (SomeTVar s)
written
Set TVarId -> Set TVarId -> Bool
forall a. Eq a => a -> a -> Bool
== [TVarId] -> Set TVarId
forall a. Ord a => [a] -> Set a
Set.fromList [ TVar s a -> TVarId
forall s a. TVar s a -> TVarId
tvarId TVar s a
tvar | SomeTVar TVar s a
tvar <- [SomeTVar s]
writtenSeq ]
execAtomically' :: StmA s () -> ST s [SomeTVar s]
execAtomically' :: StmA s () -> ST s [SomeTVar s]
execAtomically' = Map TVarId (SomeTVar s) -> StmA s () -> ST s [SomeTVar s]
forall s. Map TVarId (SomeTVar s) -> StmA s () -> ST s [SomeTVar s]
go Map TVarId (SomeTVar s)
forall k a. Map k a
Map.empty
where
go :: Map TVarId (SomeTVar s)
-> StmA s ()
-> ST s [SomeTVar s]
go :: Map TVarId (SomeTVar s) -> StmA s () -> ST s [SomeTVar s]
go !Map TVarId (SomeTVar s)
written StmA s ()
action = case StmA s ()
action of
ReturnStm () -> do
!()
_ <- (SomeTVar s -> ST s ()) -> Map TVarId (SomeTVar s) -> ST s ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (\(SomeTVar TVar s a
tvar) -> TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
commitTVar TVar s a
tvar) Map TVarId (SomeTVar s)
written
[SomeTVar s] -> ST s [SomeTVar s]
forall (m :: * -> *) a. Monad m => a -> m a
return (Map TVarId (SomeTVar s) -> [SomeTVar s]
forall k a. Map k a -> [a]
Map.elems Map TVarId (SomeTVar s)
written)
ReadTVar TVar s a
v a -> StmA s ()
k -> do
a
x <- TVar s a -> ST s a
forall s a. TVar s a -> ST s a
execReadTVar TVar s a
v
Map TVarId (SomeTVar s) -> StmA s () -> ST s [SomeTVar s]
forall s. Map TVarId (SomeTVar s) -> StmA s () -> ST s [SomeTVar s]
go Map TVarId (SomeTVar s)
written (a -> StmA s ()
k a
x)
WriteTVar TVar s a
v a
x StmA s ()
k
| TVar s a -> TVarId
forall s a. TVar s a -> TVarId
tvarId TVar s a
v TVarId -> Map TVarId (SomeTVar s) -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Map.member` Map TVarId (SomeTVar s)
written -> do
!()
_ <- TVar s a -> a -> ST s ()
forall s a. TVar s a -> a -> ST s ()
execWriteTVar TVar s a
v a
x
Map TVarId (SomeTVar s) -> StmA s () -> ST s [SomeTVar s]
forall s. Map TVarId (SomeTVar s) -> StmA s () -> ST s [SomeTVar s]
go Map TVarId (SomeTVar s)
written StmA s ()
k
| Bool
otherwise -> do
!()
_ <- TVar s a -> ST s ()
forall s a. TVar s a -> ST s ()
saveTVar TVar s a
v
!()
_ <- TVar s a -> a -> ST s ()
forall s a. TVar s a -> a -> ST s ()
execWriteTVar TVar s a
v a
x
let written' :: Map TVarId (SomeTVar s)
written' = TVarId
-> SomeTVar s -> Map TVarId (SomeTVar s) -> Map TVarId (SomeTVar s)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert (TVar s a -> TVarId
forall s a. TVar s a -> TVarId
tvarId TVar s a
v) (TVar s a -> SomeTVar s
forall s a. TVar s a -> SomeTVar s
SomeTVar TVar s a
v) Map TVarId (SomeTVar s)
written
Map TVarId (SomeTVar s) -> StmA s () -> ST s [SomeTVar s]
forall s. Map TVarId (SomeTVar s) -> StmA s () -> ST s [SomeTVar s]
go Map TVarId (SomeTVar s)
written' StmA s ()
k
StmA s ()
_ -> ThreadLabel -> ST s [SomeTVar s]
forall a. (?callStack::CallStack) => ThreadLabel -> a
error ThreadLabel
"execAtomically': only for special case of reads and writes"
execNewTVar :: TVarId -> Maybe String -> a -> ST s (TVar s a)
execNewTVar :: TVarId -> Maybe ThreadLabel -> a -> ST s (TVar s a)
execNewTVar TVarId
nextVid !Maybe ThreadLabel
mbLabel a
x = do
!STRef s (Maybe ThreadLabel)
tvarLabel <- Maybe ThreadLabel -> ST s (STRef s (Maybe ThreadLabel))
forall a s. a -> ST s (STRef s a)
newSTRef Maybe ThreadLabel
mbLabel
!STRef s a
tvarCurrent <- a -> ST s (STRef s a)
forall a s. a -> ST s (STRef s a)
newSTRef a
x
!STRef s [a]
tvarUndo <- [a] -> ST s (STRef s [a])
forall a s. a -> ST s (STRef s a)
newSTRef ([a] -> ST s (STRef s [a])) -> [a] -> ST s (STRef s [a])
forall a b. (a -> b) -> a -> b
$! []
!STRef s ([ThreadId], Set ThreadId)
tvarBlocked <- ([ThreadId], Set ThreadId)
-> ST s (STRef s ([ThreadId], Set ThreadId))
forall a s. a -> ST s (STRef s a)
newSTRef ([], Set ThreadId
forall a. Set a
Set.empty)
!STRef s VectorClock
tvarVClock <- VectorClock -> ST s (STRef s VectorClock)
forall a s. a -> ST s (STRef s a)
newSTRef (VectorClock -> ST s (STRef s VectorClock))
-> VectorClock -> ST s (STRef s VectorClock)
forall a b. (a -> b) -> a -> b
$! Map ThreadId Int -> VectorClock
VectorClock Map ThreadId Int
forall k a. Map k a
Map.empty
!STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
tvarTrace <- Maybe (Maybe a -> a -> ST s TraceValue)
-> ST s (STRef s (Maybe (Maybe a -> a -> ST s TraceValue)))
forall a s. a -> ST s (STRef s a)
newSTRef (Maybe (Maybe a -> a -> ST s TraceValue)
-> ST s (STRef s (Maybe (Maybe a -> a -> ST s TraceValue))))
-> Maybe (Maybe a -> a -> ST s TraceValue)
-> ST s (STRef s (Maybe (Maybe a -> a -> ST s TraceValue)))
forall a b. (a -> b) -> a -> b
$! Maybe (Maybe a -> a -> ST s TraceValue)
forall a. Maybe a
Nothing
TVar s a -> ST s (TVar s a)
forall (m :: * -> *) a. Monad m => a -> m a
return TVar :: forall s a.
TVarId
-> STRef s (Maybe ThreadLabel)
-> STRef s a
-> STRef s [a]
-> STRef s ([ThreadId], Set ThreadId)
-> STRef s VectorClock
-> STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
-> TVar s a
TVar {tvarId :: TVarId
tvarId = TVarId
nextVid, STRef s (Maybe ThreadLabel)
tvarLabel :: STRef s (Maybe ThreadLabel)
tvarLabel :: STRef s (Maybe ThreadLabel)
tvarLabel,
STRef s a
tvarCurrent :: STRef s a
tvarCurrent :: STRef s a
tvarCurrent, STRef s [a]
tvarUndo :: STRef s [a]
tvarUndo :: STRef s [a]
tvarUndo, STRef s ([ThreadId], Set ThreadId)
tvarBlocked :: STRef s ([ThreadId], Set ThreadId)
tvarBlocked :: STRef s ([ThreadId], Set ThreadId)
tvarBlocked, STRef s VectorClock
tvarVClock :: STRef s VectorClock
tvarVClock :: STRef s VectorClock
tvarVClock,
STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
tvarTrace :: STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
tvarTrace :: STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
tvarTrace}
execReadTVar :: TVar s a -> ST s a
execReadTVar :: TVar s a -> ST s a
execReadTVar TVar{STRef s a
tvarCurrent :: STRef s a
tvarCurrent :: forall s a. TVar s a -> STRef s a
tvarCurrent} = STRef s a -> ST s a
forall s a. STRef s a -> ST s a
readSTRef STRef s a
tvarCurrent
{-# INLINE execReadTVar #-}
execWriteTVar :: TVar s a -> a -> ST s ()
execWriteTVar :: TVar s a -> a -> ST s ()
execWriteTVar TVar{STRef s a
tvarCurrent :: STRef s a
tvarCurrent :: forall s a. TVar s a -> STRef s a
tvarCurrent} = STRef s a -> a -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s a
tvarCurrent
{-# INLINE execWriteTVar #-}
saveTVar :: TVar s a -> ST s ()
saveTVar :: TVar s a -> ST s ()
saveTVar TVar{STRef s a
tvarCurrent :: STRef s a
tvarCurrent :: forall s a. TVar s a -> STRef s a
tvarCurrent, STRef s [a]
tvarUndo :: STRef s [a]
tvarUndo :: forall s a. TVar s a -> STRef s [a]
tvarUndo} = do
a
v <- STRef s a -> ST s a
forall s a. STRef s a -> ST s a
readSTRef STRef s a
tvarCurrent
[a]
vs <- STRef s [a] -> ST s [a]
forall s a. STRef s a -> ST s a
readSTRef STRef s [a]
tvarUndo
!()
_ <- STRef s [a] -> [a] -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s [a]
tvarUndo (a
va -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
vs)
() -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
revertTVar :: TVar s a -> ST s ()
revertTVar :: TVar s a -> ST s ()
revertTVar TVar{STRef s a
tvarCurrent :: STRef s a
tvarCurrent :: forall s a. TVar s a -> STRef s a
tvarCurrent, STRef s [a]
tvarUndo :: STRef s [a]
tvarUndo :: forall s a. TVar s a -> STRef s [a]
tvarUndo} = do
(a
v:[a]
vs) <- STRef s [a] -> ST s [a]
forall s a. STRef s a -> ST s a
readSTRef STRef s [a]
tvarUndo
!()
_ <- STRef s a -> a -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s a
tvarCurrent a
v
!()
_ <- STRef s [a] -> [a] -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s [a]
tvarUndo [a]
vs
() -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
{-# INLINE revertTVar #-}
commitTVar :: TVar s a -> ST s ()
commitTVar :: TVar s a -> ST s ()
commitTVar TVar{STRef s [a]
tvarUndo :: STRef s [a]
tvarUndo :: forall s a. TVar s a -> STRef s [a]
tvarUndo} = do
(a
_:[a]
vs) <- STRef s [a] -> ST s [a]
forall s a. STRef s a -> ST s a
readSTRef STRef s [a]
tvarUndo
!()
_ <- STRef s [a] -> [a] -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s [a]
tvarUndo [a]
vs
() -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
{-# INLINE commitTVar #-}
readTVarUndos :: TVar s a -> ST s [a]
readTVarUndos :: TVar s a -> ST s [a]
readTVarUndos TVar{STRef s [a]
tvarUndo :: STRef s [a]
tvarUndo :: forall s a. TVar s a -> STRef s [a]
tvarUndo} = STRef s [a] -> ST s [a]
forall s a. STRef s a -> ST s a
readSTRef STRef s [a]
tvarUndo
traceTVarST :: TVar s a
-> Bool
-> ST s TraceValue
traceTVarST :: TVar s a -> Bool -> ST s TraceValue
traceTVarST TVar{STRef s a
tvarCurrent :: STRef s a
tvarCurrent :: forall s a. TVar s a -> STRef s a
tvarCurrent, STRef s [a]
tvarUndo :: STRef s [a]
tvarUndo :: forall s a. TVar s a -> STRef s [a]
tvarUndo, STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
tvarTrace :: STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
tvarTrace :: forall s a.
TVar s a -> STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
tvarTrace} Bool
new = do
Maybe (Maybe a -> a -> ST s TraceValue)
mf <- STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
-> ST s (Maybe (Maybe a -> a -> ST s TraceValue))
forall s a. STRef s a -> ST s a
readSTRef STRef s (Maybe (Maybe a -> a -> ST s TraceValue))
tvarTrace
case Maybe (Maybe a -> a -> ST s TraceValue)
mf of
Maybe (Maybe a -> a -> ST s TraceValue)
Nothing -> TraceValue -> ST s TraceValue
forall (m :: * -> *) a. Monad m => a -> m a
return TraceValue :: forall tr.
Typeable tr =>
Maybe tr -> Maybe ThreadLabel -> TraceValue
TraceValue { traceDynamic :: Maybe ()
traceDynamic = (Maybe ()
forall a. Maybe a
Nothing :: Maybe ())
, traceString :: Maybe ThreadLabel
traceString = Maybe ThreadLabel
forall a. Maybe a
Nothing }
Just Maybe a -> a -> ST s TraceValue
f -> do
[a]
vs <- STRef s [a] -> ST s [a]
forall s a. STRef s a -> ST s a
readSTRef STRef s [a]
tvarUndo
a
v <- STRef s a -> ST s a
forall s a. STRef s a -> ST s a
readSTRef STRef s a
tvarCurrent
case (Bool
new, [a]
vs) of
(Bool
True, [a]
_) -> Maybe a -> a -> ST s TraceValue
f Maybe a
forall a. Maybe a
Nothing a
v
(Bool
_, a
_:[a]
_) -> Maybe a -> a -> ST s TraceValue
f (a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> a -> Maybe a
forall a b. (a -> b) -> a -> b
$ [a] -> a
forall a. [a] -> a
last [a]
vs) a
v
(Bool, [a])
_ -> ThreadLabel -> ST s TraceValue
forall a. (?callStack::CallStack) => ThreadLabel -> a
error ThreadLabel
"traceTVarST: unexpected tvar state"
readTVarBlockedThreads :: TVar s a -> ST s [ThreadId]
readTVarBlockedThreads :: TVar s a -> ST s [ThreadId]
readTVarBlockedThreads TVar{STRef s ([ThreadId], Set ThreadId)
tvarBlocked :: STRef s ([ThreadId], Set ThreadId)
tvarBlocked :: forall s a. TVar s a -> STRef s ([ThreadId], Set ThreadId)
tvarBlocked} = ([ThreadId], Set ThreadId) -> [ThreadId]
forall a b. (a, b) -> a
fst (([ThreadId], Set ThreadId) -> [ThreadId])
-> ST s ([ThreadId], Set ThreadId) -> ST s [ThreadId]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> STRef s ([ThreadId], Set ThreadId)
-> ST s ([ThreadId], Set ThreadId)
forall s a. STRef s a -> ST s a
readSTRef STRef s ([ThreadId], Set ThreadId)
tvarBlocked
blockThreadOnTVar :: ThreadId -> TVar s a -> ST s ()
blockThreadOnTVar :: ThreadId -> TVar s a -> ST s ()
blockThreadOnTVar ThreadId
tid TVar{STRef s ([ThreadId], Set ThreadId)
tvarBlocked :: STRef s ([ThreadId], Set ThreadId)
tvarBlocked :: forall s a. TVar s a -> STRef s ([ThreadId], Set ThreadId)
tvarBlocked} = do
([ThreadId]
tids, Set ThreadId
tidsSet) <- STRef s ([ThreadId], Set ThreadId)
-> ST s ([ThreadId], Set ThreadId)
forall s a. STRef s a -> ST s a
readSTRef STRef s ([ThreadId], Set ThreadId)
tvarBlocked
Bool -> ST s () -> ST s ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ThreadId
tid ThreadId -> Set ThreadId -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.notMember` Set ThreadId
tidsSet) (ST s () -> ST s ()) -> ST s () -> ST s ()
forall a b. (a -> b) -> a -> b
$ do
let !tids' :: [ThreadId]
tids' = ThreadId
tid ThreadId -> [ThreadId] -> [ThreadId]
forall a. a -> [a] -> [a]
: [ThreadId]
tids
!tidsSet' :: Set ThreadId
tidsSet' = ThreadId -> Set ThreadId -> Set ThreadId
forall a. Ord a => a -> Set a -> Set a
Set.insert ThreadId
tid Set ThreadId
tidsSet
!()
_ <- STRef s ([ThreadId], Set ThreadId)
-> ([ThreadId], Set ThreadId) -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s ([ThreadId], Set ThreadId)
tvarBlocked ([ThreadId]
tids', Set ThreadId
tidsSet')
() -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
unblockAllThreadsFromTVar :: TVar s a -> ST s ()
unblockAllThreadsFromTVar :: TVar s a -> ST s ()
unblockAllThreadsFromTVar TVar{STRef s ([ThreadId], Set ThreadId)
tvarBlocked :: STRef s ([ThreadId], Set ThreadId)
tvarBlocked :: forall s a. TVar s a -> STRef s ([ThreadId], Set ThreadId)
tvarBlocked} = do
!()
_ <- STRef s ([ThreadId], Set ThreadId)
-> ([ThreadId], Set ThreadId) -> ST s ()
forall s a. STRef s a -> a -> ST s ()
writeSTRef STRef s ([ThreadId], Set ThreadId)
tvarBlocked ([], Set ThreadId
forall a. Set a
Set.empty)
() -> ST s ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
threadsUnblockedByWrites :: [SomeTVar s]
-> ST s ([ThreadId], Map ThreadId (Set (Labelled TVarId)))
threadsUnblockedByWrites :: [SomeTVar s]
-> ST s ([ThreadId], Map ThreadId (Set (Labelled TVarId)))
threadsUnblockedByWrites [SomeTVar s]
written = do
![(Labelled TVarId, [ThreadId])]
tidss <- [ST s (Labelled TVarId, [ThreadId])]
-> ST s [(Labelled TVarId, [ThreadId])]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence
[ (,) (Labelled TVarId -> [ThreadId] -> (Labelled TVarId, [ThreadId]))
-> ST s (Labelled TVarId)
-> ST s ([ThreadId] -> (Labelled TVarId, [ThreadId]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TVar s a -> ST s (Labelled TVarId)
forall s a. TVar s a -> ST s (Labelled TVarId)
labelledTVarId TVar s a
tvar ST s ([ThreadId] -> (Labelled TVarId, [ThreadId]))
-> ST s [ThreadId] -> ST s (Labelled TVarId, [ThreadId])
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> TVar s a -> ST s [ThreadId]
forall s a. TVar s a -> ST s [ThreadId]
readTVarBlockedThreads TVar s a
tvar
| SomeTVar TVar s a
tvar <- [SomeTVar s]
written ]
let !wakeup :: [ThreadId]
wakeup = [ThreadId] -> [ThreadId]
forall a. Ord a => [a] -> [a]
ordNub [ ThreadId
tid | (Labelled TVarId
_vid, [ThreadId]
tids) <- [(Labelled TVarId, [ThreadId])]
tidss, ThreadId
tid <- [ThreadId] -> [ThreadId]
forall a. [a] -> [a]
reverse [ThreadId]
tids ]
wokeby :: Map ThreadId (Set (Labelled TVarId))
wokeby = (Set (Labelled TVarId)
-> Set (Labelled TVarId) -> Set (Labelled TVarId))
-> [(ThreadId, Set (Labelled TVarId))]
-> Map ThreadId (Set (Labelled TVarId))
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
Map.fromListWith Set (Labelled TVarId)
-> Set (Labelled TVarId) -> Set (Labelled TVarId)
forall a. Ord a => Set a -> Set a -> Set a
Set.union
[ (ThreadId
tid, Labelled TVarId -> Set (Labelled TVarId)
forall a. a -> Set a
Set.singleton Labelled TVarId
vid)
| (Labelled TVarId
vid, [ThreadId]
tids) <- [(Labelled TVarId, [ThreadId])]
tidss
, ThreadId
tid <- [ThreadId]
tids ]
([ThreadId], Map ThreadId (Set (Labelled TVarId)))
-> ST s ([ThreadId], Map ThreadId (Set (Labelled TVarId)))
forall (m :: * -> *) a. Monad m => a -> m a
return ([ThreadId]
wakeup, Map ThreadId (Set (Labelled TVarId))
wokeby)
ordNub :: Ord a => [a] -> [a]
ordNub :: [a] -> [a]
ordNub = Set a -> [a] -> [a]
forall a. Ord a => Set a -> [a] -> [a]
go Set a
forall a. Set a
Set.empty
where
go :: Set a -> [a] -> [a]
go !Set a
_ [] = []
go !Set a
s (a
x:[a]
xs)
| a
x a -> Set a -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set a
s = Set a -> [a] -> [a]
go Set a
s [a]
xs
| Bool
otherwise = a
x a -> [a] -> [a]
forall a. a -> [a] -> [a]
: Set a -> [a] -> [a]
go (a -> Set a -> Set a
forall a. Ord a => a -> Set a -> Set a
Set.insert a
x Set a
s) [a]
xs
{-# INLINE ordNub #-}