{-# LINE 1 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE RecordWildCards #-}
{-# OPTIONS_GHC -funbox-strict-fields #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  GHC.Internal.RTS.Stats
-- Copyright   :  (c) The University of Glasgow, 1994-2000
-- License     :  see libraries/base/LICENSE
--
-- Maintainer  :  ghc-devs@haskell.org
-- Stability   :  internal
-- Portability :  non-portable (GHC extensions)
--
-- This module provides access to internal garbage collection and
-- memory usage statistics.  These statistics are not available unless
-- a program is run with the @-T@ RTS flag.
--
-- /The API of this module is unstable and is tightly coupled to GHC's internals./
-- If depend on it, make sure to use a tight upper bound, e.g., @base < 4.X@ rather
-- than @base < 5@, because the interface can change rapidly without much warning.
--
-- @since base-4.5.0.0
-----------------------------------------------------------------------------
module GHC.Internal.Stats
    (
    -- * Runtime statistics
      RTSStats(..), GCDetails(..), RtsTime
    , getRTSStats
    , getRTSStatsEnabled
) where

import GHC.Internal.Control.Monad
import GHC.Internal.Int
import GHC.Internal.Word
import GHC.Internal.Base
import GHC.Internal.Generics (Generic)
import GHC.Internal.Read ( Read )
import GHC.Internal.Show ( Show )
import GHC.Internal.IO.Exception
import GHC.Internal.Foreign.Marshal.Alloc
import GHC.Internal.Foreign.Storable
import GHC.Internal.Foreign.Ptr



foreign import ccall "getRTSStats" getRTSStats_ :: Ptr () -> IO ()

-- | Returns whether GC stats have been enabled (with @+RTS -T@, for example).
--
-- @since base-4.10.0.0
foreign import ccall "getRTSStatsEnabled" getRTSStatsEnabled :: IO Bool

--
-- | Statistics about runtime activity since the start of the
-- program.  This is a mirror of the C @struct RTSStats@ in @RtsAPI.h@
--
-- @since base-4.10.0.0
--
data RTSStats = RTSStats {
  -- -----------------------------------
  -- Cumulative stats about memory use

    -- | Total number of GCs
    RTSStats -> Word32
gcs :: Word32
    -- | Total number of major (oldest generation) GCs
  , RTSStats -> Word32
major_gcs :: Word32
    -- | Total bytes allocated
  , RTSStats -> Word64
allocated_bytes :: Word64
    -- | Maximum live data (including large objects + compact regions) in the
    -- heap. Updated after a major GC.
  , RTSStats -> Word64
max_live_bytes :: Word64
    -- | Maximum live data in large objects
  , RTSStats -> Word64
max_large_objects_bytes :: Word64
    -- | Maximum live data in compact regions
  , RTSStats -> Word64
max_compact_bytes :: Word64
    -- | Maximum slop
  , RTSStats -> Word64
max_slop_bytes :: Word64
    -- | Maximum memory in use by the RTS
  , RTSStats -> Word64
max_mem_in_use_bytes :: Word64
    -- | Sum of live bytes across all major GCs.  Divided by major_gcs
    -- gives the average live data over the lifetime of the program.
  , RTSStats -> Word64
cumulative_live_bytes :: Word64
    -- | Sum of copied_bytes across all GCs
  , RTSStats -> Word64
copied_bytes :: Word64
    -- | Sum of copied_bytes across all parallel GCs
  , RTSStats -> Word64
par_copied_bytes :: Word64
    -- | Sum of par_max_copied_bytes across all parallel GCs. Deprecated.
  , RTSStats -> Word64
cumulative_par_max_copied_bytes :: Word64
    -- | Sum of par_balanced_copied bytes across all parallel GCs
  , RTSStats -> Word64
cumulative_par_balanced_copied_bytes :: Word64

  -- -----------------------------------
  -- Cumulative stats about time use
  -- (we use signed values here because due to inaccuracies in timers
  -- the values can occasionally go slightly negative)

    -- | Total CPU time used by the init phase
    -- @since base-4.12.0.0
  , RTSStats -> RtsTime
init_cpu_ns :: RtsTime
    -- | Total elapsed time used by the init phase
    -- @since base-4.12.0.0
  , RTSStats -> RtsTime
init_elapsed_ns :: RtsTime
    -- | Total CPU time used by the mutator
  , RTSStats -> RtsTime
mutator_cpu_ns :: RtsTime
    -- | Total elapsed time used by the mutator
  , RTSStats -> RtsTime
mutator_elapsed_ns :: RtsTime
    -- | Total CPU time used by the GC
  , RTSStats -> RtsTime
gc_cpu_ns :: RtsTime
    -- | Total elapsed time used by the GC
  , RTSStats -> RtsTime
gc_elapsed_ns :: RtsTime
    -- | Total CPU time (at the previous GC)
  , RTSStats -> RtsTime
cpu_ns :: RtsTime
    -- | Total elapsed time (at the previous GC)
  , RTSStats -> RtsTime
elapsed_ns :: RtsTime

    -- | The total CPU time used during the post-mark pause phase of the
    -- concurrent nonmoving GC.
  , RTSStats -> RtsTime
nonmoving_gc_sync_cpu_ns :: RtsTime
    -- | The total time elapsed during the post-mark pause phase of the
    -- concurrent nonmoving GC.
  , RTSStats -> RtsTime
nonmoving_gc_sync_elapsed_ns :: RtsTime
    -- | The maximum elapsed length of any post-mark pause phase of the
    -- concurrent nonmoving GC.
  , RTSStats -> RtsTime
nonmoving_gc_sync_max_elapsed_ns :: RtsTime
    -- | The total CPU time used by the nonmoving GC.
  , RTSStats -> RtsTime
nonmoving_gc_cpu_ns :: RtsTime
    -- | The total time elapsed during which there is a nonmoving GC active.
  , RTSStats -> RtsTime
nonmoving_gc_elapsed_ns :: RtsTime
    -- | The maximum time elapsed during any nonmoving GC cycle.
  , RTSStats -> RtsTime
nonmoving_gc_max_elapsed_ns :: RtsTime

    -- | Details about the most recent GC
  , RTSStats -> GCDetails
gc :: GCDetails
  } deriving ( ReadPrec [RTSStats]
ReadPrec RTSStats
Int -> ReadS RTSStats
ReadS [RTSStats]
(Int -> ReadS RTSStats)
-> ReadS [RTSStats]
-> ReadPrec RTSStats
-> ReadPrec [RTSStats]
-> Read RTSStats
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS RTSStats
readsPrec :: Int -> ReadS RTSStats
$creadList :: ReadS [RTSStats]
readList :: ReadS [RTSStats]
$creadPrec :: ReadPrec RTSStats
readPrec :: ReadPrec RTSStats
$creadListPrec :: ReadPrec [RTSStats]
readListPrec :: ReadPrec [RTSStats]
Read -- ^ @since base-4.10.0.0
             , Int -> RTSStats -> ShowS
[RTSStats] -> ShowS
RTSStats -> String
(Int -> RTSStats -> ShowS)
-> (RTSStats -> String) -> ([RTSStats] -> ShowS) -> Show RTSStats
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RTSStats -> ShowS
showsPrec :: Int -> RTSStats -> ShowS
$cshow :: RTSStats -> String
show :: RTSStats -> String
$cshowList :: [RTSStats] -> ShowS
showList :: [RTSStats] -> ShowS
Show -- ^ @since base-4.10.0.0
             , (forall x. RTSStats -> Rep RTSStats x)
-> (forall x. Rep RTSStats x -> RTSStats) -> Generic RTSStats
forall x. Rep RTSStats x -> RTSStats
forall x. RTSStats -> Rep RTSStats x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. RTSStats -> Rep RTSStats x
from :: forall x. RTSStats -> Rep RTSStats x
$cto :: forall x. Rep RTSStats x -> RTSStats
to :: forall x. Rep RTSStats x -> RTSStats
Generic -- ^ @since base-4.15.0.0
             )

--
-- | Statistics about a single GC.  This is a mirror of the C @struct
--   GCDetails@ in @RtsAPI.h@, with the field prefixed with @gc_@ to
--   avoid collisions with 'RTSStats'.
--
data GCDetails = GCDetails {
    -- | The generation number of this GC
    GCDetails -> Word32
gcdetails_gen :: Word32
    -- | Number of threads used in this GC
  , GCDetails -> Word32
gcdetails_threads :: Word32
    -- | Number of bytes allocated since the previous GC
  , GCDetails -> Word64
gcdetails_allocated_bytes :: Word64
    -- | Total amount of live data in the heap (includes large + compact data).
    -- Updated after every GC. Data in uncollected generations (in minor GCs)
    -- are considered live.
  , GCDetails -> Word64
gcdetails_live_bytes :: Word64
    -- | Total amount of live data in large objects
  , GCDetails -> Word64
gcdetails_large_objects_bytes :: Word64
    -- | Total amount of live data in compact regions
  , GCDetails -> Word64
gcdetails_compact_bytes :: Word64
    -- | Total amount of slop (wasted memory)
  , GCDetails -> Word64
gcdetails_slop_bytes :: Word64
    -- | Total amount of memory in use by the RTS
  , GCDetails -> Word64
gcdetails_mem_in_use_bytes :: Word64
    -- | Total amount of data copied during this GC
  , GCDetails -> Word64
gcdetails_copied_bytes :: Word64
    -- | In parallel GC, the max amount of data copied by any one thread.
    -- Deprecated.
  , GCDetails -> Word64
gcdetails_par_max_copied_bytes :: Word64
    -- | In parallel GC, the amount of balanced data copied by all threads
  , GCDetails -> Word64
gcdetails_par_balanced_copied_bytes :: Word64
    -- | The amount of memory lost due to block fragmentation in bytes.
    -- Block fragmentation is the difference between the amount of blocks retained by the RTS and the blocks that are in use.
    -- This occurs when megablocks are only sparsely used, eg, when data that cannot be moved retains a megablock.
    --
    -- @since base-4.18.0.0
  , GCDetails -> Word64
gcdetails_block_fragmentation_bytes :: Word64
    -- | The time elapsed during synchronisation before GC
  , GCDetails -> RtsTime
gcdetails_sync_elapsed_ns :: RtsTime
    -- | The CPU time used during GC itself
  , GCDetails -> RtsTime
gcdetails_cpu_ns :: RtsTime
    -- | The time elapsed during GC itself
  , GCDetails -> RtsTime
gcdetails_elapsed_ns :: RtsTime

    -- | The CPU time used during the post-mark pause phase of the concurrent
    -- nonmoving GC.
  , GCDetails -> RtsTime
gcdetails_nonmoving_gc_sync_cpu_ns :: RtsTime
    -- | The time elapsed during the post-mark pause phase of the concurrent
    -- nonmoving GC.
  , GCDetails -> RtsTime
gcdetails_nonmoving_gc_sync_elapsed_ns :: RtsTime
  } deriving ( ReadPrec [GCDetails]
ReadPrec GCDetails
Int -> ReadS GCDetails
ReadS [GCDetails]
(Int -> ReadS GCDetails)
-> ReadS [GCDetails]
-> ReadPrec GCDetails
-> ReadPrec [GCDetails]
-> Read GCDetails
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS GCDetails
readsPrec :: Int -> ReadS GCDetails
$creadList :: ReadS [GCDetails]
readList :: ReadS [GCDetails]
$creadPrec :: ReadPrec GCDetails
readPrec :: ReadPrec GCDetails
$creadListPrec :: ReadPrec [GCDetails]
readListPrec :: ReadPrec [GCDetails]
Read -- ^ @since base-4.10.0.0
             , Int -> GCDetails -> ShowS
[GCDetails] -> ShowS
GCDetails -> String
(Int -> GCDetails -> ShowS)
-> (GCDetails -> String)
-> ([GCDetails] -> ShowS)
-> Show GCDetails
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GCDetails -> ShowS
showsPrec :: Int -> GCDetails -> ShowS
$cshow :: GCDetails -> String
show :: GCDetails -> String
$cshowList :: [GCDetails] -> ShowS
showList :: [GCDetails] -> ShowS
Show -- ^ @since base-4.10.0.0
             , (forall x. GCDetails -> Rep GCDetails x)
-> (forall x. Rep GCDetails x -> GCDetails) -> Generic GCDetails
forall x. Rep GCDetails x -> GCDetails
forall x. GCDetails -> Rep GCDetails x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. GCDetails -> Rep GCDetails x
from :: forall x. GCDetails -> Rep GCDetails x
$cto :: forall x. Rep GCDetails x -> GCDetails
to :: forall x. Rep GCDetails x -> GCDetails
Generic -- ^ @since base-4.15.0.0
             )

-- | Time values from the RTS, using a fixed resolution of nanoseconds.
type RtsTime = Int64

-- | Get current runtime system statistics.
--
-- @since base-4.10.0.0
--
getRTSStats :: IO RTSStats
getRTSStats :: IO RTSStats
getRTSStats = do
  statsEnabled <- IO Bool
getRTSStatsEnabled
  unless statsEnabled .  ioError $ IOError
    Nothing
    UnsupportedOperation
    ""
    "GHC.Stats.getRTSStats: GC stats not enabled. Use `+RTS -T -RTS' to enable them."
    Nothing
    Nothing
  allocaBytes ((376)) $ \Ptr ()
p -> do
{-# LINE 215 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    getRTSStats_ p
    gcs <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) p
{-# LINE 217 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    major_gcs <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) p
{-# LINE 218 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    allocated_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) p
{-# LINE 219 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    max_live_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 16)) p
{-# LINE 220 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    max_large_objects_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 24)) p
{-# LINE 221 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    max_compact_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 32)) p
{-# LINE 222 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    max_slop_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 40)) p
{-# LINE 223 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    max_mem_in_use_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 48)) p
{-# LINE 224 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    cumulative_live_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 56)) p
{-# LINE 225 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    copied_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 64)) p
{-# LINE 226 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    par_copied_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 72)) p
{-# LINE 227 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    cumulative_par_max_copied_bytes <-
      ((\hsc_ptr -> peekByteOff hsc_ptr 80)) p
{-# LINE 229 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    cumulative_par_balanced_copied_bytes <-
      ((\hsc_ptr -> peekByteOff hsc_ptr 88)) p
{-# LINE 231 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    init_cpu_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 96)) p
{-# LINE 232 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    init_elapsed_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 104)) p
{-# LINE 233 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    mutator_cpu_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 112)) p
{-# LINE 234 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    mutator_elapsed_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 120)) p
{-# LINE 235 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    gc_cpu_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 128)) p
{-# LINE 236 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    gc_elapsed_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 136)) p
{-# LINE 237 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    cpu_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 144)) p
{-# LINE 238 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    elapsed_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 152)) p
{-# LINE 239 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    nonmoving_gc_sync_cpu_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 328)) p
{-# LINE 240 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    nonmoving_gc_sync_elapsed_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 336)) p
{-# LINE 241 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    nonmoving_gc_sync_max_elapsed_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 344)) p
{-# LINE 242 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    nonmoving_gc_cpu_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 352)) p
{-# LINE 243 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    nonmoving_gc_elapsed_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 360)) p
{-# LINE 244 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    nonmoving_gc_max_elapsed_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 368)) p
{-# LINE 245 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    let pgc = ((\hsc_ptr -> hsc_ptr `plusPtr` 160)) p
{-# LINE 246 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
    gc <- do
      gcdetails_gen <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) pgc
{-# LINE 248 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_threads <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) pgc
{-# LINE 249 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_allocated_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) pgc
{-# LINE 250 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_live_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 16)) pgc
{-# LINE 251 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_large_objects_bytes <-
        ((\hsc_ptr -> peekByteOff hsc_ptr 24)) pgc
{-# LINE 253 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_compact_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 32)) pgc
{-# LINE 254 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_slop_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 40)) pgc
{-# LINE 255 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_mem_in_use_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 48)) pgc
{-# LINE 256 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_copied_bytes <- ((\hsc_ptr -> peekByteOff hsc_ptr 56)) pgc
{-# LINE 257 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_par_max_copied_bytes <-
        ((\hsc_ptr -> peekByteOff hsc_ptr 72)) pgc
{-# LINE 259 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_par_balanced_copied_bytes <-
        ((\hsc_ptr -> peekByteOff hsc_ptr 80)) pgc
{-# LINE 261 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_block_fragmentation_bytes <-
        ((\hsc_ptr -> peekByteOff hsc_ptr 64)) pgc
{-# LINE 263 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_sync_elapsed_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 88)) pgc
{-# LINE 264 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_cpu_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 96)) pgc
{-# LINE 265 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_elapsed_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 104)) pgc
{-# LINE 266 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_nonmoving_gc_sync_cpu_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 112)) pgc
{-# LINE 267 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      gcdetails_nonmoving_gc_sync_elapsed_ns <- ((\hsc_ptr -> peekByteOff hsc_ptr 120)) pgc
{-# LINE 268 "libraries/ghc-internal/src/GHC/Internal/Stats.hsc" #-}
      return GCDetails{..}
    return RTSStats{..}