threadscope 0.2.1 → 0.2.2
raw patch · 17 files changed
+2964/−1383 lines, 17 filesdep ~containersdep ~ghc-eventsdep ~unixnew-uploader
Dependency ranges changed: containers, ghc-events, unix
Files
- Events/HECs.hs +7/−6
- Events/ReadEvents.hs +67/−24
- Events/SparkTree.hs +2/−4
- GUI/GtkExtras.hs +25/−1
- GUI/Histogram.hs +1/−0
- GUI/KeyView.hs +4/−0
- GUI/Main.hs +19/−13
- GUI/MainWindow.hs +0/−1
- GUI/SaveAs.hs +3/−3
- GUI/SummaryView.hs +866/−51
- GUI/Timeline/HEC.hs +96/−67
- GUI/Timeline/Render.hs +4/−2
- GUI/Timeline/Ticks.hs +35/−18
- GUI/ViewerColours.hs +1/−1
- LICENSE +31/−31
- threadscope.cabal +8/−8
- threadscope.ui +1795/−1153
Events/HECs.hs view
@@ -7,7 +7,7 @@ eventIndexToTimestamp, timestampToEventIndex,- extractUserMessages,+ extractUserMarkers, histogram, histogramCounts, ) where@@ -32,7 +32,8 @@ minXHistogram :: Int, maxXHistogram :: Int, maxYHistogram :: Timestamp,- durHistogram :: [(Timestamp, Int, Timestamp)]+ durHistogram :: [(Timestamp, Int, Timestamp)],+ perfNames :: IM.IntMap String } -----------------------------------------------------------------------------@@ -55,10 +56,10 @@ mid = l + (r - l) `quot` 2 tmid = time (ce_event (arr!mid)) -extractUserMessages :: HECs -> [(Timestamp, String)]-extractUserMessages hecs =- [ (ts, msg)- | CapEvent _ (Event ts (UserMessage msg)) <- elems (hecEventArray hecs) ]+extractUserMarkers :: HECs -> [(Timestamp, String)]+extractUserMarkers hecs =+ [ (ts, mark)+ | CapEvent _ (Event ts (UserMarker mark)) <- elems (hecEventArray hecs) ] -- | Sum durations in the same buckets to form a histogram. histogram :: [(Int, Timestamp)] -> [(Int, Timestamp)]
Events/ReadEvents.hs view
@@ -10,25 +10,30 @@ import qualified GUI.ProgressView as ProgressView import GUI.ProgressView (ProgressView) -import qualified GHC.RTS.Events as GHCEvents-import GHC.RTS.Events hiding (Event)+import GHC.RTS.Events -- hiding (Event) import GHC.RTS.Events.Analysis import GHC.RTS.Events.Analysis.SparkThread+import GHC.RTS.Events.Analysis.Capability import Data.Array import qualified Data.List as L import Data.Map (Map) import qualified Data.Map as M+import qualified Data.IntMap as IM import Data.Set (Set)-import Data.Maybe (catMaybes)+import Data.Maybe (catMaybes, fromMaybe) import Text.Printf import System.FilePath import Control.Monad import Control.Exception import qualified Control.DeepSeq as DeepSeq+import Data.Function+import Data.Either -------------------------------------------------------------------------------+-- import qualified GHC.RTS.Events as GHCEvents+-- -- The GHC.RTS.Events library returns the profile information -- in a data-streucture which contains a list data structure -- representing the events i.e. [GHCEvents.Event]@@ -46,13 +51,14 @@ ------------------------------------------------------------------------------- -rawEventsToHECs :: [(Maybe Int, [GHCEvents.Event])] -> Timestamp+rawEventsToHECs :: [CapEvent] -> Timestamp -> [(Double, (DurationTree, EventTree, SparkTree))]-rawEventsToHECs eventList endTime- = map (toTree . flip lookup heclists)- [0 .. maximum (minBound : map fst heclists)]+rawEventsToHECs evs endTime+ = map (\ cap -> toTree $ L.find ((Just cap ==) . ce_cap . head) heclists)+ [0 .. maximum (0 : map (fromMaybe 0 . ce_cap) evs)] where- heclists = [ (h, events) | (Just h, events) <- eventList ]+ heclists =+ L.groupBy ((==) `on` ce_cap) $ L.sortBy (compare `on` ce_cap) evs toTree Nothing = (0, (DurationTreeEmpty, EventTree 0 0 (EventTreeLeaf []),@@ -62,7 +68,8 @@ (mkDurationTree (eventsToDurations nondiscrete) endTime, mkEventTree discrete endTime, mkSparkTree sparkD endTime))- where (discrete, nondiscrete) = L.partition isDiscreteEvent evs+ where es = map ce_event evs+ (discrete, nondiscrete) = L.partition isDiscreteEvent es (maxSparkPool, sparkD) = eventsToSparkDurations nondiscrete -------------------------------------------------------------------------------@@ -124,13 +131,36 @@ -- 1, to avoid graph scale 0 and division by 0 later on lastTx = maximum (1 : map eventBlockEnd eventsBy) - groups = groupEvents eventsBy- maxTrees = rawEventsToHECs groups lastTx+ -- Add caps to perf events, using the OS thread numbers+ -- obtained from task validation data.+ -- Only the perf events with a cap are displayed in the timeline.+ -- TODO: it may make sense to move this code to ghc-events+ -- and run after to-eventlog and ghc-events merge, but it requires+ -- one more step in the 'perf to TS' workflow and is a bit slower+ -- (yet another event sorting and loading eventlog chunks+ -- into the CPU cache).+ steps :: [CapEvent] -> [(Map KernelThreadId Int, CapEvent)]+ steps evs =+ zip (map fst $ rights $ validates capabilityTaskOSMachine evs) evs+ addC :: (Map KernelThreadId Int, CapEvent) -> CapEvent+ addC (state, ev@CapEvent{ce_event=Event{spec=PerfTracepoint{tid}}}) =+ case M.lookup tid state of+ Nothing -> ev -- unknown task's OS thread+ ce_cap -> ev {ce_cap}+ addC (state, ev@CapEvent{ce_event=Event{spec=PerfCounter{tid}}}) =+ case M.lookup tid state of+ Nothing -> ev -- unknown task's OS thread+ ce_cap -> ev {ce_cap}+ addC (_, ev) = ev+ addCaps evs = map addC (steps evs)++ -- sort the events by time, add extra caps and put them in an array+ sorted = addCaps $ sortEvents eventsBy+ maxTrees = rawEventsToHECs sorted lastTx maxSparkPool = maximum (0 : map fst maxTrees) trees = map snd maxTrees - -- sort the events by time and put them in an array- sorted = sortGroups groups+ -- put events in an array n_events = length sorted event_arr = listArray (0, n_events-1) sorted hec_count = length trees@@ -145,6 +175,10 @@ ilog :: Timestamp -> Int ilog 0 = 0 ilog x = floor $ logBase 2 (intDoub x)+ times :: (Int, Timestamp, Timestamp)+ -> Maybe (Timestamp, Int, Timestamp)+ times (_, timeStarted, timeElapsed) =+ Just (timeStarted, ilog timeElapsed, timeElapsed) sparkProfile :: Process ((Map ThreadId (Profile SparkThreadState),@@ -161,16 +195,15 @@ sparkSummary :: Map ThreadId (Int, Timestamp, Timestamp) -> [(ThreadId, (SparkThreadState, Timestamp, Timestamp))] -> [Maybe (Timestamp, Int, Timestamp)]- sparkSummary _ [] = []+ sparkSummary m [] = map times $ M.elems m sparkSummary m ((threadId, (state, timeStarted', timeElapsed')):xs) = case state of SparkThreadRunning sparkId' -> case M.lookup threadId m of- Just (sparkId, timeStarted, timeElapsed) ->+ Just el@(sparkId, timeStarted, timeElapsed) -> if sparkId == sparkId' then let value = (sparkId, timeStarted, timeElapsed + timeElapsed') in sparkSummary (M.insert threadId value m) xs- else let times = (timeStarted, ilog timeElapsed, timeElapsed)- in Just times : newSummary sparkId' xs+ else times el : newSummary sparkId' xs Nothing -> newSummary sparkId' xs _ -> sparkSummary m xs where@@ -191,16 +224,26 @@ -- round up to multiples of 10ms maxYHistogram = 10000 * ceiling (fromIntegral maxY / 10000) + getPerfNames nmap ev =+ case spec ev of+ EventBlock{block_events} ->+ L.foldl' getPerfNames nmap block_events+ PerfName{perfNum, name} ->+ IM.insert (fromIntegral perfNum) name nmap+ _ -> nmap+ perfNames = L.foldl' getPerfNames IM.empty eventsBy+ hecs = HECs { hecCount = hec_count, hecTrees = trees, hecEventArray = event_arr, hecLastEventTime = lastTx,- maxSparkPool = maxSparkPool,- minXHistogram = minXHistogram,- maxXHistogram = maxXHistogram,- maxYHistogram = maxYHistogram,- durHistogram = durHistogram+ maxSparkPool,+ minXHistogram,+ maxXHistogram,+ maxYHistogram,+ durHistogram,+ perfNames } treeProgress :: Int -> (DurationTree, EventTree, SparkTree) -> IO ()@@ -211,13 +254,13 @@ evaluate tree1 evaluate (eventTreeMaxDepth tree2) evaluate (sparkTreeMaxDepth tree3)- when (length trees == 1 || hec == 1) -- eval only with 2nd HEC+ when (hec_count == 1 || hec == 1) -- eval only with 2nd HEC (return $! DeepSeq.rnf durHistogram) zipWithM_ treeProgress [0..] trees ProgressView.setProgress progress hec_count hec_count - --TODO: fully evaluate HECs before returning because othewise the last+ -- TODO: fully evaluate HECs before returning because otherwise the last -- bit of work gets done after the progress window has been closed. return (hecs, name, n_events, fromIntegral lastTx / 1000000)
Events/SparkTree.hs view
@@ -40,10 +40,8 @@ newMaxSparkPool = SparkStats.maxPool delta sd = SparkDuration { startT = startTime, deltaC = delta }- (oldMaxSparkPool, l) =- aux endTime endCounters events- in ( max oldMaxSparkPool newMaxSparkPool,- sd : l)+ (oldMaxSparkPool, l) = aux endTime endCounters events+ in (max oldMaxSparkPool newMaxSparkPool, sd : l) _otherEvent -> aux startTime startCounters events in aux 0 (0,0,0,0,0,0,0) es
GUI/GtkExtras.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE ForeignFunctionInterface, CPP #-} module GUI.GtkExtras where -- This is all stuff that should be bound in the gtk package but is not yet@@ -78,11 +78,35 @@ launchProgramForURI :: String -> IO Bool+#if mingw32_HOST_OS || mingw32_TARGET_OS+launchProgramForURI uri = do+ withCString "open" $ \verbPtr ->+ withCString uri $ \filePtr ->+ c_ShellExecuteA+ nullPtr+ verbPtr+ filePtr+ nullPtr+ nullPtr+ 1 -- SW_SHOWNORMAL+ return True++foreign import stdcall unsafe "shlobj.h ShellExecuteA"+ c_ShellExecuteA :: Ptr () -- HWND hwnd+ -> CString -- LPCTSTR lpOperation+ -> CString -- LPCTSTR lpFile+ -> CString -- LPCTSTR lpParameters+ -> CString -- LPCTSTR lpDirectory+ -> CInt -- INT nShowCmd+ -> IO CInt -- HINSTANCE return++#else launchProgramForURI uri = propagateGError $ \errPtrPtr -> withCString uri $ \uriStrPtr -> do timestamp <- gtk_get_current_event_time liftM toBool $ gtk_show_uri nullPtr uriStrPtr timestamp errPtrPtr+#endif -------------------------------------------------------------------------------
GUI/Histogram.hs view
@@ -27,6 +27,7 @@ histogramViewSetHECs :: HistogramView -> Maybe HECs -> IO () histogramViewSetHECs HistogramView{..} mhecs = do writeIORef hecsIORef mhecs+ writeIORef mintervalIORef Nothing -- the old interval may make no sense widgetQueueDraw histogramDrawingArea widgetQueueDraw histogramYScaleArea
GUI/KeyView.hs view
@@ -77,6 +77,10 @@ "Indicates a HEC is terminating") , ("user message", KEvent, userMessageColour, "Indicates a message generated from Haskell code (via traceEvent)")+ , ("perf counter", KEvent, createdConvertedColour,+ "Indicates an update of a perf counter")+ , ("perf tracepoint", KEvent, shutdownColour,+ "Indicates that a perf tracepoint was reached") , ("create spark", KEventAndGraph, createdConvertedColour, "As an event it indicates a use of `par` resulted in a spark being " ++ "created (and added to the spark pool). In the spark creation " ++
GUI/Main.hs view
@@ -46,7 +46,7 @@ mainWin :: MainWindow.MainWindow, eventsView :: EventsView, startupView :: StartupInfoView,- summaryView :: InfoView,+ summaryView :: SummaryView, histogramView :: HistogramView, timelineWin :: TimelineView, traceView :: TraceView,@@ -227,8 +227,13 @@ -- dispatch EventClearState _ - dispatch (EventSetState hecs mfilename name nevents timespan) _ = do+ dispatch (EventSetState hecs mfilename name nevents timespan) _ = + -- We have to draw this ASAP, before the user manages to move+ -- the mouse away from the window, or the window is left+ -- in a partially drawn state.+ ConcurrencyControl.fullSpeed concCtl $ do+ MainWindow.setFileLoaded mainWin (Just name) MainWindow.setStatusMessage mainWin $ printf "%s (%d events, %.3fs)" name nevents timespan@@ -243,16 +248,12 @@ timelineWindowSetHECs timelineWin (Just hecs) timelineWindowSetTraces timelineWin traces' - -- TODO: disabled for now, until it's configurable (see the TODO file)- -- We set user 'traceEvent' messages as initial bookmarks.- -- This is somewhat of an experiment. If users use lots of trace events- -- then it will not be appropriate and we'll want a separate 'traceMark'.- --let usrMsgs = extractUserMessages hecs- --sequence_ [ bookmarkViewAdd bookmarkView ts label- -- | (ts, label) <- usrMsgs ]- -- timelineWindowSetBookmarks timelineWin (map fst usrMsgs)+ -- We set user 'traceMarker' events as initial bookmarks.+ let usrMarkers = extractUserMarkers hecs bookmarkViewClear bookmarkView- timelineWindowSetBookmarks timelineWin []+ sequence_ [ bookmarkViewAdd bookmarkView ts label+ | (ts, label) <- usrMarkers ]+ timelineWindowSetBookmarks timelineWin (map fst usrMarkers) if nevents == 0 then continueWith NoEventlogLoaded@@ -362,6 +363,7 @@ timelineSetSelection timelineWin selection' eventsViewSetCursor eventsView cursorPos' Nothing histogramViewSetInterval histogramView Nothing+ summaryViewSetInterval summaryView Nothing continueWith eventlogState { selection = selection', cursorPos = cursorPos'@@ -374,6 +376,7 @@ timelineSetSelection timelineWin selection' eventsViewSetCursor eventsView cursorPos' mrange histogramViewSetInterval histogramView (Just (start, end))+ summaryViewSetInterval summaryView (Just (start, end)) continueWith eventlogState { selection = selection', cursorPos = cursorPos'@@ -421,8 +424,11 @@ -- This is a desperate hack to avoid the "segfault on reload" bug -- http://trac.haskell.org/ThreadScope/ticket/1 -- It should be enough to let other threads finish and so avoid- -- re-entering gtk C code (see ticket for the dirty details)- threadDelay 100000 -- 1/10th of a second+ -- re-entering gtk C code (see ticket for the dirty details).+ --+ -- Unfortunately it halts drawing of the loaded events if the user+ -- manages to move the mouse away from the window during the delay.+ -- threadDelay 100000 -- 1/10th of a second post (EventSetState hecs mfilename name nevents timespan) return ()
GUI/MainWindow.hs view
@@ -106,7 +106,6 @@ eventsBox <- getWidget castToWidget "eventsbox" bwToggle <- getWidget castToCheckMenuItem "black_and_white"--- TODO: tie in the button and the menu toggle and then re-enable: labModeToggle <- getWidget castToCheckMenuItem "view_labels_mode" sidebarToggle <- getWidget castToCheckMenuItem "view_sidebar" eventsToggle <- getWidget castToCheckMenuItem "view_events"
GUI/SaveAs.hs view
@@ -14,11 +14,11 @@ saveAs :: HECs -> ViewParameters -> Double -> DrawingArea -> (Int, Int, Render ()) saveAs hecs params' @ViewParameters{xScaleAreaHeight, width,- height = oldHeight, histogramHeight}+ height = oldHeight {-, histogramHeight-}} yScaleAreaWidth yScaleArea =- let histTotalHeight = histogramHeight + histXScaleHeight+ let histTotalHeight = histXScaleHeight -- + histogramHeight params@ViewParameters{height} =- params'{ viewTraces = viewTraces params' ++ [TraceHistogram]+ params'{ viewTraces = viewTraces params' -- ++ [TraceHistogram] , height = oldHeight + histTotalHeight + tracePad } w = ceiling yScaleAreaWidth + width
GUI/SummaryView.hs view
@@ -1,80 +1,895 @@ module GUI.SummaryView (- InfoView,+ SummaryView, summaryViewNew, summaryViewSetEvents,+ summaryViewSetInterval, ) where import GHC.RTS.Events -import GUI.Timeline.Render.Constants+import GUI.Types import Graphics.UI.Gtk-import Graphics.Rendering.Cairo import Data.Array import Data.IORef+import Data.Maybe+import Data.Word (Word64)+import Data.List as L+import qualified Data.IntMap as IM+import Control.Monad+import Control.Exception (assert)+import Numeric (showFFloat)+import Text.Printf --------------------------------------------------------------------------------+------------------------------------------------------------------------------ -data InfoView = InfoView- { gtkLayout :: !Layout- , stateRef :: !(IORef InfoState)+type Events = Array Int CapEvent++data SummaryView = SummaryView {++ -- we cache the stats for the whole interval+ cacheEventsStats :: !(IORef (Maybe (Events, SummaryStats, Bool)))++ -- widgets for time stuff+ , labelTimeTotal :: Label+ , labelTimeMutator :: Label+ , labelTimeGC :: Label+ , labelTimeProductivity :: Label++ -- widgets for heap stuff+ , labelHeapMaxSize+ , labelHeapMaxResidency+ , labelHeapAllocTotal+ , labelHeapAllocRate+ , labelHeapMaxSlop :: (Label, Label, Label, Label)+ , tableHeap :: Widget++ -- widgets for GC stuff+ , labelGcCopied :: (Label, Label, Label, Label)+ , labelGcParWorkBalance :: Label+ , storeGcStats :: ListStore GcStatsEntry+ , tableGc :: Widget++ -- widgets for sparks stuff+ , storeSparkStats :: ListStore (Cap, SparkCounts)+ }++------------------------------------------------------------------------------++summaryViewNew :: Builder -> IO SummaryView+summaryViewNew builder = do+ cacheEventsStats <- newIORef Nothing++ let getWidget cast = builderGetObject builder cast+ getLabel = getWidget castToLabel+ getHeapLabels w1 w2 w3 w4 = liftM4 (,,,) (getLabel w1) (getLabel w2)+ (getLabel w3) (getLabel w4)++ labelTimeTotal <- getWidget castToLabel "labelTimeTotal"+ labelTimeMutator <- getWidget castToLabel "labelTimeMutator"+ labelTimeGC <- getWidget castToLabel "labelTimeGC"+ labelTimeProductivity <- getWidget castToLabel "labelTimeProductivity"+++ labelHeapMaxSize <- getHeapLabels "labelHeapMaxSize" "labelHeapMaxSizeUnit"+ "labelHeapMaxSizeBytes" "labelHeapMaxSizeUnit1"+ labelHeapMaxResidency <- getHeapLabels "labelHeapMaxResidency" "labelHeapMaxResidencyUnit"+ "labelHeapMaxResidencyBytes" "labelHeapMaxResidencyUnit1"+ labelHeapAllocTotal <- getHeapLabels "labelHeapAllocTotal" "labelHeapAllocTotalUnit"+ "labelHeapAllocTotalBytes" "labelHeapAllocTotalUnit1"+ labelHeapAllocRate <- getHeapLabels "labelHeapAllocRate" "labelHeapAllocRateUnit"+ "labelHeapAllocRateBytes" "labelHeapAllocRateUnit1"+ labelHeapMaxSlop <- getHeapLabels "labelHeapMaxSlop" "labelHeapMaxSlopUnit"+ "labelHeapMaxSlopBytes" "labelHeapMaxSlopUnit1"+ tableHeap <- getWidget castToWidget "tableHeap"++ labelGcCopied <- getHeapLabels "labelGcCopied" "labelGcCopiedUnit"+ "labelGcCopiedBytes" "labelGcCopiedUnit1"+ labelGcParWorkBalance <- getWidget castToLabel "labelGcParWorkBalance"+ storeGcStats <- listStoreNew []+ tableGc <- getWidget castToWidget "tableGC"++ storeSparkStats <- listStoreNew []++ let summaryView = SummaryView{..}++ treeviewGcStats <- getWidget castToTreeView "treeviewGcStats"+ treeViewSetModel treeviewGcStats storeGcStats+ let addGcColumn = addColumn treeviewGcStats storeGcStats+ addGcColumn "Generation" $ \(GcStatsEntry gen _ _ _ _ _) ->+ [ cellText := if gen == -1 then "GC Total" else "Gen " ++ show gen ]+ addGcColumn "Collections" $ \(GcStatsEntry _ colls _ _ _ _) ->+ [ cellText := show colls ]+ addGcColumn "Par collections" $ \(GcStatsEntry _ _ pcolls _ _ _) ->+ [ cellText := show pcolls ]+ addGcColumn "Elapsed time" $ \(GcStatsEntry _ _ _ time _ _) ->+ [ cellText := printf "%5.2fs" (timeToSecondsDbl time) ]+ addGcColumn "Avg pause" $ \(GcStatsEntry _ _ _ _ avgpause _) ->+ [ cellText := printf "%3.4fs" avgpause ]+ addGcColumn "Max pause" $ \(GcStatsEntry _ _ _ _ _ maxpause) ->+ [ cellText := printf "%3.4fs" maxpause ]++ treeviewSparkStats <- getWidget castToTreeView "treeviewSparkStats"+ treeViewSetModel treeviewSparkStats storeSparkStats+ let addSparksColumn = addColumn treeviewSparkStats storeSparkStats+ addSparksColumn "HEC" $ \(hec, _) ->+ [ cellText := if hec == -1 then "Total" else "HEC " ++ show hec ]+ addSparksColumn "Total" $ \(_, SparkCounts total _ _ _ _ _) ->+ [ cellText := show total ]+ addSparksColumn "Converted" $ \(_, SparkCounts _ conv _ _ _ _) ->+ [ cellText := show conv ]+ addSparksColumn "Overflowed" $ \(_, SparkCounts _ _ ovf _ _ _) ->+ [ cellText := show ovf ]+ addSparksColumn "Dud" $ \(_, SparkCounts _ _ _ dud _ _) ->+ [ cellText := show dud ]+ addSparksColumn "GC'd" $ \(_, SparkCounts _ _ _ _ gc _) ->+ [ cellText := show gc ]+ addSparksColumn "Fizzled" $ \(_, SparkCounts _ _ _ _ _ fiz) ->+ [ cellText := show fiz ]++ return summaryView++ where+ addColumn view store title mkAttrs = do+ col <- treeViewColumnNew+ cell <- cellRendererTextNew+ treeViewColumnSetTitle col title+ treeViewColumnPackStart col cell False+ treeViewAppendColumn view col+ cellLayoutSetAttributes col cell store mkAttrs+++------------------------------------------------------------------------------++summaryViewSetEvents :: SummaryView -> Maybe (Array Int CapEvent) -> IO ()+summaryViewSetEvents view@SummaryView{cacheEventsStats} Nothing = do+ writeIORef cacheEventsStats Nothing+ setSummaryStatsEmpty view++summaryViewSetEvents view@SummaryView{cacheEventsStats} (Just events) = do+ let stats = summaryStats events Nothing+ -- this is an almost certain indicator that there+ -- are no heap events in the eventlog:+ hasHeapEvents = heapMaxSize (summHeapStats stats) /= Just 0+ writeIORef cacheEventsStats (Just (events, stats, hasHeapEvents))+ setSummaryStats view stats hasHeapEvents+++summaryViewSetInterval :: SummaryView -> Maybe Interval -> IO ()+summaryViewSetInterval view@SummaryView{cacheEventsStats} Nothing = do+ cache <- readIORef cacheEventsStats+ case cache of+ Nothing -> return ()+ Just (_, stats, hasHeap) -> setSummaryStats view stats hasHeap++summaryViewSetInterval view@SummaryView{cacheEventsStats} (Just interval) = do+ cache <- readIORef cacheEventsStats+ case cache of+ Nothing -> return ()+ Just (events, _, hasHeap) -> setSummaryStats view stats hasHeap+ where stats = summaryStats events (Just interval)++------------------------------------------------------------------------------++setSummaryStats :: SummaryView -> SummaryStats -> Bool -> IO ()+setSummaryStats view SummaryStats{..} hasHeapEvents = do+ setTimeStats view summTimeStats+ if hasHeapEvents+ then do setHeapStatsAvailable view True+ setHeapStats view summHeapStats+ setGcStats view summGcStats+ else setHeapStatsAvailable view False+ setSparkStats view summSparkStats++setTimeStats :: SummaryView -> TimeStats -> IO ()+setTimeStats SummaryView{..} TimeStats{..} =+ mapM_ (\(label, text) -> set label [ labelText := text ])+ [ (labelTimeTotal , showFFloat (Just 2) (timeToSecondsDbl timeTotal) "s")+ , (labelTimeMutator , showFFloat (Just 2) (timeToSecondsDbl timeMutator) "s")+ , (labelTimeGC , showFFloat (Just 2) (timeToSecondsDbl timeGC) "s")+ , (labelTimeProductivity, showFFloat (Just 1) (timeProductivity * 100) "% of mutator vs total")+ ]++setHeapStats :: SummaryView -> HeapStats -> IO ()+setHeapStats SummaryView{..} HeapStats{..} = do+ setHeapStatLabels labelHeapMaxSize heapMaxSize "" ""+ setHeapStatLabels labelHeapMaxResidency heapMaxResidency "" ""+ setHeapStatLabels labelHeapAllocTotal heapTotalAlloc "" ""+ setHeapStatLabels labelHeapAllocRate heapAllocRate "/s" " per second (of mutator time)"+ setHeapStatLabels labelHeapMaxSlop heapMaxSlop "" ""+ setHeapStatLabels labelGcCopied heapCopiedDuringGc "" ""+ where+ setHeapStatLabels labels stat unitSuffix unitSuffixLong =+ let texts = case stat of+ Nothing -> ("N/A", "", "", "")+ Just b -> ( formatBytesInUnit b u, formatUnit u ++ unitSuffix+ , formatBytes b, "bytes" ++ unitSuffixLong)+ where u = getByteUnit b+ in setLabels labels texts++ setLabels (short,shortunit,long,longunit) (short', shortunit', long', longunit') = do+ mapM_ (\(label, text) -> set label [ labelText := text ])+ [ (short, short'), (shortunit, shortunit')+ , (long, long'), (longunit, longunit') ]+++setGcStats :: SummaryView -> GcStats -> IO ()+setGcStats SummaryView{..} GcStats{..} = do+ let balText = maybe "N/A"+ (printf "%.2f%% (serial 0%%, perfect 100%%)")+ gcParWorkBalance+ set labelGcParWorkBalance [ labelText := balText ]+ listStoreClear storeGcStats+ mapM_ (listStoreAppend storeGcStats) (gcTotalStats:gcGenStats)++setSparkStats :: SummaryView -> SparkStats -> IO ()+setSparkStats SummaryView{..} SparkStats{..} = do+ listStoreClear storeSparkStats+ mapM_ (listStoreAppend storeSparkStats) ((-1,totalSparkStats):capSparkStats)++data ByteUnit = TiB | GiB | MiB | KiB | B deriving Show++byteUnitVal :: ByteUnit -> Word64+byteUnitVal TiB = 2^40+byteUnitVal GiB = 2^30+byteUnitVal MiB = 2^20+byteUnitVal KiB = 2^10+byteUnitVal B = 1++getByteUnit :: Word64 -> ByteUnit+getByteUnit b+ | b >= 2^40 = TiB+ | b >= 2^30 = GiB+ | b >= 2^20 = MiB+ | b >= 2^10 = KiB+ | otherwise = B++formatBytesInUnit :: Word64 -> ByteUnit -> String+formatBytesInUnit n u =+ formatFixed (fromIntegral n / fromIntegral (byteUnitVal u))+ where+ formatFixed x = showFFloat (Just 1) x ""++formatUnit :: ByteUnit -> String+formatUnit = show++formatBytes :: Word64 -> String+formatBytes b = ppWithCommas b++ppWithCommas :: Word64 -> String+ppWithCommas =+ let spl [] = []+ spl l = let (c3, cs) = L.splitAt 3 l+ in c3 : spl cs+ in L.reverse . L.intercalate "," . spl . L.reverse . show++setSummaryStatsEmpty :: SummaryView -> IO ()+setSummaryStatsEmpty SummaryView{..} = do+ mapM_ (\label -> set label [ labelText := "", widgetTooltipText := Nothing ]) $+ [ labelTimeTotal, labelTimeMutator+ , labelTimeGC, labelTimeProductivity ] +++ [ w+ | (a,b,c,d) <- [ labelHeapMaxSize, labelHeapMaxResidency+ , labelHeapAllocTotal, labelHeapAllocRate+ , labelHeapMaxSlop, labelGcCopied ]+ , w <- [ a,b,c,d] ]+ listStoreClear storeGcStats+ listStoreClear storeSparkStats++setHeapStatsAvailable :: SummaryView -> Bool -> IO ()+setHeapStatsAvailable SummaryView{..} available+ | available = do+ forM_ unavailableWidgets $ \widget ->+ set widget [ widgetTooltipText := Nothing, widgetSensitive := True ]++ | otherwise = do+ forM_ allLabels $ \label -> set label [ labelText := "" ]+ listStoreClear storeGcStats++ forM_ unavailableLabels $ \label ->+ set label [ labelText := "(unavailable)" ]++ forM_ unavailableWidgets $ \widget ->+ set widget [ widgetTooltipText := Just msgInfoUnavailable, widgetSensitive := False ]++ where+ allLabels =+ [ labelTimeMutator, labelTimeGC+ , labelTimeProductivity, labelGcParWorkBalance ] +++ [ w | (a,b,c,d) <- [ labelHeapMaxSize, labelHeapMaxResidency+ , labelHeapAllocTotal, labelHeapAllocRate+ , labelHeapMaxSlop, labelGcCopied ]+ , w <- [ a,b,c,d] ]+ unavailableLabels =+ [ labelTimeMutator, labelTimeGC+ , labelTimeProductivity, labelGcParWorkBalance+ , case labelGcCopied of (w,_,_,_) -> w ] +++ [ c | (_,_,c,_) <- [ labelHeapMaxSize, labelHeapMaxResidency+ , labelHeapAllocTotal, labelHeapAllocRate+ , labelHeapMaxSlop ] ]+ unavailableWidgets = [ toWidget labelTimeMutator, toWidget labelTimeGC+ , toWidget labelTimeProductivity+ , tableHeap, tableGc ]+ msgInfoUnavailable = "This eventlog does not contain heap or GC information."++------------------------------------------------------------------------------+-- Calculating the stats we want to display+--++data SummaryStats = SummaryStats {+ summTimeStats :: TimeStats,+ summHeapStats :: HeapStats,+ summGcStats :: GcStats,+ summSparkStats :: SparkStats } -data InfoState- = InfoEmpty- | InfoLoaded- { infoState :: String+data TimeStats = TimeStats {+ timeTotal :: !Word64, -- we really should have a better type for elapsed time+ timeGC :: !Word64,+ timeMutator :: !Word64,+ timeProductivity :: !Double } --------------------------------------------------------------------------------+data HeapStats = HeapStats {+ heapMaxSize :: Maybe Word64,+ heapMaxResidency :: Maybe Word64,+ heapMaxSlop :: Maybe Word64,+ heapTotalAlloc :: Maybe Word64,+ heapAllocRate :: Maybe Word64,+ heapCopiedDuringGc :: Maybe Word64+ } -infoViewNew :: String -> Builder -> IO InfoView-infoViewNew widgetName builder = do+data GcStats = GcStats {+ gcNumThreads :: !Int,+ gcParWorkBalance :: !(Maybe Double),+ gcGenStats :: [GcStatsEntry],+ gcTotalStats :: !GcStatsEntry+ }+data GcStatsEntry = GcStatsEntry !Int !Int !Int !Word64 !Double !Double - stateRef <- newIORef undefined- let getWidget cast = builderGetObject builder cast- gtkLayout <- getWidget castToLayout widgetName- writeIORef stateRef InfoEmpty- let infoView = InfoView{..}+data SparkStats = SparkStats {+ capSparkStats :: [(Cap, SparkCounts)],+ totalSparkStats :: !SparkCounts+ }+data SparkCounts = SparkCounts !Word64 !Word64 !Word64 !Word64 !Word64 !Word64 - -- Drawing- on gtkLayout exposeEvent $ liftIO $ do- drawInfo infoView =<< readIORef stateRef- return True - return infoView+-- | Take the events, and optionally some sub-range, and generate the summary+-- stats for that range.+--+-- We take a two-step approach:+-- * a single pass over the events, accumulating into an intermediate+-- 'StatsAccum' record,+-- * then look at that 'StatsAccum' record and construct the various final+-- stats that we want to present.+--+summaryStats :: Array Int CapEvent -> Maybe Interval -> SummaryStats+summaryStats events minterval =+ SummaryStats {+ summHeapStats = hs,+ summGcStats = gs,+ summSparkStats = ss,+ summTimeStats = ts+ }+ where+ !statsAccum = accumStats events minterval -summaryViewNew :: Builder -> IO InfoView-summaryViewNew = infoViewNew "eventsLayoutSummary"+ gs = gcStats statsAccum+ ss = sparkStats statsAccum+ ts = timeStats events minterval gs+ hs = heapStats statsAccum ts -------------------------------------------------------------------------------- -infoViewSetEvents :: (Array Int CapEvent -> InfoState)- -> InfoView -> Maybe (Array Int CapEvent) -> IO ()-infoViewSetEvents f InfoView{gtkLayout, stateRef} mevents = do- let infoState = case mevents of- Nothing -> InfoEmpty- Just events -> f events- writeIORef stateRef infoState- widgetQueueDraw gtkLayout+-- | Linearly accumulate the stats from the events array,+-- either the full thing or some sub-range.+accumStats :: Array Int CapEvent -> Maybe Interval -> StatsAccum+accumStats events minterval =+ foldl' accumEvent start [ events ! i | i <- range eventsRange ]+ where+ eventsRange = selectEventRange events minterval -summaryViewProcessEvents :: Array Int CapEvent -> InfoState-summaryViewProcessEvents _events = InfoLoaded "TODO"+ -- If we're starting from time zero then we know many of the stats+ -- also start at from, where as from other points it's just unknown+ start | fst eventsRange == 0 = zeroStatsAccum+ | otherwise = emptyStatsAccum -summaryViewSetEvents :: InfoView -> Maybe (Array Int CapEvent) -> IO ()-summaryViewSetEvents = infoViewSetEvents summaryViewProcessEvents+-- | Given the event array and a time interval, return the range of array+-- indicies containing that interval. The Nothing interval means to select+-- the whole array range.+--+selectEventRange :: Array Int CapEvent -> Maybe Interval -> (Int, Int)+selectEventRange arr Nothing = bounds arr+selectEventRange arr (Just (start, end)) = (lbound, ubound)+ where+ !lbound = either snd id $ findArrayRange cmp arr start+ !ubound = either fst id $ findArrayRange cmp arr end+ cmp ts (CapEvent _ (Event ts' _)) = compare ts ts' --------------------------------------------------------------------------------+ findArrayRange :: (key -> val -> Ordering)+ -> Array Int val -> key -> Either (Int,Int) Int+ findArrayRange cmp arr key =+ binarySearch a0 b0 key+ where+ (a0,b0) = bounds arr -drawInfo :: InfoView -> InfoState -> IO ()-drawInfo _ InfoEmpty = return ()-drawInfo InfoView{gtkLayout} InfoLoaded{..} = do- win <- layoutGetDrawWindow gtkLayout- pangoCtx <- widgetGetPangoContext gtkLayout- layout <- layoutText pangoCtx infoState- (_, Rectangle _ _ width height) <- layoutGetPixelExtents layout- layoutSetSize gtkLayout (width + 30) (height + 30)- renderWithDrawable win $ do- moveTo (fromIntegral ox / 2) (fromIntegral ox / 3)- showLayout layout+ binarySearch a b key+ | a > b = Left (b,a)+ | otherwise = case cmp key (arr ! mid) of+ LT -> binarySearch a (mid-1) key+ EQ -> Right mid+ GT -> binarySearch (mid+1) b key+ where mid = (a + b) `div` 2++------------------------------------------------------------------------------+-- Final step where we convert from StatsAccum to various presentation forms++timeStats :: Array Int CapEvent -> Maybe Interval -> GcStats -> TimeStats+timeStats events minterval+ GcStats { gcTotalStats = GcStatsEntry _ _ _ timeGC _ _ } =+ TimeStats {..}+ where+ timeTotal = intervalEnd - intervalStart+ timeMutator = timeTotal - timeGC+ timeProductivity = timeToSecondsDbl timeMutator+ / timeToSecondsDbl timeTotal++ (intervalStart, intervalEnd) =+ case minterval of+ Just (s,e) -> (s, e)+ Nothing -> (0, timeOf (events ! ub))+ where+ (_lb, ub) = bounds events+ timeOf (CapEvent _ (Event t _)) = t+++heapStats :: StatsAccum -> TimeStats -> HeapStats+heapStats StatsAccum{..} TimeStats{timeMutator} =+ HeapStats {+ heapMaxSize = dmaxMemory,+ heapMaxResidency = dmaxResidency,+ heapMaxSlop = dmaxSlop,+ heapTotalAlloc = if totalAlloc == 0+ then Nothing+ else Just totalAlloc,+ heapAllocRate = if timeMutator == 0 || totalAlloc == 0+ then Nothing+ else Just $ truncate (fromIntegral totalAlloc / timeToSecondsDbl timeMutator),+ heapCopiedDuringGc = if dcopied == Just 0+ then Nothing+ else dcopied+ }+ where+ totalAlloc = sum [ end - start+ | (end,start) <- IM.elems dallocTable ]+++gcStats :: StatsAccum -> GcStats+gcStats StatsAccum{..} =+ GcStats {+ gcNumThreads = nThreads,+ gcParWorkBalance,+ gcGenStats = [ mkGcStatsEntry gen (gcGather gen)+ | gen <- gens ],+ gcTotalStats = mkGcStatsEntry gcGenTot (gcGather gcGenTot)+ }+ where+ nThreads = fromMaybe 1 dmaxParNThreads++ gcParWorkBalance | nThreads <= 1+ || fromMaybe 0 dparMaxCopied <= 0 = Nothing+ | otherwise =+ Just $+ 100 * ((maybe 0 fromIntegral dparTotCopied+ / maybe 0 fromIntegral dparMaxCopied) - 1)+ / (fromIntegral nThreads - 1)++ gens = [0..maxGeneration]+ where+ -- Does not work for generationless GCs, but works reasonably+ -- for > 2 gens and perfectly for 2 gens.+ maxGeneration = maximum $ 1+ : [ maxGen+ | RtsGC { gcGenStat } <- IM.elems dGCTable+ , not (IM.null gcGenStat)+ , let (maxGen, _) = IM.findMax gcGenStat ]++ gcGather :: Gen -> GenStat+ gcGather gen = gcSum gen $ map gcGenStat $ IM.elems dGCTable+ -- TODO: Consider per-HEC display of GC stats and then use+ -- the values summed over all generations at key gcGenTot at each cap.++ gcSum :: Gen -> [IM.IntMap GenStat] -> GenStat+ gcSum gen l =+ GenStat (sumPr gcAll) (sumPr gcPar)+ (gcElapsed mainGen) (gcMaxPause mainGen)+ where+ l_genGC = map (IM.findWithDefault emptyGenStat gen) l+ sumPr proj = sum $ map proj l_genGC+ _maxPr proj = L.maximum $ map proj l_genGC+ _minPr proj = L.minimum $ filter (> 0) $ map proj l_genGC+ -- This would be the most balanced way of aggregating gcElapsed,+ -- if only the event times were accurate.+ _avgPr proj = let vs = filter (> 0) $ map proj l_genGC+ in sum vs `div` fromIntegral (length vs)+ -- But since the times include scheduling noise,+ -- we only use the times from the main cap for each GC+ -- and so get readings almost identical to +RTS -s.+ mainGen = IM.findWithDefault emptyGenStat gen mainStat++ mainStat = gcGenStat (fromMaybe (defaultGC 0) dGCMain)++ mkGcStatsEntry :: Gen -> GenStat -> GcStatsEntry+ mkGcStatsEntry gen GenStat{..} =+ GcStatsEntry gen gcAll gcPar gcElapsedS gcAvgPauseS gcMaxPauseS+ where+ gcElapsedS = gcElapsed+ gcMaxPauseS = timeToSecondsDbl gcMaxPause+ gcAvgPauseS+ | gcAll == 0 = 0+ | otherwise = timeToSeconds $+ fromIntegral gcElapsed / fromIntegral gcAll+++sparkStats :: StatsAccum -> SparkStats+sparkStats StatsAccum{dsparkTable} =+ SparkStats {+ capSparkStats =+ [ (cap, mkSparkStats sparkCounts)+ | (cap, sparkCounts) <- capsSparkCounts ],++ totalSparkStats =+ mkSparkStats $+ foldl' (binopSparks (+)) zeroSparks+ [ sparkCounts | (_cap, sparkCounts) <- capsSparkCounts ]+ }+ where+ capsSparkCounts =+ [ (cap, sparkCounts)+ | (cap, (countsEnd, countsStart)) <- IM.assocs dsparkTable+ , let sparkCounts = binopSparks (-) countsEnd countsStart ]++ mkSparkStats RtsSpark {sparkCreated, sparkDud, sparkOverflowed,+ sparkConverted, sparkFizzled, sparkGCd} =+ -- in our final presentation we show the total created,+ -- and the breakdown of that into outcomes:+ SparkCounts (sparkCreated + sparkDud + sparkOverflowed)+ sparkConverted sparkOverflowed+ sparkDud sparkGCd sparkFizzled+++------------------------------------------------------------------------------++timeToSecondsDbl :: Integral a => a -> Double+timeToSecondsDbl t = timeToSeconds $ fromIntegral t++timeToSeconds :: Double -> Double+timeToSeconds t = t / tIME_RESOLUTION+ where tIME_RESOLUTION = 1000000++------------------------------------------------------------------------------+-- The single-pass stats accumulation stuff+--++-- | Data collected and computed gradually while events are scanned.+data StatsAccum = StatsAccum+ { dallocTable :: !(IM.IntMap (Word64, Word64)) -- indexed by caps+ , dcopied :: !(Maybe Word64)+ , dmaxResidency :: !(Maybe Word64)+ , dmaxSlop :: !(Maybe Word64)+ , dmaxMemory :: !(Maybe Word64)+--, dmaxFrag :: Maybe Word64 -- not important enough+ , dGCTable :: !(IM.IntMap RtsGC) -- indexed by caps+ -- Here we store the official +RTS -s timings of GCs,+ -- that is times aggregated from the main caps of all GCs.+ -- For now only gcElapsed and gcMaxPause are needed, so the rest+ -- of the fields stays at default values.+ , dGCMain :: !(Maybe RtsGC)+ , dparMaxCopied :: !(Maybe Word64)+ , dparTotCopied :: !(Maybe Word64)+ , dmaxParNThreads :: !(Maybe Int)+--, dtaskTable -- of questionable usefulness, hard to get+ , dsparkTable :: !(IM.IntMap (RtsSpark, RtsSpark)) -- indexed by caps+--, dInitExitT -- TODO. At least init time can be included in the total+ -- time registered in the eventlog. Can we measure this+ -- as the time between some initial events?+--, dGCTime -- Is better computed after all events are scanned,+ -- e.g., because the same info can be used to calculate+ -- per-cap GCTime and other per-cap stats.+--, dtotalTime -- TODO: can we measure this excluding INIT or EXIT times?+ }++data RtsSpark = RtsSpark+ { sparkCreated, sparkDud, sparkOverflowed+ , sparkConverted, sparkFizzled, sparkGCd :: !Word64+ }++zeroSparks :: RtsSpark+zeroSparks = RtsSpark 0 0 0 0 0 0++binopSparks :: (Word64 -> Word64 -> Word64) -> RtsSpark -> RtsSpark -> RtsSpark+binopSparks op (RtsSpark crt1 dud1 ovf1 cnv1 fiz1 gcd1)+ (RtsSpark crt2 dud2 ovf2 cnv2 fiz2 gcd2) =+ RtsSpark (crt1 `op` crt2) (dud1 `op` dud2) (ovf1 `op` ovf2)+ (cnv1 `op` cnv2) (fiz1 `op` fiz2) (gcd1 `op` gcd2)++type Gen = Int++type Cap = Int++data GcMode =+ ModeInit | ModeStart | ModeSync Cap | ModeGHC Cap Gen | ModeEnd | ModeIdle+ deriving Eq++data RtsGC = RtsGC+ { gcMode :: !GcMode+ , gcStartTime :: !Timestamp+ , gcGenStat :: !(IM.IntMap GenStat) -- indexed by generations+ }++-- Index at the @gcGenStat@ map at which we store the sum of stats over all+-- generations, or the single set of stats for non-genenerational GC models.+gcGenTot :: Gen+gcGenTot = -1++data GenStat = GenStat+ { -- Sum over all seqential and pararell GC invocations.+ gcAll :: !Int+ , -- Only parallel GCs. For GC models without stop-the-world par, always 0.+ gcPar :: !Int+ , gcElapsed :: !Timestamp+ , gcMaxPause :: !Timestamp+ }++emptyStatsAccum :: StatsAccum+emptyStatsAccum = StatsAccum+ { dallocTable = IM.empty+ , dcopied = Nothing+ , dmaxResidency = Nothing+ , dmaxSlop = Nothing+ , dmaxMemory = Nothing+ , dGCTable = IM.empty+ , dGCMain = Nothing+ , dparMaxCopied = Nothing+ , dparTotCopied = Nothing+ , dmaxParNThreads = Nothing+ , dsparkTable = IM.empty+ }++-- | At the beginning of a program run, we know for sure several of the+-- stats start at zero:+zeroStatsAccum :: StatsAccum+zeroStatsAccum = emptyStatsAccum {+ dcopied = Just 0,+ dmaxResidency = Just 0,+ dmaxSlop = Just 0,+ dmaxMemory = Just 0,+ dallocTable = -- a hack: we assume no more than 999 caps+ IM.fromDistinctAscList $ zip [0..999] $ repeat (0, 0)+ -- FIXME: but also, we should have a way to init to 0 for all caps.+ }++defaultGC :: Timestamp -> RtsGC+defaultGC time = RtsGC+ { gcMode = ModeInit+ , gcStartTime = time+ , gcGenStat = IM.empty+ }++emptyGenStat :: GenStat+emptyGenStat = GenStat+ { gcAll = 0+ , gcPar = 0+ , gcElapsed = 0+ , gcMaxPause = 0+ }++accumEvent :: StatsAccum -> CapEvent -> StatsAccum+accumEvent !statsAccum (CapEvent mcap ev) =+ let -- For events that contain a counter with a running sum.+ -- Eventually we'll subtract the last found+ -- event from the first. Intervals beginning at time 0+ -- are a special case, because morally the first event should have+ -- value 0, but it may be absent, so we start with @Just (0, 0)@.+ alterCounter n Nothing = Just (n, n)+ alterCounter n (Just (_previous, first)) = Just (n, first)+ -- For events that contain discrete increments. We assume the event+ -- is emitted close to the end of the process it measures,+ -- so we ignore the first found event, because most of the process+ -- could have happened before the start of the current inverval.+ -- This is consistent with @alterCounter@. For interval beginning+ -- at time 0, we start with @Just 0@.+ alterIncrement _ Nothing = Just 0+ alterIncrement n (Just k) = Just (k + n)+ -- For events that contain sampled values, where a max is sought.+ alterMax n Nothing = Just n+ alterMax n (Just k) | n > k = Just n+ alterMax _ jk = jk+ -- Scan events, updating summary data.+ scan cap !sd@StatsAccum{..} Event{time, spec} =+ let capGC = IM.findWithDefault (defaultGC time) cap dGCTable+ in case spec of+ -- TODO: check EventBlock elsewhere; define {map,fold}EventBlock+ EventBlock{cap = bcap, block_events} ->+ L.foldl' (scan bcap) sd block_events+ HeapAllocated{allocBytes} ->+ sd { dallocTable =+ IM.alter (alterCounter allocBytes) cap dallocTable }+ HeapLive{liveBytes} ->+ sd { dmaxResidency = alterMax liveBytes dmaxResidency}+ HeapSize{sizeBytes} ->+ sd { dmaxMemory = alterMax sizeBytes dmaxMemory}+ StartGC ->+ assert (gcMode capGC `elem` [ModeInit, ModeEnd, ModeIdle]) $+ let newGC = capGC { gcMode = ModeStart+ , gcStartTime = time+ }+ -- TODO: Index with generations, not caps?+ in sd { dGCTable = IM.insert cap newGC dGCTable }+ GlobalSyncGC ->+ -- All caps must be stopped. Those that take part in the GC+ -- are in ModeInit or ModeStart, those that do not+ -- are in ModeInit, ModeEnd or ModeIdle.+ assert (L.all (notModeGHCEtc . gcMode) (IM.elems dGCTable)) $+ sd { dGCTable = IM.mapWithKey setSync dGCTable }+ where+ notModeGHCEtc ModeGHC{} = False+ notModeGHCEtc ModeSync{} = False+ notModeGHCEtc _ = True+ someInit = L.any ((== ModeInit) . gcMode) (IM.elems dGCTable)+ setSync capKey dGC@RtsGC{gcGenStat}+ | someInit =+ -- If even one cap could possibly have started GC before+ -- the start of the selected interval, skip the GC on all caps.+ -- We don't verify the overwritten modes in this case.+ -- TODO: we could be smarter and defer the decision to EndGC,+ -- when we can deduce if the suspect caps take part in GC+ -- or not at all.+ dGC { gcMode = ModeInit }+ | otherwise =+ let totGC = IM.findWithDefault emptyGenStat gcGenTot gcGenStat+ in case gcMode dGC of+ -- Cap takes part in the GC (not known if seq or par).+ -- Here is the moment where all caps taking place in the GC+ -- are identified and we can aggregate all their data+ -- at once (currently we just increment a counter for each).+ -- The EndGC events can come much later for some caps and at+ -- that time other caps are already inside their new GC.+ ModeStart ->+ dGC { gcMode = ModeSync cap+ , gcGenStat =+ if capKey == cap+ then IM.insert gcGenTot+ totGC{ gcAll = gcAll totGC + 1 }+ gcGenStat+ else gcGenStat+ }+ -- Cap is not in the GC. Mark it as idle to complete+ -- the identification of caps that take part+ -- in the current GC. Without overwritin the mode,+ -- the cap could be processed later on as if+ -- it took part in the GC, giving wrong results.+ ModeEnd -> dGC { gcMode = ModeIdle }+ ModeIdle -> dGC+ -- Impossible.+ ModeInit -> error "scanEvents: GlobalSyncGC ModeInit"+ ModeSync{} -> error "scanEvents: GlobalSyncGC ModeSync"+ ModeGHC{} -> error "scanEvents: GlobalSyncGC ModeGHC"+ GCStatsGHC{..} ->+ -- All caps must be stopped. Those that take part in the GC+ -- are in ModeInit or ModeSync, those that do not+ -- are in ModeInit or ModeIdle.+ assert (L.all (notModeStartEtc . gcMode) (IM.elems dGCTable)) $+ sd { dcopied = alterIncrement copied dcopied -- sum over caps+ , dmaxSlop = alterMax slop dmaxSlop -- max over all caps+ , dGCTable = IM.mapWithKey setParSeq dGCTable+ , dparMaxCopied = alterIncrement parMaxCopied dparMaxCopied+ , dparTotCopied = alterIncrement parTotCopied dparTotCopied+ , dmaxParNThreads = alterMax parNThreads dmaxParNThreads+ }+ where+ notModeStartEtc ModeStart = False+ notModeStartEtc ModeGHC{} = False+ notModeStartEtc ModeEnd = False+ notModeStartEtc _ = True+ someInit = L.any ((== ModeInit) . gcMode) (IM.elems dGCTable)+ setParSeq capKey dGC@RtsGC{gcGenStat}+ | someInit =+ -- Just starting the selected interval, so skip the GC.+ dGC+ | otherwise =+ let genGC = IM.findWithDefault emptyGenStat gen gcGenStat+ totGC = IM.findWithDefault emptyGenStat gcGenTot gcGenStat+ in case gcMode dGC of+ -- Cap takes part in seq GC.+ ModeSync capSync | parNThreads == 1 ->+ assert (cap == capSync) $+ dGC { gcMode = ModeGHC cap gen+ , gcGenStat =+ -- Already inserted into gcGenTot in GlobalSyncGC,+ -- so only inserting into gen.+ if capKey == cap+ then IM.insert gen+ genGC{ gcAll = gcAll genGC + 1 }+ gcGenStat+ else gcGenStat+ }+ -- Cap takes part in par GC.+ ModeSync capSync ->+ assert (cap == capSync) $+ assert (parNThreads > 1) $+ dGC { gcMode = ModeGHC cap gen+ , gcGenStat =+ if capKey == cap+ then IM.insert gen+ genGC{ gcAll = gcAll genGC + 1+ , gcPar = gcPar genGC + 1+ }+ (IM.insert gcGenTot+ -- Already incremented gcAll in SyncGC.+ totGC{ gcPar = gcPar totGC + 1 }+ gcGenStat)+ else gcGenStat+ }+ -- Cap not in the current GC, leave it alone.+ ModeIdle -> dGC+ -- Impossible.+ ModeInit -> error "scanEvents: GCStatsGHC ModeInit"+ ModeStart -> error "scanEvents: GCStatsGHC ModeStart"+ ModeGHC{} -> error "scanEvents: GCStatsGHC ModeGHC"+ ModeEnd -> error "scanEvents: GCStatsGHC ModeEnd"+ EndGC ->+ assert (gcMode capGC `notElem` [ModeEnd, ModeIdle]) $+ let endedGC = capGC { gcMode = ModeEnd }+ duration = time - gcStartTime capGC+ timeGC gen gstat =+ let genGC =+ IM.findWithDefault emptyGenStat gen (gcGenStat gstat)+ newGenGC =+ genGC { gcElapsed = gcElapsed genGC + duration+ , gcMaxPause = max (gcMaxPause genGC) duration+ }+ in gstat { gcGenStat = IM.insert gen newGenGC+ (gcGenStat gstat) }+ timeGenTot = timeGC gcGenTot endedGC+ updateMainCap mainCap _ dgm | mainCap /= cap = dgm+ updateMainCap _ currentGen dgm =+ -- We are at the EndGC event of the main cap of current GC.+ -- The timings from this cap are the only that +RTS -s uses.+ -- We will record them in the dGCMain field to be able+ -- to display a look-alike of +RTS -s.+ timeGC currentGen dgm+ in case gcMode capGC of+ -- We don't know the exact timing of this GC started before+ -- the selected interval, so we skip it and clear its mode.+ ModeInit -> sd { dGCTable = IM.insert cap endedGC dGCTable }+ -- There is no GlobalSyncGC nor GCStatsGHC for this GC.+ -- Consequently, we can't determine the main cap,+ -- so skip it and and clear its mode.+ ModeStart -> sd { dGCTable = IM.insert cap endedGC dGCTable }+ -- There is no GCStatsGHC for this GC. Gather partial data.+ ModeSync mainCap ->+ let dgm = fromMaybe (defaultGC time) dGCMain+ mainGenTot = updateMainCap mainCap gcGenTot dgm+ in sd { dGCTable = IM.insert cap timeGenTot dGCTable+ , dGCMain = Just mainGenTot+ }+ -- All is known, so we update the times.+ ModeGHC mainCap gen ->+ let newTime = timeGC gen timeGenTot+ dgm = fromMaybe (defaultGC time) dGCMain+ mainGenTot = updateMainCap mainCap gcGenTot dgm+ newMain = updateMainCap mainCap gen mainGenTot+ in sd { dGCTable = IM.insert cap newTime dGCTable+ , dGCMain = Just newMain+ }+ ModeEnd -> error "scanEvents: EndGC ModeEnd"+ ModeIdle -> error "scanEvents: EndGC ModeIdle"+ SparkCounters crt dud ovf cnv fiz gcd _rem ->+ -- We are guranteed the first spark counters event has all zeroes,+ -- do we don't need to rig the counters for maximal interval.+ let current = RtsSpark crt dud ovf cnv fiz gcd+ in sd { dsparkTable =+ IM.alter (alterCounter current) cap dsparkTable }+ _ -> sd+ in scan (fromJust mcap) statsAccum ev
GUI/Timeline/HEC.hs view
@@ -16,30 +16,36 @@ import qualified GHC.RTS.Events as GHC import GHC.RTS.Events hiding (Event, GCWork, GCIdle) +import qualified Data.IntMap as IM+import Data.Maybe import Control.Monad -renderHEC :: ViewParameters- -> Timestamp -> Timestamp -> (DurationTree,EventTree)+renderHEC :: ViewParameters -> Timestamp -> Timestamp+ -> IM.IntMap String -> (DurationTree,EventTree) -> Render ()-renderHEC params@ViewParameters{..} start end (dtree,etree) = do+renderHEC params@ViewParameters{..} start end perfNames (dtree,etree) = do renderDurations params start end dtree when (scaleValue < detailThreshold) $ case etree of- EventTree ltime etime tree ->- renderEvents params ltime etime start end tree+ EventTree ltime etime tree -> do+ renderEvents params ltime etime start end (fromIntegral detail)+ perfNames tree+ return () renderInstantHEC :: ViewParameters -> Timestamp -> Timestamp- -> EventTree+ -> IM.IntMap String -> EventTree -> Render () renderInstantHEC params@ViewParameters{..} start end- (EventTree ltime etime tree) =- renderEvents params ltime etime start end tree+ perfNames (EventTree ltime etime tree) = do+ let instantDetail = 1+ renderEvents params ltime etime start end instantDetail perfNames tree+ return () detailThreshold :: Double detailThreshold = 3 ---------------------------------------------------------------------------------- hecView draws the trace for a single HEC+-- draws the trace for a single HEC renderDurations :: ViewParameters -> Timestamp -> Timestamp -> DurationTree@@ -56,11 +62,11 @@ | startPos < splitTime && endPos >= splitTime && (fromIntegral (e - s) / scaleValue) <= fromIntegral detail = -- View spans both left and right sub-tree.- -- trace (printf "hecView (average): start:%d end:%d s:%d e:%d" startPos endPos s e) $+ -- trace (printf "renderDurations (average): start:%d end:%d s:%d e:%d" startPos endPos s e) $ drawAverageDuration params s e runAv gcAv | otherwise- = -- trace (printf "hecView: start:%d end:%d s:%d e:%d" startPos endPos s e) $+ = -- trace (printf "renderDurations: start:%d end:%d s:%d e:%d" startPos endPos s e) $ do when (startPos < splitTime) $ renderDurations params startPos endPos lhs when (endPos >= splitTime) $@@ -71,32 +77,47 @@ renderEvents :: ViewParameters -> Timestamp -- start time of this tree node -> Timestamp -- end time of this tree node- -> Timestamp -> Timestamp -> EventNode- -> Render ()+ -> Timestamp -> Timestamp -> Double+ -> IM.IntMap String -> EventNode+ -> Render Bool -renderEvents params@ViewParameters{..} !_s !_e !startPos !endPos- (EventTreeLeaf es)- = sequence_ [ drawEvent params e- | e <- es, let t = time e, t >= startPos && t < endPos ]-renderEvents params@ViewParameters{..} !_s !_e !startPos !endPos- (EventTreeOne ev)- | t >= startPos && t < endPos = drawEvent params ev- | otherwise = return ()+renderEvents params@ViewParameters{..} !_s !_e !startPos !endPos ewidth+ perfNames (EventTreeLeaf es)+ = let within = [ e | e <- es, let t = time e, t >= startPos && t < endPos ]+ untilTrue _ [] = return False+ untilTrue f (x : xs) = do+ b <- f x+ if b then return b else untilTrue f xs+ in untilTrue (drawEvent params ewidth perfNames) within++renderEvents params@ViewParameters{..} !_s !_e !startPos !endPos ewidth+ perfNames (EventTreeOne ev)+ | t >= startPos && t < endPos = drawEvent params ewidth perfNames ev+ | otherwise = return False where t = time ev -renderEvents params@ViewParameters{..} !s !e !startPos !endPos- (EventSplit splitTime lhs rhs)+renderEvents params@ViewParameters{..} !s !e !startPos !endPos ewidth+ perfNames (EventSplit splitTime lhs rhs) | startPos < splitTime && endPos >= splitTime &&- (fromIntegral (e - s) / scaleValue) <= fromIntegral detail- -- was: = drawTooManyEvents params s e- -- is: draw only the right hand side (let's say it overwrites LHS)- = renderEvents params splitTime e startPos endPos rhs-+ (fromIntegral (e - s) / scaleValue) <= ewidth+ = do drawnLhs <-+ renderEvents params s splitTime startPos endPos ewidth perfNames lhs+ if not drawnLhs+ then+ renderEvents params splitTime e startPos endPos ewidth perfNames rhs+ else return True | otherwise- = do when (startPos < splitTime) $- renderEvents params s splitTime startPos endPos lhs- when (endPos >= splitTime) $- renderEvents params splitTime e startPos endPos rhs+ = do drawnLhs <-+ if startPos < splitTime+ then+ renderEvents params s splitTime startPos endPos ewidth perfNames lhs+ else return False+ drawnRhs <-+ if endPos >= splitTime+ then+ renderEvents params splitTime e startPos endPos ewidth perfNames rhs+ else return False+ return $ drawnLhs || drawnRhs ------------------------------------------------------------------------------- -- An event is in view if it is not outside the view.@@ -217,48 +238,56 @@ showText str restore -drawEvent :: ViewParameters -> GHC.Event -> Render ()-drawEvent params@ViewParameters{..} event- = case spec event of- CreateThread{} -> renderInstantEvent params event createThreadColour- RequestSeqGC{} -> renderInstantEvent params event seqGCReqColour- RequestParGC{} -> renderInstantEvent params event parGCReqColour- MigrateThread{} -> renderInstantEvent params event migrateThreadColour- WakeupThread{} -> renderInstantEvent params event threadWakeupColour- Shutdown{} -> renderInstantEvent params event shutdownColour+drawEvent :: ViewParameters -> Double -> IM.IntMap String -> GHC.Event+ -> Render Bool+drawEvent params@ViewParameters{..} ewidth perfNames event =+ let renderI = renderInstantEvent params perfNames event ewidth+ in case spec event of+ CreateThread{} -> renderI createThreadColour+ RequestSeqGC{} -> renderI seqGCReqColour+ RequestParGC{} -> renderI parGCReqColour+ MigrateThread{} -> renderI migrateThreadColour+ WakeupThread{} -> renderI threadWakeupColour+ Shutdown{} -> renderI shutdownColour - SparkCreate{} -> renderInstantEvent params event createdConvertedColour- SparkDud{} -> renderInstantEvent params event fizzledDudsColour- SparkOverflow{} -> renderInstantEvent params event overflowedColour- SparkRun{} -> renderInstantEvent params event createdConvertedColour- SparkSteal{} -> renderInstantEvent params event createdConvertedColour- SparkFizzle{} -> renderInstantEvent params event fizzledDudsColour- SparkGC{} -> renderInstantEvent params event gcColour+ SparkCreate{} -> renderI createdConvertedColour+ SparkDud{} -> renderI fizzledDudsColour+ SparkOverflow{} -> renderI overflowedColour+ SparkRun{} -> renderI createdConvertedColour+ SparkSteal{} -> renderI createdConvertedColour+ SparkFizzle{} -> renderI fizzledDudsColour+ SparkGC{} -> renderI gcColour - UserMessage{} -> renderInstantEvent params event userMessageColour+ UserMessage{} -> renderI userMessageColour - RunThread{} -> return ()- StopThread{} -> return ()- StartGC{} -> return ()+ PerfCounter{} -> renderI createdConvertedColour+ PerfTracepoint{} -> renderI shutdownColour+ PerfName{} -> return False - _ -> return ()+ RunThread{} -> return False+ StopThread{} -> return False+ StartGC{} -> return False -renderInstantEvent :: ViewParameters -> GHC.Event -> Color -> Render ()-renderInstantEvent ViewParameters{..} event color = do+ _ -> return False++renderInstantEvent :: ViewParameters -> IM.IntMap String -> GHC.Event+ -> Double -> Color+ -> Render Bool+renderInstantEvent ViewParameters{..} perfNames event ewidth color = do setSourceRGBAhex color 1.0- setLineWidth (3 * scaleValue)+ setLineWidth (ewidth * scaleValue) let t = time event draw_line (t, hecBarOff-4) (t, hecBarOff+hecBarHeight+4)- labelAt labelsMode t $ showEventInfo (spec event)---_drawTooManyEvents :: ViewParameters -> Timestamp -> Timestamp- -> Render ()-_drawTooManyEvents _params@ViewParameters{..} _start _end = do- return ()--- setSourceRGBAhex grey 1.0--- setLineWidth (3 * scaleValue)--- draw_rectangle start (hecBarOff-4) (end - start) 4--- draw_rectangle start (hecBarOff+hecBarHeight) (end - start) 4+ let numToLabel PerfCounter{perfNum, period} | period == 0 =+ IM.lookup (fromIntegral perfNum) perfNames+ numToLabel PerfCounter{perfNum, period} =+ fmap (++ " <" ++ show (period + 1) ++ " times>") $+ IM.lookup (fromIntegral perfNum) perfNames+ numToLabel PerfTracepoint{perfNum} =+ fmap ("tracepoint: " ++) $ IM.lookup (fromIntegral perfNum) perfNames+ numToLabel _ = Nothing+ showLabel espec = fromMaybe (showEventInfo espec) (numToLabel espec)+ labelAt labelsMode t $ showLabel (spec event)+ return True -------------------------------------------------------------------------------
GUI/Timeline/Render.hs view
@@ -211,10 +211,12 @@ case trace of TraceHEC c -> let (dtree, etree, _) = hecTrees hecs !! c- in renderHEC params startPos endPos (dtree, etree)+ in renderHEC params startPos endPos+ (perfNames hecs) (dtree, etree) TraceInstantHEC c -> let (_, etree, _) = hecTrees hecs !! c- in renderInstantHEC params startPos endPos etree+ in renderInstantHEC params startPos endPos+ (perfNames hecs) etree TraceCreationHEC c -> renderSparkCreation params slice start end (prof !! c) TraceConversionHEC c ->
GUI/Timeline/Ticks.hs view
@@ -61,12 +61,15 @@ drawVRulers tickWidthInPixels scaleValue pos incr endPos height i = if floor pos <= endPos then do when (atMajorTick || atMidTick || tickWidthInPixels > 70) $ do- draw_line (round pos, 0) (round pos, height)+ draw_line (veryRoundedPos, 0) (veryRoundedPos, height) drawVRulers tickWidthInPixels scaleValue (pos + incr) incr endPos height (i + 1) else return () where+ -- Hack to sync with drawXTicks.+ veryRoundedPos = round $+ scaleValue * fromIntegral (floor (fromIntegral (round pos) / scaleValue)) atMidTick = i `mod` 5 == 0 atMajorTick = i `mod` 10 == 0 @@ -91,19 +94,22 @@ renderXScale scaleValue hadjValue lastTx width off xScaleMode = do let scale_width = fromIntegral width * scaleValue startPos :: Timestamp- startPos = truncate hadjValue+ startPos = floor hadjValue+ startLine :: Timestamp+ startLine = floor $ hadjValue / scaleValue endPos :: Timestamp endPos = ceiling $ min (hadjValue + scale_width) (fromIntegral lastTx)+ endLine :: Timestamp+ endLine = ceiling $ min (hadjValue + scale_width) (fromIntegral lastTx)+ / scaleValue save- scale (1/scaleValue) 1.0- translate (-hadjValue) 0+ translate (- fromIntegral startLine) 0 selectFontFace "sans serif" FontSlantNormal FontWeightNormal setFontSize 12 setSourceRGBAhex black 1.0 -- setLineCap LineCapRound -- TODO: breaks rendering currently (see BrokenX.png)- setLineWidth 1.0 -- TODO: it's not really 1 pixel, due to the scale- -- TODO: snap to pixels, currently looks semi-transparent- draw_line (startPos, off 16) (endPos, off 16)+ setLineWidth 1.0+ draw_line (startLine, off 16) (endLine, off 16) let tFor100Pixels = truncate (100 * scaleValue) snappedTickDuration :: Timestamp snappedTickDuration =@@ -113,7 +119,6 @@ tickWidthInPixels = fromIntegral snappedTickDuration / scaleValue firstTick :: Timestamp firstTick = snappedTickDuration * (startPos `div` snappedTickDuration)- setLineWidth scaleValue -- TODO: should be 0.5 pixels (when we rewrite stuff) case xScaleMode of XScaleTime -> drawXTicks tickWidthInPixels scaleValue (fromIntegral firstTick)@@ -129,19 +134,16 @@ -> Render () drawXTicks tickWidthInPixels scaleValue pos incr endPos off xScaleMode i = if floor pos <= endPos then do- -- TODO: snap to pixels, currently looks semi-transparent when (pos /= 0 || xScaleMode == XScaleTime) $- draw_line (x1, off 16) (x1, off (16 - tickLength))+ draw_line (floor $ fromIntegral x1 / scaleValue, off 16)+ (floor $ fromIntegral x1 / scaleValue, off (16 - tickLength)) when (atMajorTick || atMidTick || tickWidthInPixels > 70) $ do tExtent <- textExtents tickTimeText let tExtentWidth = textExtentsWidth tExtent- move_to textPos- m <- getMatrix- identityMatrix+ move_to (floor $ fromIntegral textPosX / scaleValue, textPosY) when (floor (pos + incr) <= endPos && (tExtentWidth + tExtentWidth / 3 < width || atMajorTick)) $ showText tickTimeText- setMatrix m drawXTicks tickWidthInPixels scaleValue (pos + incr) incr endPos off xScaleMode (i+1) else@@ -149,7 +151,7 @@ where atMidTick = xScaleMode == XScaleTime && i `mod` 5 == 0 atMajorTick = xScaleMode == XScaleTime && i `mod` 10 == 0- textPos =+ (textPosX, textPosY) = if xScaleMode == XScaleTime then (x1 + ceiling (scaleValue * 3), off (-3)) else (x1 + ceiling (scaleValue * 2), tickLength + 13)@@ -157,7 +159,7 @@ | atMidTick = 10 | otherwise = if xScaleMode == XScaleTime then 6 else 8 posTime = case xScaleMode of- XScaleTime -> round pos+ XScaleTime -> round pos XScaleLog minX _ -> round $ 2 ** (minX + pos / incr) tickTimeText = showMultiTime posTime width = if atMidTick then 5 * tickWidthInPixels@@ -257,11 +259,14 @@ | atMidTick = 9 | otherwise = 6 reformatV :: Double -> String- reformatV v = deZero (printf "%.2f" v)+ reformatV v =+ if v < 0.01 && v > 0+ then eps+ else deZero (printf "%.2f" v) ------------------------------------------------------------------------------- --- | The 'micro' symbol.+-- | The \'micro\' symbol. mu :: String #if MIN_VERSION_cairo(0,12,0) && !MIN_VERSION_cairo(0,12,1) -- this version of cairo doesn't handle Unicode properly.@@ -271,6 +276,18 @@ -- Haskell cairo bindings 0.12.1 have proper Unicode support mu = "\x00b5" #endif++-- | The \'epsilon\' symbol.+eps :: String+#if MIN_VERSION_cairo(0,12,0) && !MIN_VERSION_cairo(0,12,1)+-- this version of cairo doesn't handle Unicode properly.+-- Thus, we do the encoding by hand:+eps = "\206\181"+#else+-- Haskell cairo bindings 0.12.1 have proper Unicode support+eps = "\x03b5"+#endif+ -- | Remove all meaningless trailing zeroes. deZero :: String -> String
GUI/ViewerColours.hs view
@@ -43,7 +43,7 @@ shutdownColour = darkBrown labelTextColour :: Color-labelTextColour = black+labelTextColour = white bookmarkColour :: Color bookmarkColour = Color 0xff00 0x0000 0xff00 -- pinkish
LICENSE view
@@ -1,31 +1,31 @@-The Glasgow Haskell Compiler License - -Copyright 2002, The University Court of the University of Glasgow. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. - -- Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -- Neither name of the University nor the names of its contributors may be -used to endorse or promote products derived from this software without -specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF -GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. +The Glasgow Haskell Compiler License++Copyright 2002-2012, The University Court of the University of Glasgow+and others. All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++- Redistributions of source code must retain the above copyright notice,+this list of conditions and the following disclaimer.++- Redistributions in binary form must reproduce the above copyright notice,+this list of conditions and the following disclaimer in the documentation+and/or other materials provided with the distribution.++- Neither name of the University nor the names of its contributors may be+used to endorse or promote products derived from this software without+specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF+GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH+DAMAGE.
threadscope.cabal view
@@ -1,5 +1,5 @@ Name: threadscope-Version: 0.2.1+Version: 0.2.2 Category: Development, Profiling, Trace Synopsis: A graphical tool for profiling parallel Haskell programs. Description: ThreadScope is a graphical viewer for thread profile@@ -16,9 +16,9 @@ Copyright: 2009-2010 Satnam Singh, 2009-2011 Simon Marlow, 2009 Donnie Jones,- 2011 Duncan Coutts,- 2011 Mikolaj Konarski- 2011 Nicolas Wu+ 2011-2012 Duncan Coutts,+ 2011-2012 Mikolaj Konarski,+ 2011 Nicolas Wu, 2011 Eric Kow Author: Satnam Singh <s.singh@ieee.org>, Simon Marlow <marlowsd@gmail.com>,@@ -27,7 +27,7 @@ Mikolaj Konarski <mikolaj@well-typed.com>, Nicolas Wu <nick@well-typed.com>, Eric Kow <eric@well-typed.com>-Maintainer: Satnam Singh <s.singh@ieee.org>+Maintainer: Simon Marlow <marlowsd@gmail.com> Homepage: http://www.haskell.org/haskellwiki/ThreadScope Bug-reports: http://trac.haskell.org/ThreadScope/ Build-Type: Simple@@ -43,8 +43,8 @@ Build-Depends: base >= 4.0 && < 5, gtk >= 0.12, cairo, glib, pango, binary, array, mtl, filepath,- ghc-events == 0.4.*,- containers >= 0.2 && < 0.5,+ ghc-events >= 0.4.2,+ containers >= 0.2 && < 0.6, deepseq >= 1.1, time >= 1.1 Extensions: RecordWildCards, NamedFieldPuns, BangPatterns, PatternGuards@@ -92,4 +92,4 @@ ghc-options: -fno-warn-unused-matches if !os(windows)- build-depends: unix >= 2.3 && < 2.6+ build-depends: unix >= 2.3 && < 2.7
threadscope.ui view
@@ -1,1158 +1,1800 @@ <?xml version="1.0" encoding="UTF-8"?> <interface> <requires lib="gtk+" version="2.16"/>- <!-- interface-naming-policy toplevel-contextual -->- <object class="GtkAdjustment" id="adjustment1"/>- <object class="GtkImage" id="image1">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="stock">gtk-refresh</property>- </object>- <object class="GtkImage" id="image2">- <property name="visible">True</property>- <property name="can_focus">False</property>- </object>- <object class="GtkImage" id="image3">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="stock">gtk-save-as</property>- </object>- <object class="GtkImage" id="image4">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="stock">gtk-goto-first</property>- </object>- <object class="GtkImage" id="image5">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="stock">gtk-home</property>- </object>- <object class="GtkImage" id="image6">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="stock">gtk-goto-last</property>- </object>- <object class="GtkImage" id="image7">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="stock">gtk-zoom-in</property>- </object>- <object class="GtkImage" id="image8">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="stock">gtk-zoom-out</property>- </object>- <object class="GtkImage" id="image9">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="stock">gtk-zoom-fit</property>- </object>- <object class="GtkWindow" id="main_window">- <property name="width_request">600</property>- <property name="height_request">400</property>- <property name="can_focus">True</property>- <property name="title" translatable="yes">ThreadScope</property>- <property name="default_width">1200</property>- <property name="default_height">600</property>- <child>- <object class="GtkVBox" id="vbox1">- <property name="visible">True</property>- <property name="can_focus">False</property>- <child>- <object class="GtkMenuBar" id="menubar1">- <property name="visible">True</property>- <property name="can_focus">False</property>- <child>- <object class="GtkMenuItem" id="menuitem1">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="label" translatable="yes">_File</property>- <property name="use_underline">True</property>- <child type="submenu">- <object class="GtkMenu" id="menu1">- <property name="visible">True</property>- <property name="can_focus">False</property>- <child>- <object class="GtkImageMenuItem" id="openMenuItem">- <property name="label">gtk-open</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="use_stock">True</property>- <accelerator key="o" signal="activate" modifiers="GDK_CONTROL_MASK"/>- </object>- </child>- <child>- <object class="GtkImageMenuItem" id="exportMenuItem">- <property name="label" translatable="yes">Export image...</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="image">image2</property>- <property name="use_stock">False</property>- </object>- </child>- <child>- <object class="GtkSeparatorMenuItem" id="separatormenuitem1">- <property name="visible">True</property>- <property name="can_focus">False</property>- </object>- </child>- <child>- <object class="GtkImageMenuItem" id="quitMenuItem">- <property name="label">gtk-quit</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="use_stock">True</property>- <accelerator key="q" signal="activate" modifiers="GDK_CONTROL_MASK"/>- </object>- </child>- </object>- </child>- </object>- </child>- <child>- <object class="GtkMenuItem" id="menuitem2">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="label" translatable="yes">_View</property>- <property name="use_underline">True</property>- <child type="submenu">- <object class="GtkMenu" id="menu2">- <property name="visible">True</property>- <property name="can_focus">False</property>- <child>- <object class="GtkCheckMenuItem" id="view_sidebar">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="label" translatable="yes">Sidebar</property>- <property name="use_underline">True</property>- <property name="active">True</property>- </object>- </child>- <child>- <object class="GtkCheckMenuItem" id="view_events">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="label" translatable="yes">Information pane</property>- <property name="use_underline">True</property>- <property name="active">True</property>- </object>- </child>- <child>- <object class="GtkCheckMenuItem" id="black_and_white">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="label" translatable="yes">Black & white</property>- <property name="use_underline">True</property>- </object>- </child>- <child>- <object class="GtkCheckMenuItem" id="view_labels_mode">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="label" translatable="yes">Event labels</property>- <property name="use_underline">True</property>- </object>- </child>- <child>- <object class="GtkSeparatorMenuItem" id="separatormenuitem2">- <property name="visible">True</property>- <property name="can_focus">False</property>- </object>- </child>- <child>- <object class="GtkImageMenuItem" id="view_reload">- <property name="label">_Reload</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="image">image1</property>- <property name="use_stock">False</property>- <accelerator key="r" signal="activate" modifiers="GDK_CONTROL_MASK"/>- </object>- </child>- </object>- </child>- </object>- </child>- <child>- <object class="GtkMenuItem" id="menuitem2dot5">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="label" translatable="yes">_Move</property>- <property name="use_underline">True</property>- <child type="submenu">- <object class="GtkMenu" id="menu2dot5">- <property name="visible">True</property>- <property name="can_focus">False</property>- <child>- <object class="GtkImageMenuItem" id="move_first">- <property name="label" translatable="yes">Jump to start</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="image">image4</property>- <property name="use_stock">False</property>- </object>- </child>- <child>- <object class="GtkImageMenuItem" id="move_centre">- <property name="label" translatable="yes">Centre on cursor</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="image">image5</property>- <property name="use_stock">False</property>- </object>- </child>- <child>- <object class="GtkImageMenuItem" id="move_last">- <property name="label" translatable="yes">Jump to end</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="image">image6</property>- <property name="use_stock">False</property>- </object>- </child>- <child>- <object class="GtkSeparatorMenuItem" id="separatormenuitem2dot5">- <property name="visible">True</property>- <property name="can_focus">False</property>- </object>- </child>- <child>- <object class="GtkImageMenuItem" id="move_zoomin">- <property name="label" translatable="yes">Zoom in</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="image">image7</property>- <property name="use_stock">False</property>- </object>- </child>- <child>- <object class="GtkImageMenuItem" id="move_zoomout">- <property name="label" translatable="yes">Zoom out</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="image">image8</property>- <property name="use_stock">False</property>- </object>- </child>- <child>- <object class="GtkImageMenuItem" id="move_zoomfit">- <property name="label" translatable="yes">Fit to window</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="image">image9</property>- <property name="use_stock">False</property>- </object>- </child>- </object>- </child>- </object>- </child>- <child>- <object class="GtkMenuItem" id="menuitem3">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="label" translatable="yes">Help</property>- <property name="use_underline">True</property>- <child type="submenu">- <object class="GtkMenu" id="menu3">- <property name="visible">True</property>- <property name="can_focus">False</property>- <child>- <object class="GtkMenuItem" id="tutorialMenuItem">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="label" translatable="yes">Online tutorial</property>- <property name="use_underline">True</property>- </object>- </child>- <child>- <object class="GtkMenuItem" id="websiteMenuItem">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="label" translatable="yes">Website</property>- <property name="use_underline">True</property>- </object>- </child>- <child>- <object class="GtkSeparatorMenuItem" id="menuitem5">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- </object>- </child>- <child>- <object class="GtkImageMenuItem" id="aboutMenuItem">- <property name="label">gtk-about</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="use_stock">True</property>- </object>- </child>- </object>- </child>- </object>- </child>- </object>- <packing>- <property name="expand">False</property>- <property name="fill">True</property>- <property name="position">0</property>- </packing>- </child>- <child>- <object class="GtkToolbar" id="toolbar2">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="toolbar_style">both-horiz</property>- <property name="show_arrow">False</property>- <child>- <object class="GtkToolButton" id="cpus_open">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="tooltip_text" translatable="yes">Open an eventlog</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="stock_id">gtk-open</property>- </object>- <packing>- <property name="expand">False</property>- <property name="homogeneous">True</property>- </packing>- </child>- <child>- <object class="GtkSeparatorToolItem" id="separatortoolitem5dot5">- <property name="visible">True</property>- <property name="can_focus">False</property>- </object>- <packing>- <property name="expand">False</property>- </packing>- </child>- <child>- <object class="GtkToolButton" id="cpus_first">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="tooltip_text" translatable="yes">Jump to the start</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="stock_id">gtk-goto-first</property>- </object>- <packing>- <property name="expand">False</property>- <property name="homogeneous">True</property>- </packing>- </child>- <child>- <object class="GtkToolButton" id="cpus_centre">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="tooltip_text" translatable="yes">Centre view on the cursor</property>- <property name="use_action_appearance">False</property>- <property name="stock_id">gtk-home</property>- </object>- <packing>- <property name="expand">False</property>- <property name="homogeneous">True</property>- </packing>- </child>- <child>- <object class="GtkToolButton" id="cpus_last">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="tooltip_text" translatable="yes">Jump to the end</property>- <property name="use_action_appearance">False</property>- <property name="use_underline">True</property>- <property name="stock_id">gtk-goto-last</property>- </object>- <packing>- <property name="expand">False</property>- <property name="homogeneous">True</property>- </packing>- </child>- <child>- <object class="GtkSeparatorToolItem" id="separatortoolitem5">- <property name="visible">True</property>- <property name="can_focus">False</property>- </object>- <packing>- <property name="expand">False</property>- </packing>- </child>- <child>- <object class="GtkToolButton" id="cpus_zoomin">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="tooltip_text" translatable="yes">Zoom in</property>- <property name="use_action_appearance">False</property>- <property name="stock_id">gtk-zoom-in</property>- </object>- <packing>- <property name="expand">False</property>- <property name="homogeneous">True</property>- </packing>- </child>- <child>- <object class="GtkToolButton" id="cpus_zoomout">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="tooltip_text" translatable="yes">Zoom out</property>- <property name="use_action_appearance">False</property>- <property name="stock_id">gtk-zoom-out</property>- </object>- <packing>- <property name="expand">False</property>- <property name="homogeneous">True</property>- </packing>- </child>- <child>- <object class="GtkToolButton" id="cpus_zoomfit">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="tooltip_text" translatable="yes">Fit view to the window</property>- <property name="use_action_appearance">False</property>- <property name="stock_id">gtk-zoom-fit</property>- </object>- <packing>- <property name="expand">False</property>- <property name="homogeneous">True</property>- </packing>- </child>- </object>- <packing>- <property name="expand">False</property>- <property name="fill">False</property>- <property name="position">1</property>- </packing>- </child>- <child>- <object class="GtkHPaned" id="hpaned">- <property name="visible">True</property>- <property name="can_focus">True</property>- <child>- <object class="GtkNotebook" id="sidebar">- <property name="visible">True</property>- <property name="can_focus">True</property>- <child>- <object class="GtkScrolledWindow" id="scrolledwindow2">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="hscrollbar_policy">automatic</property>- <property name="vscrollbar_policy">automatic</property>- <child>- <object class="GtkTreeView" id="key_list">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="headers_visible">False</property>- <property name="enable_search">False</property>- </object>- </child>- </object>- </child>- <child type="tab">- <object class="GtkLabel" id="label5">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="label" translatable="yes">Key</property>- </object>- <packing>- <property name="position">2</property>- <property name="tab_fill">False</property>- </packing>- </child>- <child>- <object class="GtkScrolledWindow" id="scrolledwindow1">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="hscrollbar_policy">automatic</property>- <property name="vscrollbar_policy">automatic</property>- <child>- <object class="GtkTreeView" id="traces_tree">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="headers_visible">False</property>- </object>- </child>- </object>- <packing>- <property name="position">1</property>- </packing>- </child>- <child type="tab">- <object class="GtkLabel" id="label1">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="label" translatable="yes">Traces</property>- </object>- <packing>- <property name="position">1</property>- <property name="tab_fill">False</property>- </packing>- </child>- <child>- <object class="GtkVBox" id="bookmarks_vbox">- <property name="visible">True</property>- <property name="can_focus">False</property>- <child>- <object class="GtkToolbar" id="toolbar3">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="toolbar_style">both-horiz</property>- <property name="show_arrow">False</property>- <child>- <object class="GtkToolButton" id="goto_bookmark_button">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="is_important">True</property>- <property name="stock_id">gtk-jump-to</property>- </object>- <packing>- <property name="expand">False</property>- <property name="homogeneous">True</property>- </packing>- </child>- <child>- <object class="GtkToolButton" id="add_bookmark_button">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="label" translatable="yes">Bookmark</property>- <property name="use_underline">True</property>- <property name="stock_id">gtk-add</property>- </object>- <packing>- <property name="expand">False</property>- <property name="homogeneous">True</property>- </packing>- </child>- <child>- <object class="GtkToolButton" id="delete_bookmark">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="use_action_appearance">False</property>- <property name="stock_id">gtk-remove</property>- </object>- <packing>- <property name="expand">False</property>- <property name="homogeneous">True</property>- </packing>- </child>- </object>- <packing>- <property name="expand">False</property>- <property name="fill">False</property>- <property name="position">0</property>- </packing>- </child>- <child>- <object class="GtkScrolledWindow" id="bookmark_list_scrolled_window">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="hscrollbar_policy">automatic</property>- <property name="vscrollbar_policy">automatic</property>- <child>- <object class="GtkTreeView" id="bookmark_list">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="headers_clickable">False</property>- </object>- </child>- </object>- <packing>- <property name="expand">True</property>- <property name="fill">True</property>- <property name="position">1</property>- </packing>- </child>- </object>- <packing>- <property name="position">2</property>- </packing>- </child>- <child type="tab">- <object class="GtkLabel" id="label2">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="label" translatable="yes">Bookmarks</property>- </object>- <packing>- <property name="position">2</property>- <property name="tab_fill">False</property>- </packing>- </child>- </object>- <packing>- <property name="resize">False</property>- <property name="shrink">True</property>- </packing>- </child>- <child>- <object class="GtkVPaned" id="vpaned1">- <property name="visible">True</property>- <property name="can_focus">True</property>- <child>- <object class="GtkVBox" id="timelinebox">- <property name="visible">True</property>- <property name="can_focus">False</property>- <child>- <object class="GtkLabel" id="label3">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="xalign">0</property>- <property name="xpad">4</property>- <property name="ypad">4</property>- <property name="label" translatable="yes"><b>Timeline</b></property>- <property name="use_markup">True</property>- </object>- <packing>- <property name="expand">False</property>- <property name="fill">False</property>- <property name="position">0</property>- </packing>- </child>- <child>- <object class="GtkTable" id="table1">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="n_rows">2</property>- <property name="n_columns">2</property>- <property name="column_spacing">3</property>- <property name="row_spacing">3</property>- <child>- <object class="GtkVScrollbar" id="timeline_vscroll">- <property name="visible">True</property>- <property name="can_focus">False</property>- </object>- <packing>- <property name="left_attach">1</property>- <property name="right_attach">2</property>- <property name="x_options">GTK_SHRINK | GTK_FILL</property>- </packing>- </child>- <child>- <object class="GtkHScrollbar" id="timeline_hscroll">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="restrict_to_fill_level">False</property>- <property name="fill_level">0</property>- </object>- <packing>- <property name="top_attach">1</property>- <property name="bottom_attach">2</property>- <property name="y_options">GTK_SHRINK</property>- </packing>- </child>- <child>- <object class="GtkViewport" id="timeline_viewport">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="has_focus">True</property>- <property name="events">GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>- <property name="resize_mode">queue</property>- <child>- <object class="GtkTable" id="table2">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="n_rows">2</property>- <property name="n_columns">2</property>- <child>- <object class="GtkDrawingArea" id="timeline_yscale_area">- <property name="width_request">110</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- </object>- <packing>- <property name="top_attach">1</property>- <property name="bottom_attach">2</property>- <property name="x_options">GTK_SHRINK</property>- </packing>- </child>- <child>- <object class="GtkDrawingArea" id="timeline_xscale_area">- <property name="height_request">38</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- </object>- <packing>- <property name="left_attach">1</property>- <property name="right_attach">2</property>- <property name="y_options">GTK_SHRINK</property>- </packing>- </child>- <child>- <object class="GtkDrawingArea" id="timeline_drawingarea">- <property name="visible">True</property>- <property name="can_focus">True</property>- </object>- <packing>- <property name="left_attach">1</property>- <property name="right_attach">2</property>- <property name="top_attach">1</property>- <property name="bottom_attach">2</property>- </packing>- </child>- <child>- <placeholder/>- </child>- </object>- </child>- </object>- </child>- <child>- <placeholder/>- </child>- </object>- <packing>- <property name="expand">True</property>- <property name="fill">True</property>- <property name="position">1</property>- </packing>- </child>- </object>- <packing>- <property name="resize">True</property>- <property name="shrink">True</property>- </packing>- </child>- <child>- <object class="GtkNotebook" id="eventsbox">- <property name="visible">True</property>- <property name="can_focus">True</property>- <child>- <object class="GtkScrolledWindow" id="scrolledwindowSummary">- <property name="can_focus">True</property>- <property name="no_show_all">True</property>- <property name="hscrollbar_policy">automatic</property>- <property name="vscrollbar_policy">automatic</property>- <child>- <object class="GtkLayout" id="eventsLayoutSummary">- <property name="visible">True</property>- <property name="can_focus">False</property>- </object>- </child>- </object>- <packing>- <property name="reorderable">True</property>- </packing>- </child>- <child type="tab">- <object class="GtkLabel" id="label7">- <property name="can_focus">False</property>- <property name="no_show_all">True</property>- <property name="label" translatable="yes">Summary stats</property>- </object>- <packing>- <property name="tab_fill">False</property>- </packing>- </child>- <child>- <object class="GtkScrolledWindow" id="scrolledwindow3">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="hscrollbar_policy">automatic</property>- <property name="vscrollbar_policy">automatic</property>- <child>- <object class="GtkViewport" id="viewport1">- <property name="visible">True</property>- <property name="can_focus">False</property>- <child>- <object class="GtkTable" id="table4">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="border_width">4</property>- <property name="n_rows">5</property>- <property name="n_columns">2</property>- <property name="column_spacing">8</property>- <property name="row_spacing">4</property>- <child>- <object class="GtkLabel" id="label9">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="xalign">0</property>- <property name="yalign">0</property>- <property name="label" translatable="yes">Executable:</property>- </object>- <packing>- <property name="x_options">GTK_FILL</property>- <property name="y_options">GTK_FILL</property>- </packing>- </child>- <child>- <object class="GtkLabel" id="label10">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="xalign">0</property>- <property name="yalign">0</property>- <property name="label" translatable="yes">Arguments:</property>- </object>- <packing>- <property name="top_attach">1</property>- <property name="bottom_attach">2</property>- <property name="x_options">GTK_FILL</property>- <property name="y_options">GTK_FILL</property>- </packing>- </child>- <child>- <object class="GtkLabel" id="label11">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="xalign">0</property>- <property name="yalign">0</property>- <property name="label" translatable="yes">Start time:</property>- </object>- <packing>- <property name="top_attach">2</property>- <property name="bottom_attach">3</property>- <property name="x_options">GTK_FILL</property>- <property name="y_options">GTK_FILL</property>- </packing>- </child>- <child>- <object class="GtkLabel" id="label12">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="xalign">0</property>- <property name="yalign">0</property>- <property name="label" translatable="yes">RTS Id:</property>- </object>- <packing>- <property name="top_attach">3</property>- <property name="bottom_attach">4</property>- <property name="x_options">GTK_FILL</property>- <property name="y_options">GTK_FILL</property>- </packing>- </child>- <child>- <object class="GtkLabel" id="label13">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="xalign">0</property>- <property name="yalign">0</property>- <property name="label" translatable="yes">Environment:</property>- </object>- <packing>- <property name="top_attach">4</property>- <property name="bottom_attach">5</property>- <property name="x_options">GTK_FILL</property>- <property name="y_options">GTK_FILL</property>- </packing>- </child>- <child>- <object class="GtkLabel" id="labelProgName">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="tooltip_text" translatable="yes">The name and path of the program's executable file</property>- <property name="xalign">0</property>- <property name="yalign">0</property>- <property name="selectable">True</property>- </object>- <packing>- <property name="left_attach">1</property>- <property name="right_attach">2</property>- <property name="y_options">GTK_FILL</property>- </packing>- </child>- <child>- <object class="GtkLabel" id="labelProgStartTime">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="tooltip_text" translatable="yes">The time at which the program was started</property>- <property name="xalign">0</property>- <property name="yalign">0</property>- <property name="selectable">True</property>- </object>- <packing>- <property name="left_attach">1</property>- <property name="right_attach">2</property>- <property name="top_attach">2</property>- <property name="bottom_attach">3</property>- <property name="y_options">GTK_FILL</property>- </packing>- </child>- <child>- <object class="GtkScrolledWindow" id="scrolledwindow4">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="hscrollbar_policy">automatic</property>- <property name="vscrollbar_policy">automatic</property>- <child>- <object class="GtkTreeView" id="treeviewProgArguments">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="tooltip_text" translatable="yes">The arguments supplied when the program was run</property>- <property name="headers_visible">False</property>- </object>- </child>- </object>- <packing>- <property name="left_attach">1</property>- <property name="right_attach">2</property>- <property name="top_attach">1</property>- <property name="bottom_attach">2</property>- </packing>- </child>- <child>- <object class="GtkScrolledWindow" id="scrolledwindow5">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="hscrollbar_policy">automatic</property>- <property name="vscrollbar_policy">automatic</property>- <child>- <object class="GtkTreeView" id="treeviewProgEnvironment">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="tooltip_text" translatable="yes">The environment variables available when the program was started</property>- <property name="headers_visible">False</property>- </object>- </child>- </object>- <packing>- <property name="left_attach">1</property>- <property name="right_attach">2</property>- <property name="top_attach">4</property>- <property name="bottom_attach">5</property>- </packing>- </child>- <child>- <object class="GtkLabel" id="labelProgRtsIdentifier">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="tooltip_text" translatable="yes">The name and version of the compiler/runtime used by the program</property>- <property name="xalign">0</property>- <property name="yalign">0</property>- <property name="selectable">True</property>- </object>- <packing>- <property name="left_attach">1</property>- <property name="right_attach">2</property>- <property name="top_attach">3</property>- <property name="bottom_attach">4</property>- <property name="y_options">GTK_FILL</property>- </packing>- </child>- </object>- </child>- </object>- </child>- </object>- <packing>- <property name="position">1</property>- </packing>- </child>- <child type="tab">- <object class="GtkLabel" id="label8">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="label" translatable="yes">Startup info</property>- </object>- <packing>- <property name="position">1</property>- <property name="tab_fill">False</property>- </packing>- </child>- <child>- <object class="GtkTable" id="table3">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="n_columns">2</property>- <child>- <object class="GtkDrawingArea" id="timeline_yscale_area2">- <property name="width_request">110</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- </object>- <packing>- <property name="top_attach">1</property>- <property name="bottom_attach">2</property>- <property name="x_options">GTK_SHRINK</property>- </packing>- </child>- <child>- <object class="GtkDrawingArea" id="histogram_drawingarea">- <property name="visible">True</property>- <property name="can_focus">True</property>- </object>- <packing>- <property name="left_attach">1</property>- <property name="right_attach">2</property>- <property name="top_attach">1</property>- <property name="bottom_attach">2</property>- </packing>- </child>- <child>- <placeholder/>- </child>- <child>- <placeholder/>- </child>- </object>- <packing>- <property name="position">2</property>- <property name="reorderable">True</property>- </packing>- </child>- <child type="tab">- <object class="GtkLabel" id="label6">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="label" translatable="yes">Spark sizes</property>- </object>- <packing>- <property name="position">2</property>- <property name="tab_fill">False</property>- </packing>- </child>- <child>- <object class="GtkVBox" id="eventsbox_old">- <property name="visible">True</property>- <property name="can_focus">False</property>- <child>- <object class="GtkEntry" id="events_entry">- <property name="visible">True</property>- <property name="can_focus">True</property>- <property name="invisible_char">●</property>- <property name="width_chars">20</property>- <property name="secondary_icon_stock">gtk-find</property>- <property name="primary_icon_activatable">False</property>- <property name="secondary_icon_activatable">False</property>- <property name="primary_icon_sensitive">True</property>- <property name="secondary_icon_sensitive">True</property>- <property name="secondary_icon_tooltip_text">Search for event</property>- </object>- <packing>- <property name="expand">False</property>- <property name="fill">True</property>- <property name="position">1</property>- </packing>- </child>- <child>- <object class="GtkHBox" id="eventsHBox">- <property name="height_request">120</property>- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="spacing">3</property>- <child>- <object class="GtkViewport" id="viewport2">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="resize_mode">queue</property>- <child>- <object class="GtkDrawingArea" id="eventsDrawingArea">- <property name="visible">True</property>- <property name="can_focus">True</property>- </object>- </child>- </object>- <packing>- <property name="expand">True</property>- <property name="fill">True</property>- <property name="position">0</property>- </packing>- </child>- <child>- <object class="GtkVScrollbar" id="eventsVScroll">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="adjustment">adjustment1</property>- </object>- <packing>- <property name="expand">False</property>- <property name="fill">True</property>- <property name="position">1</property>- </packing>- </child>- </object>- <packing>- <property name="expand">True</property>- <property name="fill">True</property>- <property name="position">2</property>- </packing>- </child>- </object>- <packing>- <property name="position">3</property>- <property name="reorderable">True</property>- </packing>- </child>- <child type="tab">- <object class="GtkLabel" id="label4">- <property name="visible">True</property>- <property name="can_focus">False</property>- <property name="label" translatable="yes">Raw events</property>- </object>- <packing>- <property name="position">3</property>- <property name="tab_fill">False</property>- </packing>- </child>- </object>- <packing>- <property name="resize">False</property>- <property name="shrink">True</property>- </packing>- </child>- </object>- <packing>- <property name="resize">True</property>- <property name="shrink">True</property>- </packing>- </child>- </object>- <packing>- <property name="expand">True</property>- <property name="fill">True</property>- <property name="position">2</property>- </packing>- </child>- <child>- <object class="GtkStatusbar" id="statusbar">- <property name="visible">True</property>- <property name="can_focus">False</property>- </object>- <packing>- <property name="expand">False</property>- <property name="fill">True</property>- <property name="position">3</property>- </packing>- </child>- </object>- </child>- </object>- <object class="GtkListStore" id="sidebar_items">- <columns>- <!-- column-name name -->- <column type="gchararray"/>- </columns>+ <object class="GtkAdjustment" id="adjustment1"/>+ <object class="GtkImage" id="image1">+ <property name="visible">True</property>+ <property name="stock">gtk-refresh</property>+ </object>+ <object class="GtkImage" id="image2">+ <property name="visible">True</property>+ <property name="stock">gtk-save-as</property>+ </object>+ <object class="GtkImage" id="image4">+ <property name="visible">True</property>+ <property name="stock">gtk-goto-first</property>+ </object>+ <object class="GtkImage" id="image5">+ <property name="visible">True</property>+ <property name="stock">gtk-home</property>+ </object>+ <object class="GtkImage" id="image6">+ <property name="visible">True</property>+ <property name="stock">gtk-goto-last</property>+ </object>+ <object class="GtkImage" id="image7">+ <property name="visible">True</property>+ <property name="stock">gtk-zoom-in</property>+ </object>+ <object class="GtkImage" id="image8">+ <property name="visible">True</property>+ <property name="stock">gtk-zoom-out</property>+ </object>+ <object class="GtkImage" id="image9">+ <property name="visible">True</property>+ <property name="stock">gtk-zoom-fit</property>+ </object>+ <object class="GtkWindow" id="main_window">+ <property name="width_request">600</property>+ <property name="height_request">400</property>+ <property name="can_focus">True</property>+ <property name="title" translatable="yes">ThreadScope</property>+ <property name="default_width">1200</property>+ <property name="default_height">600</property>+ <child>+ <object class="GtkVBox" id="vbox1">+ <property name="visible">True</property>+ <child>+ <object class="GtkMenuBar" id="menubar1">+ <property name="visible">True</property>+ <child>+ <object class="GtkMenuItem" id="menuitem1">+ <property name="visible">True</property>+ <property name="label" translatable="yes">_File</property>+ <property name="use_underline">True</property>+ <child type="submenu">+ <object class="GtkMenu" id="menu1">+ <property name="visible">True</property>+ <child>+ <object class="GtkImageMenuItem" id="openMenuItem">+ <property name="label">gtk-open</property>+ <property name="visible">True</property>+ <property name="use_underline">True</property>+ <property name="use_stock">True</property>+ <accelerator key="o" signal="activate" modifiers="GDK_CONTROL_MASK"/>+ </object>+ </child>+ <child>+ <object class="GtkImageMenuItem" id="exportMenuItem">+ <property name="label" translatable="yes">Export image...</property>+ <property name="visible">True</property>+ <property name="image">image2</property>+ <property name="use_stock">False</property>+ </object>+ </child>+ <child>+ <object class="GtkSeparatorMenuItem" id="separatormenuitem1">+ <property name="visible">True</property>+ </object>+ </child>+ <child>+ <object class="GtkImageMenuItem" id="quitMenuItem">+ <property name="label">gtk-quit</property>+ <property name="visible">True</property>+ <property name="use_underline">True</property>+ <property name="use_stock">True</property>+ <accelerator key="q" signal="activate" modifiers="GDK_CONTROL_MASK"/>+ </object>+ </child>+ </object>+ </child>+ </object>+ </child>+ <child>+ <object class="GtkMenuItem" id="menuitem2">+ <property name="visible">True</property>+ <property name="label" translatable="yes">_View</property>+ <property name="use_underline">True</property>+ <child type="submenu">+ <object class="GtkMenu" id="menu2">+ <property name="visible">True</property>+ <child>+ <object class="GtkCheckMenuItem" id="view_sidebar">+ <property name="visible">True</property>+ <property name="label" translatable="yes">Sidebar</property>+ <property name="use_underline">True</property>+ <property name="active">True</property>+ </object>+ </child>+ <child>+ <object class="GtkCheckMenuItem" id="view_events">+ <property name="visible">True</property>+ <property name="label" translatable="yes">Information pane</property>+ <property name="use_underline">True</property>+ <property name="active">True</property>+ </object>+ </child>+ <child>+ <object class="GtkCheckMenuItem" id="black_and_white">+ <property name="visible">True</property>+ <property name="label" translatable="yes">Black & white</property>+ <property name="use_underline">True</property>+ </object>+ </child>+ <child>+ <object class="GtkCheckMenuItem" id="view_labels_mode">+ <property name="visible">True</property>+ <property name="label" translatable="yes">Event labels</property>+ <property name="use_underline">True</property>+ </object>+ </child>+ <child>+ <object class="GtkSeparatorMenuItem" id="separatormenuitem2">+ <property name="visible">True</property>+ </object>+ </child>+ <child>+ <object class="GtkImageMenuItem" id="view_reload">+ <property name="label">_Reload</property>+ <property name="visible">True</property>+ <property name="use_underline">True</property>+ <property name="image">image1</property>+ <property name="use_stock">False</property>+ <accelerator key="r" signal="activate" modifiers="GDK_CONTROL_MASK"/>+ </object>+ </child>+ </object>+ </child>+ </object>+ </child>+ <child>+ <object class="GtkMenuItem" id="menuitem2dot5">+ <property name="visible">True</property>+ <property name="label" translatable="yes">_Move</property>+ <property name="use_underline">True</property>+ <child type="submenu">+ <object class="GtkMenu" id="menu2dot5">+ <property name="visible">True</property>+ <child>+ <object class="GtkImageMenuItem" id="move_first">+ <property name="label" translatable="yes">Jump to start</property>+ <property name="visible">True</property>+ <property name="use_underline">True</property>+ <property name="image">image4</property>+ <property name="use_stock">False</property>+ </object>+ </child>+ <child>+ <object class="GtkImageMenuItem" id="move_centre">+ <property name="label" translatable="yes">Centre on cursor</property>+ <property name="visible">True</property>+ <property name="use_underline">True</property>+ <property name="image">image5</property>+ <property name="use_stock">False</property>+ </object>+ </child>+ <child>+ <object class="GtkImageMenuItem" id="move_last">+ <property name="label" translatable="yes">Jump to end</property>+ <property name="visible">True</property>+ <property name="use_underline">True</property>+ <property name="image">image6</property>+ <property name="use_stock">False</property>+ </object>+ </child>+ <child>+ <object class="GtkSeparatorMenuItem" id="separatormenuitem2dot5">+ <property name="visible">True</property>+ </object>+ </child>+ <child>+ <object class="GtkImageMenuItem" id="move_zoomin">+ <property name="label" translatable="yes">Zoom in</property>+ <property name="visible">True</property>+ <property name="use_underline">True</property>+ <property name="image">image7</property>+ <property name="use_stock">False</property>+ </object>+ </child>+ <child>+ <object class="GtkImageMenuItem" id="move_zoomout">+ <property name="label" translatable="yes">Zoom out</property>+ <property name="visible">True</property>+ <property name="use_underline">True</property>+ <property name="image">image8</property>+ <property name="use_stock">False</property>+ </object>+ </child>+ <child>+ <object class="GtkImageMenuItem" id="move_zoomfit">+ <property name="label" translatable="yes">Fit to window</property>+ <property name="visible">True</property>+ <property name="use_underline">True</property>+ <property name="image">image9</property>+ <property name="use_stock">False</property>+ </object>+ </child>+ </object>+ </child>+ </object>+ </child>+ <child>+ <object class="GtkMenuItem" id="menuitem3">+ <property name="visible">True</property>+ <property name="label" translatable="yes">Help</property>+ <property name="use_underline">True</property>+ <child type="submenu">+ <object class="GtkMenu" id="menu3">+ <property name="visible">True</property>+ <child>+ <object class="GtkMenuItem" id="tutorialMenuItem">+ <property name="visible">True</property>+ <property name="label" translatable="yes">Online tutorial</property>+ <property name="use_underline">True</property>+ </object>+ </child>+ <child>+ <object class="GtkMenuItem" id="websiteMenuItem">+ <property name="visible">True</property>+ <property name="label" translatable="yes">Website</property>+ <property name="use_underline">True</property>+ </object>+ </child>+ <child>+ <object class="GtkSeparatorMenuItem" id="menuitem5">+ <property name="visible">True</property>+ </object>+ </child>+ <child>+ <object class="GtkImageMenuItem" id="aboutMenuItem">+ <property name="label">gtk-about</property>+ <property name="visible">True</property>+ <property name="use_underline">True</property>+ <property name="use_stock">True</property>+ </object>+ </child>+ </object>+ </child>+ </object>+ </child>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="fill">True</property>+ <property name="position">0</property>+ </packing>+ </child>+ <child>+ <object class="GtkToolbar" id="toolbar2">+ <property name="visible">True</property>+ <property name="toolbar_style">both-horiz</property>+ <property name="show_arrow">False</property>+ <child>+ <object class="GtkToolButton" id="cpus_open">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">Open an eventlog</property>+ <property name="use_underline">True</property>+ <property name="stock_id">gtk-open</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="homogeneous">True</property>+ </packing>+ </child>+ <child>+ <object class="GtkSeparatorToolItem" id="separatortoolitem5dot5">+ <property name="visible">True</property>+ </object>+ <packing>+ <property name="expand">False</property>+ </packing>+ </child>+ <child>+ <object class="GtkToolButton" id="cpus_first">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">Jump to the start</property>+ <property name="use_underline">True</property>+ <property name="stock_id">gtk-goto-first</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="homogeneous">True</property>+ </packing>+ </child>+ <child>+ <object class="GtkToolButton" id="cpus_centre">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">Centre view on the cursor</property>+ <property name="stock_id">gtk-home</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="homogeneous">True</property>+ </packing>+ </child>+ <child>+ <object class="GtkToolButton" id="cpus_last">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">Jump to the end</property>+ <property name="use_underline">True</property>+ <property name="stock_id">gtk-goto-last</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="homogeneous">True</property>+ </packing>+ </child>+ <child>+ <object class="GtkSeparatorToolItem" id="separatortoolitem5">+ <property name="visible">True</property>+ </object>+ <packing>+ <property name="expand">False</property>+ </packing>+ </child>+ <child>+ <object class="GtkToolButton" id="cpus_zoomin">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">Zoom in</property>+ <property name="stock_id">gtk-zoom-in</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="homogeneous">True</property>+ </packing>+ </child>+ <child>+ <object class="GtkToolButton" id="cpus_zoomout">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">Zoom out</property>+ <property name="stock_id">gtk-zoom-out</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="homogeneous">True</property>+ </packing>+ </child>+ <child>+ <object class="GtkToolButton" id="cpus_zoomfit">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">Fit view to the window</property>+ <property name="stock_id">gtk-zoom-fit</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="homogeneous">True</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="fill">False</property>+ <property name="position">1</property>+ </packing>+ </child>+ <child>+ <object class="GtkHPaned" id="hpaned">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <child>+ <object class="GtkNotebook" id="sidebar">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="group_name">sidepane</property>+ <child>+ <object class="GtkScrolledWindow" id="scrolledwindow2">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <child>+ <object class="GtkTreeView" id="key_list">+ <property name="visible">True</property>+ <property name="headers_visible">False</property>+ <property name="enable_search">False</property>+ </object>+ </child>+ </object>+ <packing>+ <property name="reorderable">True</property>+ </packing>+ </child>+ <child type="tab">+ <object class="GtkLabel" id="label5">+ <property name="visible">True</property>+ <property name="label" translatable="yes">Key</property>+ </object>+ <packing>+ <property name="position">2</property>+ <property name="tab_fill">False</property>+ </packing>+ </child>+ <child>+ <object class="GtkScrolledWindow" id="scrolledwindow1">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <child>+ <object class="GtkTreeView" id="traces_tree">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="headers_visible">False</property>+ </object>+ </child>+ </object>+ <packing>+ <property name="position">1</property>+ <property name="reorderable">True</property>+ </packing>+ </child>+ <child type="tab">+ <object class="GtkLabel" id="label1">+ <property name="visible">True</property>+ <property name="label" translatable="yes">Traces</property>+ </object>+ <packing>+ <property name="position">1</property>+ <property name="tab_fill">False</property>+ </packing>+ </child>+ <child>+ <object class="GtkVBox" id="bookmarks_vbox">+ <property name="visible">True</property>+ <child>+ <object class="GtkToolbar" id="toolbar3">+ <property name="visible">True</property>+ <property name="toolbar_style">both-horiz</property>+ <property name="show_arrow">False</property>+ <child>+ <object class="GtkToolButton" id="goto_bookmark_button">+ <property name="visible">True</property>+ <property name="is_important">True</property>+ <property name="stock_id">gtk-jump-to</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="homogeneous">True</property>+ </packing>+ </child>+ <child>+ <object class="GtkToolButton" id="add_bookmark_button">+ <property name="visible">True</property>+ <property name="label" translatable="yes">Bookmark</property>+ <property name="use_underline">True</property>+ <property name="stock_id">gtk-add</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="homogeneous">True</property>+ </packing>+ </child>+ <child>+ <object class="GtkToolButton" id="delete_bookmark">+ <property name="visible">True</property>+ <property name="stock_id">gtk-remove</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="homogeneous">True</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="fill">False</property>+ <property name="position">0</property>+ </packing>+ </child>+ <child>+ <object class="GtkScrolledWindow" id="bookmark_list_scrolled_window">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <child>+ <object class="GtkTreeView" id="bookmark_list">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="headers_clickable">False</property>+ </object>+ </child>+ </object>+ <packing>+ <property name="expand">True</property>+ <property name="fill">True</property>+ <property name="position">1</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="position">2</property>+ <property name="reorderable">True</property>+ </packing>+ </child>+ <child type="tab">+ <object class="GtkLabel" id="label2">+ <property name="visible">True</property>+ <property name="label" translatable="yes">Bookmarks</property>+ </object>+ <packing>+ <property name="position">2</property>+ <property name="tab_fill">False</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="resize">False</property>+ <property name="shrink">True</property>+ </packing>+ </child>+ <child>+ <object class="GtkVPaned" id="vpaned1">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <child>+ <object class="GtkVBox" id="timelinebox">+ <property name="visible">True</property>+ <child>+ <object class="GtkLabel" id="label3">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="xpad">4</property>+ <property name="ypad">4</property>+ <property name="label" translatable="yes"><b>Timeline</b></property>+ <property name="use_markup">True</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="fill">False</property>+ <property name="position">0</property>+ </packing>+ </child>+ <child>+ <object class="GtkTable" id="table1">+ <property name="visible">True</property>+ <property name="n_rows">2</property>+ <property name="n_columns">2</property>+ <property name="column_spacing">3</property>+ <property name="row_spacing">3</property>+ <child>+ <object class="GtkVScrollbar" id="timeline_vscroll">+ <property name="visible">True</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="x_options">GTK_SHRINK | GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkHScrollbar" id="timeline_hscroll">+ <property name="visible">True</property>+ <property name="restrict_to_fill_level">False</property>+ <property name="fill_level">0</property>+ </object>+ <packing>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="y_options">GTK_SHRINK</property>+ </packing>+ </child>+ <child>+ <object class="GtkViewport" id="timeline_viewport">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="has_focus">True</property>+ <property name="events">GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_STRUCTURE_MASK</property>+ <property name="resize_mode">queue</property>+ <child>+ <object class="GtkTable" id="table2">+ <property name="visible">True</property>+ <property name="n_rows">2</property>+ <property name="n_columns">2</property>+ <child>+ <object class="GtkDrawingArea" id="timeline_yscale_area">+ <property name="width_request">110</property>+ <property name="visible">True</property>+ </object>+ <packing>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="x_options">GTK_SHRINK</property>+ </packing>+ </child>+ <child>+ <object class="GtkDrawingArea" id="timeline_xscale_area">+ <property name="height_request">38</property>+ <property name="visible">True</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="y_options">GTK_SHRINK</property>+ </packing>+ </child>+ <child>+ <object class="GtkDrawingArea" id="timeline_drawingarea">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ </packing>+ </child>+ <child>+ <placeholder/>+ </child>+ </object>+ </child>+ </object>+ </child>+ <child>+ <placeholder/>+ </child>+ </object>+ <packing>+ <property name="expand">True</property>+ <property name="fill">True</property>+ <property name="position">1</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="resize">True</property>+ <property name="shrink">True</property>+ </packing>+ </child>+ <child>+ <object class="GtkNotebook" id="eventsbox">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="group_name">infopane</property>+ <child>+ <object class="GtkScrolledWindow" id="scrolledwindow6">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <child>+ <object class="GtkViewport" id="viewport4">+ <property name="visible">True</property>+ <property name="resize_mode">queue</property>+ <child>+ <object class="GtkTable" id="table6">+ <property name="visible">True</property>+ <property name="border_width">8</property>+ <property name="n_rows">4</property>+ <property name="n_columns">2</property>+ <property name="column_spacing">8</property>+ <property name="row_spacing">4</property>+ <child>+ <object class="GtkLabel" id="label24">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Total time:</property>+ </object>+ <packing>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="label25">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Mutator time:</property>+ </object>+ <packing>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="label26">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">GC time:</property>+ </object>+ <packing>+ <property name="top_attach">2</property>+ <property name="bottom_attach">3</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelTimeTotal">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelTimeGC">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">2</property>+ <property name="bottom_attach">3</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelTimeMutator">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="label20">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Productivity:</property>+ </object>+ <packing>+ <property name="top_attach">3</property>+ <property name="bottom_attach">4</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelTimeProductivity">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">3</property>+ <property name="bottom_attach">4</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ </object>+ </child>+ </object>+ </child>+ </object>+ <packing>+ <property name="reorderable">True</property>+ </packing>+ </child>+ <child type="tab">+ <object class="GtkLabel" id="label21">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">The time spent executing code vs doing GC+(for the full run or the selected time period)</property>+ <property name="label" translatable="yes">Time</property>+ </object>+ <packing>+ <property name="tab_fill">False</property>+ </packing>+ </child>+ <child>+ <object class="GtkScrolledWindow" id="scrolledwindowSummary">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <child>+ <object class="GtkViewport" id="viewport3">+ <property name="visible">True</property>+ <property name="resize_mode">queue</property>+ <child>+ <object class="GtkTable" id="tableHeap">+ <property name="visible">True</property>+ <property name="border_width">8</property>+ <property name="n_rows">5</property>+ <property name="n_columns">5</property>+ <property name="column_spacing">8</property>+ <property name="row_spacing">4</property>+ <child>+ <object class="GtkLabel" id="label14">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Maximum heap size:</property>+ </object>+ <packing>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="label15">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Maximum heap residency:</property>+ </object>+ <packing>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="label17">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Total allocated:</property>+ </object>+ <packing>+ <property name="top_attach">2</property>+ <property name="bottom_attach">3</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapMaxSize">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">1</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ <property name="width_chars">6</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapAllocTotal">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">1</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ <property name="width_chars">6</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">2</property>+ <property name="bottom_attach">3</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapMaxResidency">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">1</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ <property name="width_chars">6</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="label18">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Allocation rate:</property>+ </object>+ <packing>+ <property name="top_attach">3</property>+ <property name="bottom_attach">4</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapAllocRate">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">1</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ <property name="width_chars">6</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">3</property>+ <property name="bottom_attach">4</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="label29">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Maximum slop:</property>+ </object>+ <packing>+ <property name="top_attach">4</property>+ <property name="bottom_attach">5</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapMaxSlop">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">1</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ <property name="width_chars">6</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">4</property>+ <property name="bottom_attach">5</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapMaxSizeUnit">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="width_chars">3</property>+ </object>+ <packing>+ <property name="left_attach">2</property>+ <property name="right_attach">3</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapMaxResidencyUnit">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="width_chars">3</property>+ </object>+ <packing>+ <property name="left_attach">2</property>+ <property name="right_attach">3</property>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapAllocTotalUnit">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="width_chars">3</property>+ </object>+ <packing>+ <property name="left_attach">2</property>+ <property name="right_attach">3</property>+ <property name="top_attach">2</property>+ <property name="bottom_attach">3</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapAllocRateUnit">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="width_chars">5</property>+ </object>+ <packing>+ <property name="left_attach">2</property>+ <property name="right_attach">3</property>+ <property name="top_attach">3</property>+ <property name="bottom_attach">4</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapMaxSlopUnit">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="width_chars">3</property>+ </object>+ <packing>+ <property name="left_attach">2</property>+ <property name="right_attach">3</property>+ <property name="top_attach">4</property>+ <property name="bottom_attach">5</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapMaxSizeBytes">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">1</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ <property name="width_chars">18</property>+ </object>+ <packing>+ <property name="left_attach">3</property>+ <property name="right_attach">4</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapMaxResidencyBytes">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">1</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ <property name="width_chars">18</property>+ </object>+ <packing>+ <property name="left_attach">3</property>+ <property name="right_attach">4</property>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapAllocTotalBytes">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">1</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ <property name="width_chars">18</property>+ </object>+ <packing>+ <property name="left_attach">3</property>+ <property name="right_attach">4</property>+ <property name="top_attach">2</property>+ <property name="bottom_attach">3</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapAllocRateBytes">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">1</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ <property name="width_chars">18</property>+ </object>+ <packing>+ <property name="left_attach">3</property>+ <property name="right_attach">4</property>+ <property name="top_attach">3</property>+ <property name="bottom_attach">4</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapMaxSlopBytes">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">1</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ <property name="width_chars">18</property>+ </object>+ <packing>+ <property name="left_attach">3</property>+ <property name="right_attach">4</property>+ <property name="top_attach">4</property>+ <property name="bottom_attach">5</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapMaxSizeUnit1">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ </object>+ <packing>+ <property name="left_attach">4</property>+ <property name="right_attach">5</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapMaxResidencyUnit1">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ </object>+ <packing>+ <property name="left_attach">4</property>+ <property name="right_attach">5</property>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapMaxSlopUnit1">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ </object>+ <packing>+ <property name="left_attach">4</property>+ <property name="right_attach">5</property>+ <property name="top_attach">4</property>+ <property name="bottom_attach">5</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapAllocRateUnit1">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ </object>+ <packing>+ <property name="left_attach">4</property>+ <property name="right_attach">5</property>+ <property name="top_attach">3</property>+ <property name="bottom_attach">4</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelHeapAllocTotalUnit1">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ </object>+ <packing>+ <property name="left_attach">4</property>+ <property name="right_attach">5</property>+ <property name="top_attach">2</property>+ <property name="bottom_attach">3</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ </object>+ </child>+ </object>+ </child>+ </object>+ <packing>+ <property name="position">1</property>+ <property name="reorderable">True</property>+ </packing>+ </child>+ <child type="tab">+ <object class="GtkLabel" id="label23">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">Summary statistics about the heap+(for the full run or the selected time period)</property>+ <property name="label" translatable="yes">Heap</property>+ </object>+ <packing>+ <property name="position">1</property>+ <property name="tab_fill">False</property>+ </packing>+ </child>+ <child>+ <object class="GtkScrolledWindow" id="scrolledwindowSummary1">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <child>+ <object class="GtkViewport" id="viewport5">+ <property name="visible">True</property>+ <property name="resize_mode">queue</property>+ <child>+ <object class="GtkTable" id="tableGC">+ <property name="visible">True</property>+ <property name="border_width">8</property>+ <property name="n_rows">3</property>+ <property name="n_columns">2</property>+ <property name="column_spacing">8</property>+ <property name="row_spacing">4</property>+ <child>+ <object class="GtkLabel" id="label19">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Copied during GC:</property>+ </object>+ <packing>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="label22">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Parallel GC work balance:</property>+ </object>+ <packing>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelGcParWorkBalance">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkScrolledWindow" id="scrolledwindow7">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <child>+ <object class="GtkTreeView" id="treeviewGcStats">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="headers_clickable">False</property>+ </object>+ </child>+ </object>+ <packing>+ <property name="right_attach">2</property>+ <property name="top_attach">2</property>+ <property name="bottom_attach">3</property>+ </packing>+ </child>+ <child>+ <object class="GtkHBox" id="hbox1">+ <property name="visible">True</property>+ <property name="spacing">4</property>+ <child>+ <object class="GtkLabel" id="labelGcCopied">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="fill">True</property>+ <property name="position">0</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelGcCopiedUnit">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="fill">True</property>+ <property name="position">1</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelGcCopiedBytes">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">1</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ <property name="width_chars">18</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="fill">True</property>+ <property name="position">2</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelGcCopiedUnit1">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="fill">True</property>+ <property name="position">3</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ </object>+ </child>+ </object>+ </child>+ </object>+ <packing>+ <property name="position">2</property>+ <property name="reorderable">True</property>+ </packing>+ </child>+ <child type="tab">+ <object class="GtkLabel" id="label16">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">Garbage collector statistics+(for the full run or the selected time period)</property>+ <property name="label" translatable="yes">GC</property>+ </object>+ <packing>+ <property name="position">2</property>+ <property name="tab_fill">False</property>+ </packing>+ </child>+ <child>+ <object class="GtkScrolledWindow" id="scrolledwindow8">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <child>+ <object class="GtkTreeView" id="treeviewSparkStats">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ </object>+ </child>+ </object>+ <packing>+ <property name="position">3</property>+ <property name="reorderable">True</property>+ </packing>+ </child>+ <child type="tab">+ <object class="GtkLabel" id="label27">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">Counts of how many sparks were created, converted etc+(for the full run or the selected time period)</property>+ <property name="label" translatable="yes">Spark stats</property>+ </object>+ <packing>+ <property name="position">3</property>+ <property name="tab_fill">False</property>+ </packing>+ </child>+ <child>+ <object class="GtkTable" id="table3">+ <property name="visible">True</property>+ <property name="n_columns">2</property>+ <child>+ <object class="GtkDrawingArea" id="timeline_yscale_area2">+ <property name="width_request">110</property>+ <property name="visible">True</property>+ </object>+ <packing>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="x_options">GTK_SHRINK</property>+ </packing>+ </child>+ <child>+ <object class="GtkDrawingArea" id="histogram_drawingarea">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ </packing>+ </child>+ <child>+ <placeholder/>+ </child>+ <child>+ <placeholder/>+ </child>+ </object>+ <packing>+ <property name="position">4</property>+ <property name="reorderable">True</property>+ </packing>+ </child>+ <child type="tab">+ <object class="GtkLabel" id="label8">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">A histogram of how long each spark took to evaluate,+either for the whole program or the selected time period.</property>+ <property name="label" translatable="yes">Spark sizes</property>+ </object>+ <packing>+ <property name="position">4</property>+ <property name="tab_fill">False</property>+ </packing>+ </child>+ <child>+ <object class="GtkScrolledWindow" id="scrolledwindow3">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <child>+ <object class="GtkViewport" id="viewport1">+ <property name="visible">True</property>+ <child>+ <object class="GtkTable" id="table4">+ <property name="visible">True</property>+ <property name="border_width">8</property>+ <property name="n_rows">5</property>+ <property name="n_columns">2</property>+ <property name="column_spacing">8</property>+ <property name="row_spacing">4</property>+ <child>+ <object class="GtkLabel" id="label9">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Executable:</property>+ </object>+ <packing>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="label10">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Arguments:</property>+ </object>+ <packing>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="label11">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Start time:</property>+ </object>+ <packing>+ <property name="top_attach">2</property>+ <property name="bottom_attach">3</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="label12">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">RTS Id:</property>+ </object>+ <packing>+ <property name="top_attach">3</property>+ <property name="bottom_attach">4</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="label13">+ <property name="visible">True</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="label" translatable="yes">Environment:</property>+ </object>+ <packing>+ <property name="top_attach">4</property>+ <property name="bottom_attach">5</property>+ <property name="x_options">GTK_FILL</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelProgName">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="tooltip_text" translatable="yes">The name and path of the program's executable file</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelProgStartTime">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="tooltip_text" translatable="yes">The time at which the program was started</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">2</property>+ <property name="bottom_attach">3</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ <child>+ <object class="GtkScrolledWindow" id="scrolledwindow4">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <child>+ <object class="GtkTreeView" id="treeviewProgArguments">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="tooltip_text" translatable="yes">The arguments supplied when the program was run</property>+ <property name="headers_visible">False</property>+ </object>+ </child>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">1</property>+ <property name="bottom_attach">2</property>+ </packing>+ </child>+ <child>+ <object class="GtkScrolledWindow" id="scrolledwindow5">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="hscrollbar_policy">automatic</property>+ <property name="vscrollbar_policy">automatic</property>+ <child>+ <object class="GtkTreeView" id="treeviewProgEnvironment">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="tooltip_text" translatable="yes">The environment variables available when the program was started</property>+ <property name="headers_visible">False</property>+ </object>+ </child>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">4</property>+ <property name="bottom_attach">5</property>+ </packing>+ </child>+ <child>+ <object class="GtkLabel" id="labelProgRtsIdentifier">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="tooltip_text" translatable="yes">The name and version of the compiler/runtime used by the program</property>+ <property name="xalign">0</property>+ <property name="yalign">0</property>+ <property name="selectable">True</property>+ </object>+ <packing>+ <property name="left_attach">1</property>+ <property name="right_attach">2</property>+ <property name="top_attach">3</property>+ <property name="bottom_attach">4</property>+ <property name="y_options">GTK_FILL</property>+ </packing>+ </child>+ </object>+ </child>+ </object>+ </child>+ </object>+ <packing>+ <property name="position">5</property>+ <property name="reorderable">True</property>+ </packing>+ </child>+ <child type="tab">+ <object class="GtkLabel" id="label6">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">Information about the program run including program name and command line arguments.</property>+ <property name="label" translatable="yes">Process info</property>+ </object>+ <packing>+ <property name="position">5</property>+ <property name="tab_fill">False</property>+ </packing>+ </child>+ <child>+ <object class="GtkVBox" id="eventsbox_old">+ <property name="visible">True</property>+ <child>+ <object class="GtkEntry" id="events_entry">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ <property name="invisible_char">●</property>+ <property name="width_chars">20</property>+ <property name="secondary_icon_stock">gtk-find</property>+ <property name="secondary_icon_tooltip_text">Search for event</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="fill">True</property>+ <property name="position">1</property>+ </packing>+ </child>+ <child>+ <object class="GtkHBox" id="eventsHBox">+ <property name="height_request">120</property>+ <property name="visible">True</property>+ <property name="spacing">3</property>+ <child>+ <object class="GtkViewport" id="viewport2">+ <property name="visible">True</property>+ <property name="resize_mode">queue</property>+ <child>+ <object class="GtkDrawingArea" id="eventsDrawingArea">+ <property name="visible">True</property>+ <property name="can_focus">True</property>+ </object>+ </child>+ </object>+ <packing>+ <property name="expand">True</property>+ <property name="fill">True</property>+ <property name="position">0</property>+ </packing>+ </child>+ <child>+ <object class="GtkVScrollbar" id="eventsVScroll">+ <property name="visible">True</property>+ <property name="adjustment">adjustment1</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="fill">True</property>+ <property name="position">1</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="expand">True</property>+ <property name="fill">True</property>+ <property name="position">2</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="position">6</property>+ <property name="reorderable">True</property>+ </packing>+ </child>+ <child type="tab">+ <object class="GtkLabel" id="label4">+ <property name="visible">True</property>+ <property name="tooltip_text" translatable="yes">The raw events from the eventlog.+The selection is synchronised with the timeline.</property>+ <property name="label" translatable="yes">Raw events</property>+ </object>+ <packing>+ <property name="position">6</property>+ <property name="tab_fill">False</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="resize">False</property>+ <property name="shrink">True</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="resize">True</property>+ <property name="shrink">True</property>+ </packing>+ </child>+ </object>+ <packing>+ <property name="expand">True</property>+ <property name="fill">True</property>+ <property name="position">2</property>+ </packing>+ </child>+ <child>+ <object class="GtkStatusbar" id="statusbar">+ <property name="visible">True</property>+ </object>+ <packing>+ <property name="expand">False</property>+ <property name="fill">True</property>+ <property name="position">3</property>+ </packing>+ </child>+ </object>+ </child> </object> </interface>