GHC.Stats: Use camelCase in public APIs
[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 module GHC.Stats
8     ( GCStats(..)
9     , getGCStats
10 ) where
11
12 import Foreign.Marshal.Alloc
13 import Foreign.Storable
14 import Foreign.Ptr
15 import Data.Int
16
17 #include "Rts.h"
18
19 foreign import ccall "getGCStats"    getGCStats_    :: Ptr () -> IO ()
20
21 -- I'm probably violating a bucket of constraints here... oops.
22
23 -- | Global garbage collection and memory statistics.
24 data GCStats = GCStats
25     { bytesAllocated :: !Int64 -- ^ Total number of bytes allocated
26     , numGcs :: !Int64 -- ^ Number of garbage collections performed
27     , maxBytesUsed :: !Int64 -- ^ Maximum number of live bytes seen so far
28     , numByteUsageSamples :: !Int64 -- ^ Number of byte usage samples taken
29     -- | Sum of all byte usage samples, can be used with
30     -- 'numByteUsageSamples' to calculate averages with
31     -- arbitrary weighting (if you are sampling this record multiple
32     -- times).
33     , cumulativeBytesUsed :: !Int64
34     , bytesCopied :: !Int64 -- ^ Number of bytes copied during GC
35     , currentBytesUsed :: !Int64 -- ^ Current number of live bytes
36     , currentBytesSlop :: !Int64 -- ^ Current number of bytes lost to slop
37     , maxBytesSlop :: !Int64 -- ^ Maximum number of bytes lost to slop at any one time so far
38     , peakMegabytesAllocated :: !Int64 -- ^ Maximum number of megabytes allocated
39     -- | CPU time spent running mutator threads.  This does not include
40     -- any profiling overhead or initialization.
41     , mutatorCpuSeconds :: !Double
42     -- | Wall clock time spent running mutator threads.  This does not
43     -- include initialization.
44     , mutatorWallSeconds :: !Double
45     , gcCpuSeconds :: !Double -- ^ CPU time spent running GC
46     , gcWallSeconds :: !Double -- ^ Wall clock time spent running GC
47     , cpuSeconds :: !Double -- ^ Total CPU time elapsed since program start
48     , wallSeconds :: !Double -- ^ Total wall clock time elapsed since start
49     -- | Number of bytes copied during GC, minus space held by mutable
50     -- lists held by the capabilities.  Can be used with
51     -- 'parMaxBytesCopied' to determine how well parallel GC utilized
52     -- all cores.
53     , parAvgBytesCopied :: !Int64
54     -- | Sum of number of bytes copied each GC by the most active GC
55     -- thread each GC.  The ratio of 'parAvgBytesCopied' divided by
56     -- 'parMaxBytesCopied' approaches 1 for a maximally sequential
57     -- run and approaches the number of threads (set by the RTS flag
58     -- @-N@) for a maximally parallel run.
59     , parMaxBytesCopied :: !Int64
60     } deriving (Show, Read)
61
62     {-
63     , initCpuSeconds :: !Double
64     , initWallSeconds :: !Double
65     -}
66
67 -- | Retrieves garbage collection and memory statistics as of the last
68 -- garbage collection.  If you would like your statistics as recent as
69 -- possible, first run a 'System.Mem.performGC'.
70 getGCStats :: IO GCStats
71 getGCStats = allocaBytes (#size GCStats) $ \p -> do
72     getGCStats_ p
73     bytesAllocated <- (# peek GCStats, bytes_allocated) p
74     numGcs <- (# peek GCStats, num_gcs ) p
75     numByteUsageSamples <- (# peek GCStats, num_byte_usage_samples ) p
76     maxBytesUsed <- (# peek GCStats, max_bytes_used ) p
77     cumulativeBytesUsed <- (# peek GCStats, cumulative_bytes_used ) p
78     bytesCopied <- (# peek GCStats, bytes_copied ) p
79     currentBytesUsed <- (# peek GCStats, current_bytes_used ) p
80     currentBytesSlop <- (# peek GCStats, current_bytes_slop) p
81     maxBytesSlop <- (# peek GCStats, max_bytes_slop) p
82     peakMegabytesAllocated <- (# peek GCStats, peak_megabytes_allocated ) p
83     {-
84     initCpuSeconds <- (# peek GCStats, init_cpu_seconds) p
85     initWallSeconds <- (# peek GCStats, init_wall_seconds) p
86     -}
87     mutatorCpuSeconds <- (# peek GCStats, mutator_cpu_seconds) p
88     mutatorWallSeconds <- (# peek GCStats, mutator_wall_seconds) p
89     gcCpuSeconds <- (# peek GCStats, gc_cpu_seconds) p
90     gcWallSeconds <- (# peek GCStats, gc_wall_seconds) p
91     cpuSeconds <- (# peek GCStats, cpu_seconds) p
92     wallSeconds <- (# peek GCStats, wall_seconds) p
93     parAvgBytesCopied <- (# peek GCStats, par_avg_bytes_copied) p
94     parMaxBytesCopied <- (# peek GCStats, par_max_bytes_copied) p
95     return GCStats { .. }
96
97 {-
98
99 -- Nontrivial to implement: TaskStats needs arbitrarily large
100 -- amounts of memory, spark stats wants to use SparkCounters
101 -- but that needs a new rts/ header.
102
103 data TaskStats = TaskStats
104     { taskMutCpuSeconds :: Int64
105     , taskMutWallSeconds :: Int64
106     , taskGcCpuSeconds :: Int64
107     , taskGcWallSeconds :: Int64
108     } deriving (Show, Read)
109
110 data SparkStats = SparkStats
111     { sparksCreated :: Int64
112     , sparksDud :: Int64
113     , sparksOverflowed :: Int64
114     , sparksConverted :: Int64
115     , sparksGcd :: Int64
116     , sparksFizzled :: Int64
117     } deriving (Show, Read)
118
119 -- We also could get per-generation stats, which requires a
120 -- non-constant but at runtime known about of memory.
121
122 -}