1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
-- This module supports a duration-based data-type to represent thread
-- execution and GC information.
module Events.EventDuration (
EventDuration(..),
isGCDuration,
startTimeOf, endTimeOf, durationOf,
eventsToDurations,
isDiscreteEvent
) where
-- Imports for GHC Events
import qualified GHC.RTS.Events as GHC
import GHC.RTS.Events hiding (Event,GCWork,GCIdle)
-------------------------------------------------------------------------------
-- This datastructure is a duration-based representation of the event
-- loginformation where thread-runs and GCs are explicitly represented
-- by a single constructor identifying their start and end points.
data EventDuration
= ThreadRun {-#UNPACK#-}!ThreadId
ThreadStopStatus
{-#UNPACK#-}!Timestamp
{-#UNPACK#-}!Timestamp
| GCStart {-#UNPACK#-}!Timestamp
{-#UNPACK#-}!Timestamp
| GCWork {-#UNPACK#-}!Timestamp
{-#UNPACK#-}!Timestamp
| GCIdle {-#UNPACK#-}!Timestamp
{-#UNPACK#-}!Timestamp
| GCEnd {-#UNPACK#-}!Timestamp
{-#UNPACK#-}!Timestamp
deriving Show
{-
GCStart GCWork GCIdle GCEnd
gc start -----> work -----> idle ------+> done -----> gc end
| |
`-------<-------<-----'
-}
isGCDuration :: EventDuration -> Bool
isGCDuration GCStart{} = True
isGCDuration GCWork{} = True
isGCDuration GCIdle{} = True
isGCDuration GCEnd{} = True
isGCDuration _ = False
-------------------------------------------------------------------------------
-- The start time of an event.
startTimeOf :: EventDuration -> Timestamp
startTimeOf ed
= case ed of
ThreadRun _ _ startTime _ -> startTime
GCStart startTime _ -> startTime
GCWork startTime _ -> startTime
GCIdle startTime _ -> startTime
GCEnd startTime _ -> startTime
-------------------------------------------------------------------------------
-- The emd time of an event.
endTimeOf :: EventDuration -> Timestamp
endTimeOf ed
= case ed of
ThreadRun _ _ _ endTime -> endTime
GCStart _ endTime -> endTime
GCWork _ endTime -> endTime
GCIdle _ endTime -> endTime
GCEnd _ endTime -> endTime
-------------------------------------------------------------------------------
-- The duration of an EventDuration
durationOf :: EventDuration -> Timestamp
durationOf ed = endTimeOf ed - startTimeOf ed
-------------------------------------------------------------------------------
eventsToDurations :: [GHC.Event] -> [EventDuration]
eventsToDurations [] = []
eventsToDurations (event : events) =
case spec event of
RunThread{thread=t} -> runDuration t : rest
StopThread{} -> rest
StartGC -> gcStart (time event) events
EndGC{} -> rest
_otherEvent -> rest
where
rest = eventsToDurations events
runDuration t = ThreadRun t s (time event) endTime
where (endTime, s) = case findRunThreadTime events of
Nothing -> error $ "findRunThreadTime for " ++ (show event)
Just x -> x
isDiscreteEvent :: GHC.Event -> Bool
isDiscreteEvent e =
case spec e of
RunThread{} -> False
StopThread{} -> False
StartGC{} -> False
EndGC{} -> False
GHC.GCWork{} -> False
GHC.GCIdle{} -> False
GHC.GCDone{} -> False
GHC.SparkCounters{} -> False
_ -> True
gcStart :: Timestamp -> [GHC.Event] -> [EventDuration]
gcStart _ [] = []
gcStart t0 (event : events) =
case spec event of
GHC.GCWork{} -> GCStart t0 t1 : gcWork t1 events
GHC.GCIdle{} -> GCStart t0 t1 : gcIdle t1 events
GHC.GCDone{} -> GCStart t0 t1 : gcDone t1 events
GHC.EndGC{} -> GCStart t0 t1 : eventsToDurations events
RunThread{} -> GCStart t0 t1 : eventsToDurations (event : events)
_other -> gcStart t0 events
where
t1 = time event
gcWork :: Timestamp -> [GHC.Event] -> [EventDuration]
gcWork _ [] = []
gcWork t0 (event : events) =
case spec event of
GHC.GCWork{} -> gcWork t0 events
GHC.GCIdle{} -> GCWork t0 t1 : gcIdle t1 events
GHC.GCDone{} -> GCWork t0 t1 : gcDone t1 events
GHC.EndGC{} -> GCWork t0 t1 : eventsToDurations events
RunThread{} -> GCWork t0 t1 : eventsToDurations (event : events)
_other -> gcStart t0 events
where
t1 = time event
gcIdle :: Timestamp -> [GHC.Event] -> [EventDuration]
gcIdle _ [] = []
gcIdle t0 (event : events) =
case spec event of
GHC.GCIdle{} -> gcIdle t0 events
GHC.GCWork{} -> GCIdle t0 t1 : gcWork t1 events
GHC.GCDone{} -> GCIdle t0 t1 : gcDone t1 events
GHC.EndGC{} -> GCIdle t0 t1 : eventsToDurations events
RunThread{} -> GCIdle t0 t1 : eventsToDurations (event : events)
_other -> gcStart t0 events
where
t1 = time event
gcDone :: Timestamp -> [GHC.Event] -> [EventDuration]
gcDone _ [] = []
gcDone t0 (event : events) =
case spec event of
GHC.GCDone{} -> gcDone t0 events
GHC.GCWork{} -> GCEnd t0 t1 : gcWork t1 events
GHC.GCIdle{} -> GCEnd t0 t1 : gcIdle t1 events
GHC.EndGC{} -> GCEnd t0 t1 : eventsToDurations events
RunThread{} -> GCEnd t0 t1 : eventsToDurations (event : events)
_other -> gcStart t0 events
where
t1 = time event
-------------------------------------------------------------------------------
findRunThreadTime :: [GHC.Event] -> Maybe (Timestamp, ThreadStopStatus)
findRunThreadTime [] = Nothing
findRunThreadTime (e : es)
= case spec e of
StopThread{status=s} -> Just (time e, s)
_ -> findRunThreadTime es
-------------------------------------------------------------------------------
|