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