ghc-events-analyze 0.2.5 → 0.2.6
raw patch · 5 files changed
+42/−21 lines, 5 filesdep ~basedep ~hashabledep ~lens
Dependency ranges changed: base, hashable, lens, optparse-applicative, th-lift
Files
- ChangeLog +6/−1
- ghc-events-analyze.cabal +6/−6
- src/GHC/RTS/Events/Analyze.hs +2/−1
- src/GHC/RTS/Events/Analyze/Analysis.hs +26/−12
- src/GHC/RTS/Events/Analyze/Types.hs +2/−1
ChangeLog view
@@ -1,6 +1,11 @@+0.2.6++ * Support for GHC 8.6+ (2019-11-01 Simon Jakobi <simon.jakobi@gmail.com>)+ 0.2.5 - * Add suppor for filtering threads by name, and improve+ * Add support for filtering threads by name, and improve performance of relabelling. (2017-03-11 Pepe Iborra <mnislaih@gmail.com>)
ghc-events-analyze.cabal view
@@ -1,5 +1,5 @@ name: ghc-events-analyze-version: 0.2.5+version: 0.2.6 synopsis: Analyze and visualize event logs description: ghc-events-analyze is a simple Haskell profiling tool that uses GHC's eventlog system. It helps with some profiling@@ -51,7 +51,7 @@ GHC.RTS.Events.Analyze.Reports.Timed GHC.RTS.Events.Analyze.Reports.Timed.SVG - build-depends: base >= 4.8 && < 4.12,+ build-depends: base >= 4.8 && < 4.14, blaze-svg >= 0.3 && < 0.4, bytestring >= 0.10 && < 0.11, containers >= 0.5 && < 0.7,@@ -59,15 +59,15 @@ diagrams-svg >= 1.1 && < 1.5, filepath >= 1.3 && < 1.5, ghc-events >= 0.6,- hashable >= 1.2 && < 1.3,- lens >= 3.10 && < 4.18,+ hashable >= 1.2 && < 1.4,+ lens >= 3.10 && < 4.19, mtl >= 2.2.1 && < 2.3,- optparse-applicative >= 0.11 && < 0.15,+ optparse-applicative >= 0.11 && < 0.16, parsec >= 3.1 && < 3.2, regex-base >= 0.93 && < 0.94, regex-pcre-builtin >= 0.94 && < 0.95, SVGFonts >= 1.5 && < 1.8,- th-lift >= 0.6 && < 0.8,+ th-lift >= 0.6 && < 0.9, transformers >= 0.3 && < 0.6, unordered-containers >= 0.2 && < 0.3, -- No version: whatever is bundled with ghc
src/GHC/RTS/Events/Analyze.hs view
@@ -2,6 +2,7 @@ module Main where import Control.Monad (when, forM_)+import qualified Data.List.NonEmpty as NonEmpty import Data.Maybe (isNothing) import System.FilePath (replaceExtension, takeFileName) import Text.Parsec.String (parseFromFile)@@ -44,7 +45,7 @@ | isNothing optionsWindowEvent = filename | otherwise = show i ++ "." ++ filename - forM_ (zip [0..] analyses) $ \ (i,analysis) -> do+ forM_ (zip [0..] (NonEmpty.toList analyses)) $ \ (i,analysis) -> do let quantized = quantize optionsNumBuckets analysis totals = Totals.createReport analysis totalsScript
src/GHC/RTS/Events/Analyze/Analysis.hs view
@@ -21,8 +21,18 @@ import qualified Data.HashMap.Strict as Map import Data.IntMap.Strict (IntMap) import qualified Data.IntMap.Strict as IntMap-import GHC.RTS.Events hiding (events)+import Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty +import GHC.RTS.Events (+ Event(..)+ , EventInfo(..)+ , EventLog(..)+ , ThreadStopStatus(..)+ , Timestamp+ )+import qualified GHC.RTS.Events as Events+ #if !MIN_VERSION_base(4,8,0) import Control.Applicative ((<$>)) #endif@@ -37,10 +47,10 @@ -------------------------------------------------------------------------------} sortedEvents :: EventLog -> [Event]-sortedEvents (EventLog _header (Data es)) = sortEvents es+sortedEvents (EventLog _header (Events.Data es)) = Events.sortEvents es readEventLog :: FilePath -> IO EventLog-readEventLog = throwLeftStr . readEventLogFromFile+readEventLog = throwLeftStr . Events.readEventLogFromFile {------------------------------------------------------------------------------- Basic analysis of the eventlog, making the information more easily accessible.@@ -48,14 +58,14 @@ the analysis combines such events. -------------------------------------------------------------------------------} -analyze :: Options -> EventLog -> [EventAnalysis]+analyze :: Options -> EventLog -> NonEmpty EventAnalysis analyze opts@Options{..} log = let AnalysisState _ analyses = execState (mapM_ analyzeEvent (sortedEvents log)) (initialAnalysisState opts)- in reverse- [ analysis { eventTotals = computeTotals (_events analysis)- , eventStarts = computeStarts (_events analysis) }- | analysis <- (if length analyses > 1 then drop 1 else id) analyses ]+ in NonEmpty.reverse $ do+ analysis <- nonEmptyTail analyses+ pure analysis { eventTotals = computeTotals (_events analysis)+ , eventStarts = computeStarts (_events analysis) } where isWindowEvent :: EventId -> Bool isWindowEvent = case optionsWindowEvent of@@ -95,6 +105,10 @@ stopId (UserMessage (prefix optionsUserStop -> Just e)) = Just $ parseUserEvent e stopId _ = Nothing + nonEmptyTail :: NonEmpty a -> NonEmpty a+ nonEmptyTail (_ :| (x : xs)) = x :| xs+ nonEmptyTail xs = xs+ ifInWindow :: State EventAnalysis () -> State EventAnalysis () ifInWindow m = do b <- use inWindow@@ -103,9 +117,9 @@ -- Lift actions on the current analysis to the head of the list. cur :: State EventAnalysis a -> State AnalysisState a cur m = do- AnalysisState ts (h:t) <- get+ AnalysisState ts (h:|t) <- get case runState m h of- (r, h') -> put (AnalysisState ts (h':t)) >> return r+ (r, h') -> put (AnalysisState ts (h':|t)) >> return r -- We take the _first_ CapCreate to be the official startup time recordStartup :: Timestamp -> State EventAnalysis ()@@ -177,7 +191,7 @@ inWindow .= False recordShutdown time recordRunningThreadFinish time- windowAnalyses %= (initialEventAnalysis opts :)+ windowAnalyses %= NonEmpty.cons (initialEventAnalysis opts) -- Record thread creation in current window, and add it to the map of running threads recordThreadCreation :: ThreadId -> Timestamp -> State AnalysisState ()@@ -232,7 +246,7 @@ initialAnalysisState :: Options -> AnalysisState initialAnalysisState opts = AnalysisState { _runningThreads = Map.empty- , _windowAnalyses = [initialEventAnalysis opts]+ , _windowAnalyses = initialEventAnalysis opts :| [] } initialEventAnalysis :: Options -> EventAnalysis
src/GHC/RTS/Events/Analyze/Types.hs view
@@ -42,6 +42,7 @@ import Data.Hashable import Data.HashMap.Strict (HashMap) import Data.IntMap.Strict (IntMap)+import Data.List.NonEmpty (NonEmpty) import GHC.Generics import GHC.RTS.Events (Timestamp, ThreadId) import Text.Regex.PCRE@@ -220,7 +221,7 @@ -- and appends an 'EventAnalysis' per window. data AnalysisState = AnalysisState { _runningThreads :: RunningThreads- , _windowAnalyses :: [EventAnalysis]+ , _windowAnalyses :: NonEmpty EventAnalysis } $(makeLenses ''AnalysisState)