Add Haddock `/Since: 4.5.[01].0/` comments to symbols
[packages/base.git] / GHC / Stats.hsc
1 {-# LANGUAGE Safe #-}
2 {-# LANGUAGE CPP #-}
3 {-# LANGUAGE ForeignFunctionInterface #-}
4 {-# LANGUAGE RecordWildCards #-}
5 {-# OPTIONS_GHC -funbox-strict-fields #-}
6
7 -----------------------------------------------------------------------------
8 -- | This module provides access to internal garbage collection and
9 -- memory usage statistics.  These statistics are not available unless
10 -- a program is run with the @-T@ RTS flag.
11 --
12 -- This module is GHC-only and should not be considered portable.
13 --
14 -- /Since: 4.5.0.0/
15 -----------------------------------------------------------------------------
16 module GHC.Stats
17     ( GCStats(..)
18     , getGCStats
19     , getGCStatsEnabled
20 ) where
21
22 import Control.Monad
23 import Data.Int
24 import GHC.IO.Exception
25 import Foreign.Marshal.Alloc
26 import Foreign.Storable
27 import Foreign.Ptr
28
29 #include "Rts.h"
30
31 foreign import ccall "getGCStats"        getGCStats_       :: Ptr () -> IO ()
32
33 -- | Returns whether GC stats have been enabled (with @+RTS -T@, for example).
34 --
35 -- /Since: 4.6.0.0/
36 foreign import ccall "getGCStatsEnabled" getGCStatsEnabled :: IO Bool
37
38 -- I'm probably violating a bucket of constraints here... oops.
39
40 -- | Global garbage collection and memory statistics.
41 --
42 -- /Since: 4.5.0.0/
43 data GCStats = GCStats
44     { bytesAllocated :: !Int64 -- ^ Total number of bytes allocated
45     , numGcs :: !Int64 -- ^ Number of garbage collections performed
46     , maxBytesUsed :: !Int64 -- ^ Maximum number of live bytes seen so far
47     , numByteUsageSamples :: !Int64 -- ^ Number of byte usage samples taken
48     -- | Sum of all byte usage samples, can be used with
49     -- 'numByteUsageSamples' to calculate averages with
50     -- arbitrary weighting (if you are sampling this record multiple
51     -- times).
52     , cumulativeBytesUsed :: !Int64
53     , bytesCopied :: !Int64 -- ^ Number of bytes copied during GC
54     , currentBytesUsed :: !Int64 -- ^ Current number of live bytes
55     , currentBytesSlop :: !Int64 -- ^ Current number of bytes lost to slop
56     , maxBytesSlop :: !Int64 -- ^ Maximum number of bytes lost to slop at any one time so far
57     , peakMegabytesAllocated :: !Int64 -- ^ Maximum number of megabytes allocated
58     -- | CPU time spent running mutator threads.  This does not include
59     -- any profiling overhead or initialization.
60     , mutatorCpuSeconds :: !Double
61     -- | Wall clock time spent running mutator threads.  This does not
62     -- include initialization.
63     , mutatorWallSeconds :: !Double
64     , gcCpuSeconds :: !Double -- ^ CPU time spent running GC
65     , gcWallSeconds :: !Double -- ^ Wall clock time spent running GC
66     , cpuSeconds :: !Double -- ^ Total CPU time elapsed since program start
67     , wallSeconds :: !Double -- ^ Total wall clock time elapsed since start
68     -- | Number of bytes copied during GC, minus space held by mutable
69     -- lists held by the capabilities.  Can be used with
70     -- 'parMaxBytesCopied' to determine how well parallel GC utilized
71     -- all cores.
72     , parTotBytesCopied :: !Int64
73     -- | Sum of number of bytes copied each GC by the most active GC
74     -- thread each GC.  The ratio of 'parTotBytesCopied' divided by
75     -- 'parMaxBytesCopied' approaches 1 for a maximally sequential
76     -- run and approaches the number of threads (set by the RTS flag
77     -- @-N@) for a maximally parallel run.
78     , parMaxBytesCopied :: !Int64
79     } deriving (Show, Read)
80
81     {-
82     , initCpuSeconds :: !Double
83     , initWallSeconds :: !Double
84     -}
85
86 -- | Retrieves garbage collection and memory statistics as of the last
87 -- garbage collection.  If you would like your statistics as recent as
88 -- possible, first run a 'System.Mem.performGC'.
89 --
90 -- /Since: 4.5.0.0/
91 getGCStats :: IO GCStats
92 getGCStats = do
93   statsEnabled <- getGCStatsEnabled
94   unless statsEnabled .  ioError $ IOError
95     Nothing
96     UnsupportedOperation
97     ""
98     "getGCStats: GC stats not enabled. Use `+RTS -T -RTS' to enable them."
99     Nothing
100     Nothing
101   allocaBytes (#size GCStats) $ \p -> do
102     getGCStats_ p
103     bytesAllocated <- (# peek GCStats, bytes_allocated) p
104     numGcs <- (# peek GCStats, num_gcs ) p
105     numByteUsageSamples <- (# peek GCStats, num_byte_usage_samples ) p
106     maxBytesUsed <- (# peek GCStats, max_bytes_used ) p
107     cumulativeBytesUsed <- (# peek GCStats, cumulative_bytes_used ) p
108     bytesCopied <- (# peek GCStats, bytes_copied ) p
109     currentBytesUsed <- (# peek GCStats, current_bytes_used ) p
110     currentBytesSlop <- (# peek GCStats, current_bytes_slop) p
111     maxBytesSlop <- (# peek GCStats, max_bytes_slop) p
112     peakMegabytesAllocated <- (# peek GCStats, peak_megabytes_allocated ) p
113     {-
114     initCpuSeconds <- (# peek GCStats, init_cpu_seconds) p
115     initWallSeconds <- (# peek GCStats, init_wall_seconds) p
116     -}
117     mutatorCpuSeconds <- (# peek GCStats, mutator_cpu_seconds) p
118     mutatorWallSeconds <- (# peek GCStats, mutator_wall_seconds) p
119     gcCpuSeconds <- (# peek GCStats, gc_cpu_seconds) p
120     gcWallSeconds <- (# peek GCStats, gc_wall_seconds) p
121     cpuSeconds <- (# peek GCStats, cpu_seconds) p
122     wallSeconds <- (# peek GCStats, wall_seconds) p
123     parTotBytesCopied <- (# peek GCStats, par_tot_bytes_copied) p
124     parMaxBytesCopied <- (# peek GCStats, par_max_bytes_copied) p
125     return GCStats { .. }
126
127 {-
128
129 -- Nontrivial to implement: TaskStats needs arbitrarily large
130 -- amounts of memory, spark stats wants to use SparkCounters
131 -- but that needs a new rts/ header.
132
133 data TaskStats = TaskStats
134     { taskMutCpuSeconds :: Int64
135     , taskMutWallSeconds :: Int64
136     , taskGcCpuSeconds :: Int64
137     , taskGcWallSeconds :: Int64
138     } deriving (Show, Read)
139
140 data SparkStats = SparkStats
141     { sparksCreated :: Int64
142     , sparksDud :: Int64
143     , sparksOverflowed :: Int64
144     , sparksConverted :: Int64
145     , sparksGcd :: Int64
146     , sparksFizzled :: Int64
147     } deriving (Show, Read)
148
149 -- We also could get per-generation stats, which requires a
150 -- non-constant but at runtime known about of memory.
151
152 -}