Merge branch 'master' of /home/dafis/GHC/./ghc//libraries/base
[packages/base.git] / GHC / Stats.hsc
1 {-# LANGUAGE CPP #-}
2 {-# LANGUAGE ForeignFunctionInterface #-}
3 {-# LANGUAGE RecordWildCards #-}
4
5 module GHC.Stats
6     ( GCStats(..)
7     , getGCStats
8 ) where
9
10 import Foreign.Marshal.Alloc
11 import Foreign.Storable
12 import Foreign.Ptr
13 import Data.Int
14
15 #include "Rts.h"
16
17 foreign import ccall "getGCStats"    getGCStats_    :: Ptr () -> IO ()
18
19 -- I'm probably violating a bucket of constraints here... oops.
20
21 -- | Global garbage collection and memory statistics.
22 data GCStats = GCStats
23     { bytes_allocated :: Int64 -- ^ Total number of bytes allocated
24     , num_gcs :: Int64 -- ^ Number of garbage collections performed
25     , max_bytes_used :: Int64 -- ^ Maximum number of live bytes seen so far
26     , num_byte_usage_samples :: Int64 -- ^ Number of byte usage samples taken
27     -- | Sum of all byte usage samples, can be used with
28     -- 'num_byte_usage_samples' to calculate averages with
29     -- arbitrary weighting (if you are sampling this record multiple
30     -- times).
31     , cumulative_bytes_used :: Int64
32     , bytes_copied :: Int64 -- ^ Number of bytes copied during GC
33     , current_bytes_used :: Int64 -- ^ Current number of live bytes
34     , current_bytes_slop :: Int64 -- ^ Current number of bytes lost to slop
35     , max_bytes_slop :: Int64 -- ^ Maximum number of bytes lost to slop at any one time so far
36     , peak_megabytes_allocated :: Int64 -- ^ Maximum number of megabytes allocated
37     -- | CPU time spent running mutator threads.  This does not include
38     -- any profiling overhead or initialization.
39     , mutator_cpu_seconds :: Double
40     -- | Wall clock time spent running mutator threads.  This does not
41     -- include initialization.
42     , mutator_wall_seconds :: Double
43     , gc_cpu_seconds :: Double -- ^ CPU time spent running GC
44     , gc_wall_seconds :: Double -- ^ Wall clock time spent running GC
45     -- | Number of bytes copied during GC, minus space held by mutable
46     -- lists held by the capabilities.  Can be used with
47     -- 'par_max_bytes_copied' to determine how well parallel GC utilized
48     -- all cores.
49     , par_avg_bytes_copied :: Int64
50     -- | Sum of number of bytes copied each GC by the most active GC
51     -- thread each GC.  The ratio of 'par_avg_bytes_copied' divided by
52     -- 'par_max_bytes_copied' approaches 1 for a maximally sequential
53     -- run and approaches the number of threads (set by the RTS flag
54     -- @-N@) for a maximally parallel run.
55     , par_max_bytes_copied :: Int64
56     } deriving (Show, Read)
57
58     {-
59     , g_init_cpu_seconds :: Double
60     , g_init_wall_seconds :: Double
61     -}
62
63 -- | Retrieves garbage collection and memory statistics as of the last
64 -- garbage collection.  If you would like your statistics as recent as
65 -- possible, first run a 'performGC' from "System.Mem".
66 getGCStats :: IO GCStats
67 getGCStats = allocaBytes (#size GCStats) $ \p -> do
68     getGCStats_ p
69     bytes_allocated <- (# peek GCStats, bytes_allocated) p
70     num_gcs <- (# peek GCStats, num_gcs ) p
71     num_byte_usage_samples <- (# peek GCStats, num_byte_usage_samples ) p
72     max_bytes_used <- (# peek GCStats, max_bytes_used ) p
73     cumulative_bytes_used <- (# peek GCStats, cumulative_bytes_used ) p
74     bytes_copied <- (# peek GCStats, bytes_copied ) p
75     current_bytes_used <- (# peek GCStats, current_bytes_used ) p
76     current_bytes_slop <- (# peek GCStats, current_bytes_slop) p
77     max_bytes_slop <- (# peek GCStats, max_bytes_slop) p
78     peak_megabytes_allocated <- (# peek GCStats, peak_megabytes_allocated ) p
79     {-
80     init_cpu_seconds <- (# peek GCStats, init_cpu_seconds) p
81     init_wall_seconds <- (# peek GCStats, init_wall_seconds) p
82     -}
83     mutator_cpu_seconds <- (# peek GCStats, mutator_cpu_seconds) p
84     mutator_wall_seconds <- (# peek GCStats, mutator_wall_seconds) p
85     gc_cpu_seconds <- (# peek GCStats, gc_cpu_seconds) p
86     gc_wall_seconds <- (# peek GCStats, gc_wall_seconds) p
87     par_avg_bytes_copied <- (# peek GCStats, par_avg_bytes_copied) p
88     par_max_bytes_copied <- (# peek GCStats, par_max_bytes_copied) p
89     return GCStats { .. }
90
91 {-
92
93 -- Nontrivial to implement: TaskStats needs arbitrarily large
94 -- amounts of memory, spark stats wants to use SparkCounters
95 -- but that needs a new rts/ header.
96
97 data TaskStats = TaskStats
98     { task_mut_cpu_seconds :: Int64
99     , task_mut_wall_seconds :: Int64
100     , task_gc_cpu_seconds :: Int64
101     , task_gc_wall_seconds :: Int64
102     } deriving (Show, Read)
103
104 data SparkStats = SparkStats
105     { sparks_created :: Int64
106     , sparks_dud :: Int64
107     , sparks_overflowed :: Int64
108     , sparks_converted :: Int64
109     , sparks_gcd :: Int64
110     , sparks_fizzled :: Int64
111     } deriving (Show, Read)
112
113 -- We also could get per-generation stats, which requires a
114 -- non-constant but at runtime known about of memory.
115
116 -}