{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE NumericUnderscores #-}
{-# OPTIONS_GHC -Wno-orphans #-}
module GHC.Debug.ParTrace ( traceParFromM, tracePar, TraceFunctionsIO(..), ClosurePtrWithInfo(..) ) where
import GHC.Debug.Types
import GHC.Debug.Client.Query
import qualified Data.IntMap as IM
import Data.Array.BitArray.IO hiding (map)
import Control.Monad.Reader
import Data.Word
import GHC.Debug.Client.Monad.Simple
import GHC.Debug.Client.Monad.Class
import Control.Concurrent.Async
import Data.IORef
import Control.Exception.Base
import Control.Concurrent.STM
threads :: Int
threads :: Int
threads = Int
64
type InChan = TChan
type OutChan = TChan
data ThreadState s = ThreadState (IM.IntMap (IM.IntMap (IOBitArray Word16))) (IORef s)
newtype ThreadInfo a = ThreadInfo (InChan (ClosurePtrWithInfo a))
data ClosurePtrWithInfo a = ClosurePtrWithInfo !a !ClosurePtr
type ThreadMap a = IM.IntMap (ThreadInfo a)
newtype TraceState a = TraceState { forall a. TraceState a -> ThreadMap a
visited :: (ThreadMap a) }
getKeyTriple :: ClosurePtr -> (Int, Int, Word16)
getKeyTriple :: ClosurePtr -> (Int, Int, Word16)
getKeyTriple ClosurePtr
cp =
let BlockPtr Word64
raw_bk = ClosurePtr -> BlockPtr
applyBlockMask ClosurePtr
cp
bk :: Int
bk = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
raw_bk forall a. Integral a => a -> a -> a
`div` Int
8
offset :: Word64
offset = ClosurePtr -> Word64
getBlockOffset ClosurePtr
cp forall a. Integral a => a -> a -> a
`div` Word64
8
BlockPtr Word64
raw_mbk = ClosurePtr -> BlockPtr
applyMBlockMask ClosurePtr
cp
mbk :: Int
mbk = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
raw_mbk forall a. Integral a => a -> a -> a
`div` Int
8
in (Int
mbk, Int
bk, forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
offset)
getMBlockKey :: ClosurePtr -> Int
getMBlockKey :: ClosurePtr -> Int
getMBlockKey ClosurePtr
cp =
let BlockPtr Word64
raw_bk = ClosurePtr -> BlockPtr
applyMBlockMask ClosurePtr
cp
in (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
raw_bk forall a. Integral a => a -> a -> a
`div` forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
mblockMask forall a. Integral a => a -> a -> a
`div` Int
4) forall a. Integral a => a -> a -> a
`mod` Int
threads
sendToChan :: TraceState a -> ClosurePtrWithInfo a -> DebugM ()
sendToChan :: forall a. TraceState a -> ClosurePtrWithInfo a -> DebugM ()
sendToChan TraceState a
ts cpi :: ClosurePtrWithInfo a
cpi@(ClosurePtrWithInfo a
_ ClosurePtr
cp) = forall a. ReaderT Debuggee IO a -> DebugM a
DebugM forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ do
let st :: ThreadMap a
st = forall a. TraceState a -> ThreadMap a
visited TraceState a
ts
mkey :: Int
mkey = ClosurePtr -> Int
getMBlockKey ClosurePtr
cp
case forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
mkey ThreadMap a
st of
Maybe (ThreadInfo a)
Nothing -> forall a. HasCallStack => [Char] -> a
error forall a b. (a -> b) -> a -> b
$ [Char]
"Not enough chans:" forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
mkey forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
threads
Just (ThreadInfo InChan (ClosurePtrWithInfo a)
ic) -> forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a. TChan a -> a -> STM ()
writeTChan InChan (ClosurePtrWithInfo a)
ic ClosurePtrWithInfo a
cpi
initThread :: Monoid s =>
Int
-> TraceFunctionsIO a s
-> DebugM (ThreadInfo a, STM Bool, (ClosurePtrWithInfo a -> DebugM ()) -> DebugM (Async s))
initThread :: forall s a.
Monoid s =>
Int
-> TraceFunctionsIO a s
-> DebugM
(ThreadInfo a, STM Bool,
(ClosurePtrWithInfo a -> DebugM ()) -> DebugM (Async s))
initThread Int
n TraceFunctionsIO a s
k = forall a. ReaderT Debuggee IO a -> DebugM a
DebugM forall a b. (a -> b) -> a -> b
$ do
Debuggee
e <- forall r (m :: * -> *). MonadReader r m => m r
ask
TChan (ClosurePtrWithInfo a)
ic <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. IO (TChan a)
newTChanIO
let oc :: TChan (ClosurePtrWithInfo a)
oc = TChan (ClosurePtrWithInfo a)
ic
IORef s
ref <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (IORef a)
newIORef forall a. Monoid a => a
mempty
TVar Bool
worker_active <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (TVar a)
newTVarIO Bool
True
let start :: (ClosurePtrWithInfo a -> DebugM ()) -> m (Async s)
start ClosurePtrWithInfo a -> DebugM ()
go = forall (m :: * -> *) a. DebugMonad m => IO a -> m a
unsafeLiftIO forall a b. (a -> b) -> a -> b
$ forall a. IO a -> IO (Async a)
async forall a b. (a -> b) -> a -> b
$ forall a. Debuggee -> DebugM a -> IO a
runSimple Debuggee
e forall a b. (a -> b) -> a -> b
$ forall s a.
Monoid s =>
Int
-> TraceFunctionsIO a s
-> TVar Bool
-> IORef s
-> (ClosurePtrWithInfo a -> DebugM ())
-> OutChan (ClosurePtrWithInfo a)
-> DebugM s
workerThread Int
n TraceFunctionsIO a s
k TVar Bool
worker_active IORef s
ref ClosurePtrWithInfo a -> DebugM ()
go TChan (ClosurePtrWithInfo a)
oc
finished :: STM Bool
finished = do
Bool
active <- Bool -> Bool
not forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. TVar a -> STM a
readTVar TVar Bool
worker_active
Bool
empty <- forall a. TChan a -> STM Bool
isEmptyTChan TChan (ClosurePtrWithInfo a)
ic
return (Bool
active Bool -> Bool -> Bool
&& Bool
empty)
forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. InChan (ClosurePtrWithInfo a) -> ThreadInfo a
ThreadInfo TChan (ClosurePtrWithInfo a)
ic, STM Bool
finished, forall {m :: * -> *}.
DebugMonad m =>
(ClosurePtrWithInfo a -> DebugM ()) -> m (Async s)
start)
workerThread :: forall s a . Monoid s => Int -> TraceFunctionsIO a s -> TVar Bool -> IORef s -> (ClosurePtrWithInfo a -> DebugM ()) -> OutChan (ClosurePtrWithInfo a) -> DebugM s
workerThread :: forall s a.
Monoid s =>
Int
-> TraceFunctionsIO a s
-> TVar Bool
-> IORef s
-> (ClosurePtrWithInfo a -> DebugM ())
-> OutChan (ClosurePtrWithInfo a)
-> DebugM s
workerThread Int
n TraceFunctionsIO a s
k TVar Bool
worker_active IORef s
ref ClosurePtrWithInfo a -> DebugM ()
go OutChan (ClosurePtrWithInfo a)
oc = forall a. ReaderT Debuggee IO a -> DebugM a
DebugM forall a b. (a -> b) -> a -> b
$ do
Debuggee
d <- forall r (m :: * -> *). MonadReader r m => m r
ask
IORef (ThreadState s)
r <- forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. a -> IO (IORef a)
newIORef (forall s.
IntMap (IntMap (IOBitArray Word16)) -> IORef s -> ThreadState s
ThreadState forall a. IntMap a
IM.empty IORef s
ref)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ forall a. Debuggee -> DebugM a -> IO a
runSimple Debuggee
d (forall {s}. IORef (ThreadState s) -> DebugM s
loop IORef (ThreadState s)
r)
where
loop :: IORef (ThreadState s) -> DebugM s
loop IORef (ThreadState s)
r = do
Either AsyncCancelled (ClosurePtrWithInfo a)
mcp <- forall (m :: * -> *) a. DebugMonad m => IO a -> m a
unsafeLiftIO forall a b. (a -> b) -> a -> b
$ forall e a. Exception e => IO a -> IO (Either e a)
try forall a b. (a -> b) -> a -> b
$ do
forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ forall a. TVar a -> a -> STM ()
writeTVar TVar Bool
worker_active Bool
False
forall a. STM a -> IO a
atomically forall a b. (a -> b) -> a -> b
$ do
ClosurePtrWithInfo a
v <- forall a. TChan a -> STM a
readTChan OutChan (ClosurePtrWithInfo a)
oc
forall a. TVar a -> a -> STM ()
writeTVar TVar Bool
worker_active Bool
True
return ClosurePtrWithInfo a
v
case Either AsyncCancelled (ClosurePtrWithInfo a)
mcp of
Left AsyncCancelled
AsyncCancelled -> do
forall (m :: * -> *) a. DebugMonad m => IO a -> m a
unsafeLiftIO forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
readIORef IORef s
ref
Right ClosurePtrWithInfo a
cpi -> forall {s}.
IORef (ThreadState s) -> ClosurePtrWithInfo a -> DebugM ()
deref IORef (ThreadState s)
r ClosurePtrWithInfo a
cpi forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IORef (ThreadState s) -> DebugM s
loop IORef (ThreadState s)
r
deref :: IORef (ThreadState s) -> ClosurePtrWithInfo a -> DebugM ()
deref IORef (ThreadState s)
r (ClosurePtrWithInfo a
a ClosurePtr
cp) = do
ThreadState s
m <- forall (m :: * -> *) a. DebugMonad m => IO a -> m a
unsafeLiftIO forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> IO a
readIORef IORef (ThreadState s)
r
do
(ThreadState s
m', Bool
b) <- forall (m :: * -> *) a. DebugMonad m => IO a -> m a
unsafeLiftIO forall a b. (a -> b) -> a -> b
$ forall s. ClosurePtr -> ThreadState s -> IO (ThreadState s, Bool)
checkVisit ClosurePtr
cp ThreadState s
m
forall (m :: * -> *) a. DebugMonad m => IO a -> m a
unsafeLiftIO forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> a -> IO ()
writeIORef IORef (ThreadState s)
r ThreadState s
m'
if Bool
b
then do
s
s <- forall a s. TraceFunctionsIO a s -> ClosurePtr -> a -> DebugM s
visitedVal TraceFunctionsIO a s
k ClosurePtr
cp a
a
forall (m :: * -> *) a. DebugMonad m => IO a -> m a
unsafeLiftIO forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef s
ref (s
s forall a. Semigroup a => a -> a -> a
<>)
else do
SizedClosure
sc <- ClosurePtr -> DebugM SizedClosure
dereferenceClosure ClosurePtr
cp
(a
a', s
s, DebugM () -> DebugM ()
cont) <- forall a s.
TraceFunctionsIO a s
-> ClosurePtr
-> SizedClosure
-> a
-> DebugM (a, s, DebugM () -> DebugM ())
closTrace TraceFunctionsIO a s
k ClosurePtr
cp SizedClosure
sc a
a
forall (m :: * -> *) a. DebugMonad m => IO a -> m a
unsafeLiftIO forall a b. (a -> b) -> a -> b
$ forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef s
ref (s
s forall a. Semigroup a => a -> a -> a
<>)
DebugM () -> DebugM ()
cont (() forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (m :: * -> * -> * -> * -> * -> *) (f :: * -> *) a b c d e g
h i j k.
(Quintraversable m, Applicative f) =>
(a -> f b)
-> (c -> f d)
-> (e -> f g)
-> (h -> f i)
-> (j -> f k)
-> m a c e h j
-> f (m b d g i k)
quintraverse (IORef (ThreadState s) -> a -> SrtCont -> DebugM ()
gosrt IORef (ThreadState s)
r a
a') (IORef (ThreadState s) -> a -> PayloadCont -> DebugM ()
gop IORef (ThreadState s)
r a
a') SrtCont -> DebugM ()
gocd (IORef (ThreadState s) -> a -> StackCont -> DebugM ()
gos IORef (ThreadState s)
r a
a') (IORef (ThreadState s) -> ClosurePtrWithInfo a -> DebugM ()
goc IORef (ThreadState s)
r forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> ClosurePtr -> ClosurePtrWithInfo a
ClosurePtrWithInfo a
a') SizedClosure
sc)
goc :: IORef (ThreadState s) -> ClosurePtrWithInfo a -> DebugM ()
goc IORef (ThreadState s)
r c :: ClosurePtrWithInfo a
c@(ClosurePtrWithInfo a
_i ClosurePtr
cp) =
let mkey :: Int
mkey = ClosurePtr -> Int
getMBlockKey ClosurePtr
cp
in if (Int
mkey forall a. Eq a => a -> a -> Bool
== Int
n)
then IORef (ThreadState s) -> ClosurePtrWithInfo a -> DebugM ()
deref IORef (ThreadState s)
r ClosurePtrWithInfo a
c
else ClosurePtrWithInfo a -> DebugM ()
go ClosurePtrWithInfo a
c
gos :: IORef (ThreadState s) -> a -> StackCont -> DebugM ()
gos IORef (ThreadState s)
r a
a StackCont
st = do
StackFrames
st' <- StackCont -> DebugM StackFrames
dereferenceStack StackCont
st
forall a s. TraceFunctionsIO a s -> StackFrames -> DebugM ()
stackTrace TraceFunctionsIO a s
k StackFrames
st'
() forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (IORef (ThreadState s) -> ClosurePtrWithInfo a -> DebugM ()
goc IORef (ThreadState s)
r forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> ClosurePtr -> ClosurePtrWithInfo a
ClosurePtrWithInfo a
a) StackFrames
st'
gocd :: SrtCont -> DebugM ()
gocd SrtCont
d = do
ConstrDesc
cd <- SrtCont -> DebugM ConstrDesc
dereferenceConDesc SrtCont
d
forall a s. TraceFunctionsIO a s -> ConstrDesc -> DebugM ()
conDescTrace TraceFunctionsIO a s
k ConstrDesc
cd
gop :: IORef (ThreadState s) -> a -> PayloadCont -> DebugM ()
gop IORef (ThreadState s)
r a
a PayloadCont
p = do
PapPayload
p' <- PayloadCont -> DebugM PapPayload
dereferencePapPayload PayloadCont
p
forall a s. TraceFunctionsIO a s -> PapPayload -> DebugM ()
papTrace TraceFunctionsIO a s
k PapPayload
p'
() forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (IORef (ThreadState s) -> ClosurePtrWithInfo a -> DebugM ()
goc IORef (ThreadState s)
r forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> ClosurePtr -> ClosurePtrWithInfo a
ClosurePtrWithInfo a
a) PapPayload
p'
gosrt :: IORef (ThreadState s) -> a -> SrtCont -> DebugM ()
gosrt IORef (ThreadState s)
r a
a SrtCont
p = do
SrtPayload
p' <- SrtCont -> DebugM SrtPayload
dereferenceSRT SrtCont
p
forall a s. TraceFunctionsIO a s -> SrtPayload -> DebugM ()
srtTrace TraceFunctionsIO a s
k SrtPayload
p'
() forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (IORef (ThreadState s) -> ClosurePtrWithInfo a -> DebugM ()
goc IORef (ThreadState s)
r forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> ClosurePtr -> ClosurePtrWithInfo a
ClosurePtrWithInfo a
a) SrtPayload
p'
handleBlockLevel :: IM.Key
-> Word16
-> IM.IntMap (IOBitArray Word16)
-> IO (IM.IntMap (IOBitArray Word16), Bool)
handleBlockLevel :: Int
-> Word16
-> IntMap (IOBitArray Word16)
-> IO (IntMap (IOBitArray Word16), Bool)
handleBlockLevel Int
bk Word16
offset IntMap (IOBitArray Word16)
m = do
case forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
bk IntMap (IOBitArray Word16)
m of
Maybe (IOBitArray Word16)
Nothing -> do
IOBitArray Word16
na <- forall i. Ix i => (i, i) -> Bool -> IO (IOBitArray i)
newArray (Word16
0, forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
blockMask forall a. Integral a => a -> a -> a
`div` Word64
8)) Bool
False
forall i. Ix i => IOBitArray i -> i -> Bool -> IO ()
writeArray IOBitArray Word16
na Word16
offset Bool
True
return (forall a. Int -> a -> IntMap a -> IntMap a
IM.insert Int
bk IOBitArray Word16
na IntMap (IOBitArray Word16)
m, Bool
False)
Just IOBitArray Word16
bm -> do
Bool
res <- forall i. Ix i => IOBitArray i -> i -> IO Bool
readArray IOBitArray Word16
bm Word16
offset
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
res (forall i. Ix i => IOBitArray i -> i -> Bool -> IO ()
writeArray IOBitArray Word16
bm Word16
offset Bool
True)
return (IntMap (IOBitArray Word16)
m, Bool
res)
checkVisit :: ClosurePtr -> ThreadState s -> IO (ThreadState s, Bool)
checkVisit :: forall s. ClosurePtr -> ThreadState s -> IO (ThreadState s, Bool)
checkVisit ClosurePtr
cp ThreadState s
st = do
let (Int
mbk, Int
bk, Word16
offset) = ClosurePtr -> (Int, Int, Word16)
getKeyTriple ClosurePtr
cp
ThreadState IntMap (IntMap (IOBitArray Word16))
v IORef s
ref = ThreadState s
st
case forall a. Int -> IntMap a -> Maybe a
IM.lookup Int
mbk IntMap (IntMap (IOBitArray Word16))
v of
Maybe (IntMap (IOBitArray Word16))
Nothing -> do
(IntMap (IOBitArray Word16)
st', Bool
res) <- Int
-> Word16
-> IntMap (IOBitArray Word16)
-> IO (IntMap (IOBitArray Word16), Bool)
handleBlockLevel Int
bk Word16
offset forall a. IntMap a
IM.empty
forall (m :: * -> *) a. Monad m => a -> m a
return (forall s.
IntMap (IntMap (IOBitArray Word16)) -> IORef s -> ThreadState s
ThreadState (forall a. Int -> a -> IntMap a -> IntMap a
IM.insert Int
mbk IntMap (IOBitArray Word16)
st' IntMap (IntMap (IOBitArray Word16))
v) IORef s
ref, Bool
res)
Just IntMap (IOBitArray Word16)
bm -> do
(IntMap (IOBitArray Word16)
st', Bool
res) <- Int
-> Word16
-> IntMap (IOBitArray Word16)
-> IO (IntMap (IOBitArray Word16), Bool)
handleBlockLevel Int
bk Word16
offset IntMap (IOBitArray Word16)
bm
forall (m :: * -> *) a. Monad m => a -> m a
return (forall s.
IntMap (IntMap (IOBitArray Word16)) -> IORef s -> ThreadState s
ThreadState (forall a. Int -> a -> IntMap a -> IntMap a
IM.insert Int
mbk IntMap (IOBitArray Word16)
st' IntMap (IntMap (IOBitArray Word16))
v) IORef s
ref, Bool
res)
data TraceFunctionsIO a s =
TraceFunctionsIO { forall a s. TraceFunctionsIO a s -> PapPayload -> DebugM ()
papTrace :: !(GenPapPayload ClosurePtr -> DebugM ())
, forall a s. TraceFunctionsIO a s -> SrtPayload -> DebugM ()
srtTrace :: !(GenSrtPayload ClosurePtr -> DebugM ())
, forall a s. TraceFunctionsIO a s -> StackFrames -> DebugM ()
stackTrace :: !(GenStackFrames SrtCont ClosurePtr -> DebugM ())
, forall a s.
TraceFunctionsIO a s
-> ClosurePtr
-> SizedClosure
-> a
-> DebugM (a, s, DebugM () -> DebugM ())
closTrace :: !(ClosurePtr -> SizedClosure -> a -> DebugM (a, s, DebugM () -> DebugM ()))
, forall a s. TraceFunctionsIO a s -> ClosurePtr -> a -> DebugM s
visitedVal :: !(ClosurePtr -> a -> DebugM s)
, forall a s. TraceFunctionsIO a s -> ConstrDesc -> DebugM ()
conDescTrace :: !(ConstrDesc -> DebugM ())
}
traceParFromM :: Monoid s => TraceFunctionsIO a s -> [ClosurePtrWithInfo a] -> DebugM s
traceParFromM :: forall s a.
Monoid s =>
TraceFunctionsIO a s -> [ClosurePtrWithInfo a] -> DebugM s
traceParFromM TraceFunctionsIO a s
k [ClosurePtrWithInfo a]
cps = do
forall (m :: * -> *). DebugMonad m => [Char] -> m ()
traceMsg ([Char]
"SPAWNING: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> [Char]
show Int
threads)
([(Int, ThreadInfo a)]
init_mblocks, [STM Bool]
work_actives, [(ClosurePtrWithInfo a -> DebugM ()) -> DebugM (Async s)]
start) <- forall a b c. [(a, b, c)] -> ([a], [b], [c])
unzip3 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (\Int
b -> do
(ThreadInfo a
ti, STM Bool
working, (ClosurePtrWithInfo a -> DebugM ()) -> DebugM (Async s)
start) <- forall s a.
Monoid s =>
Int
-> TraceFunctionsIO a s
-> DebugM
(ThreadInfo a, STM Bool,
(ClosurePtrWithInfo a -> DebugM ()) -> DebugM (Async s))
initThread Int
b TraceFunctionsIO a s
k
forall (m :: * -> *) a. Monad m => a -> m a
return ((forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
b, ThreadInfo a
ti), STM Bool
working, (ClosurePtrWithInfo a -> DebugM ()) -> DebugM (Async s)
start)) [Int
0 .. Int
threads forall a. Num a => a -> a -> a
- Int
1]
let ts_map :: IntMap (ThreadInfo a)
ts_map = forall a. [(Int, a)] -> IntMap a
IM.fromList [(Int, ThreadInfo a)]
init_mblocks
go :: ClosurePtrWithInfo a -> DebugM ()
go = forall a. TraceState a -> ClosurePtrWithInfo a -> DebugM ()
sendToChan (forall a. ThreadMap a -> TraceState a
TraceState IntMap (ThreadInfo a)
ts_map)
[Async s]
as <- forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence (forall a b. (a -> b) -> [a] -> [b]
map (forall a b. (a -> b) -> a -> b
$ ClosurePtrWithInfo a -> DebugM ()
go) [(ClosurePtrWithInfo a -> DebugM ()) -> DebugM (Async s)]
start )
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ ClosurePtrWithInfo a -> DebugM ()
go [ClosurePtrWithInfo a]
cps
forall (m :: * -> *) a. DebugMonad m => IO a -> m a
unsafeLiftIO forall a b. (a -> b) -> a -> b
$ [STM Bool] -> IO ()
waitFinish [STM Bool]
work_actives
forall (m :: * -> *) a. DebugMonad m => IO a -> m a
unsafeLiftIO forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ forall a. Async a -> IO ()
cancel [Async s]
as
forall (m :: * -> *) a. DebugMonad m => IO a -> m a
unsafeLiftIO forall a b. (a -> b) -> a -> b
$ forall a. Monoid a => [a] -> a
mconcat forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM forall a. Async a -> IO a
wait [Async s]
as
waitFinish :: [STM Bool] -> IO ()
waitFinish :: [STM Bool] -> IO ()
waitFinish [STM Bool]
working = forall a. STM a -> IO a
atomically ([STM Bool] -> STM ()
checkDone [STM Bool]
working)
where
checkDone :: [STM Bool] -> STM ()
checkDone [] = forall (m :: * -> *) a. Monad m => a -> m a
return ()
checkDone (STM Bool
x:[STM Bool]
xs) = do
Bool
b <- STM Bool
x
if Bool
b then [STM Bool] -> STM ()
checkDone [STM Bool]
xs else forall a. STM a
retry
tracePar :: [ClosurePtr] -> DebugM ()
tracePar :: [ClosurePtr] -> DebugM ()
tracePar = forall s a.
Monoid s =>
TraceFunctionsIO a s -> [ClosurePtrWithInfo a] -> DebugM s
traceParFromM TraceFunctionsIO () ()
funcs forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a. a -> ClosurePtr -> ClosurePtrWithInfo a
ClosurePtrWithInfo ())
where
nop :: b -> DebugM ()
nop = forall a b. a -> b -> a
const (forall (m :: * -> *) a. Monad m => a -> m a
return ())
funcs :: TraceFunctionsIO () ()
funcs = forall a s.
(PapPayload -> DebugM ())
-> (SrtPayload -> DebugM ())
-> (StackFrames -> DebugM ())
-> (ClosurePtr
-> SizedClosure -> a -> DebugM (a, s, DebugM () -> DebugM ()))
-> (ClosurePtr -> a -> DebugM s)
-> (ConstrDesc -> DebugM ())
-> TraceFunctionsIO a s
TraceFunctionsIO forall {b}. b -> DebugM ()
nop forall {b}. b -> DebugM ()
nop StackFrames -> DebugM ()
stack ClosurePtr
-> SizedClosure -> () -> DebugM ((), (), DebugM () -> DebugM ())
clos (forall a b. a -> b -> a
const (forall a b. a -> b -> a
const (forall (m :: * -> *) a. Monad m => a -> m a
return ()))) forall {b}. b -> DebugM ()
nop
stack :: GenStackFrames SrtCont ClosurePtr -> DebugM ()
stack :: StackFrames -> DebugM ()
stack StackFrames
fs =
let stack_frames :: [DebugStackFrame SrtCont ClosurePtr]
stack_frames = forall srt b. GenStackFrames srt b -> [DebugStackFrame srt b]
getFrames StackFrames
fs
in forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (SrtCont -> DebugM (Maybe SourceInformation)
getSourceInfo forall b c a. (b -> c) -> (a -> b) -> a -> c
. StgInfoTableWithPtr -> SrtCont
tableId forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall srt b. DebugStackFrame srt b -> StgInfoTableWithPtr
frame_info) [DebugStackFrame SrtCont ClosurePtr]
stack_frames
clos :: ClosurePtr -> SizedClosure -> ()
-> DebugM ((), (), DebugM () -> DebugM ())
clos :: ClosurePtr
-> SizedClosure -> () -> DebugM ((), (), DebugM () -> DebugM ())
clos ClosurePtr
_cp SizedClosure
sc ()
_ = do
let itb :: StgInfoTableWithPtr
itb = forall srt pap string s b.
DebugClosure srt pap string s b -> StgInfoTableWithPtr
info (forall srt pap string s b.
DebugClosureWithSize srt pap string s b
-> DebugClosure srt pap string s b
noSize SizedClosure
sc)
Maybe SourceInformation
_traced <- SrtCont -> DebugM (Maybe SourceInformation)
getSourceInfo (StgInfoTableWithPtr -> SrtCont
tableId StgInfoTableWithPtr
itb)
return ((), (), forall a. a -> a
id)