2023-01-19 12:37:04 -05:00

321 lines
11 KiB
C

/* -----------------------------------------------------------------------------
*
* (c) The GHC Team, 1998-2009
*
* Datatypes that holds the command-line flag settings.
*
* Do not #include this file directly: #include "Rts.h" instead.
*
* To understand the structure of the RTS headers, see the wiki:
* https://gitlab.haskell.org/ghc/ghc/wikis/commentary/source-tree/includes
*
* ---------------------------------------------------------------------------*/
#pragma once
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "stg/Types.h"
#include "Time.h"
/* For defaults, see the @initRtsFlagsDefaults@ routine. */
/* Note [Synchronization of flags and base APIs]
*
* We provide accessors to RTS flags in base. (GHC.RTS module)
* The API should be updated whenever RTS flags are modified.
*/
/* See Note [Synchronization of flags and base APIs] */
typedef struct _GC_FLAGS {
FILE *statsFile;
uint32_t giveStats;
#define NO_GC_STATS 0
#define COLLECT_GC_STATS 1
#define ONELINE_GC_STATS 2
#define SUMMARY_GC_STATS 3
#define VERBOSE_GC_STATS 4
uint32_t maxStkSize; /* in *words* */
uint32_t initialStkSize; /* in *words* */
uint32_t stkChunkSize; /* in *words* */
uint32_t stkChunkBufferSize; /* in *words* */
uint32_t maxHeapSize; /* in *blocks* */
uint32_t minAllocAreaSize; /* in *blocks* */
uint32_t largeAllocLim; /* in *blocks* */
uint32_t nurseryChunkSize; /* in *blocks* */
uint32_t minOldGenSize; /* in *blocks* */
uint32_t heapSizeSuggestion; /* in *blocks* */
bool heapSizeSuggestionAuto;
double oldGenFactor;
double pcFreeHeap;
bool useNonmoving; // default = false
bool nonmovingSelectorOpt; // Do selector optimization in the
// non-moving heap, default = false
uint32_t generations;
bool squeezeUpdFrames;
bool compact; /* True <=> "compact all the time" */
double compactThreshold;
bool sweep; /* use "mostly mark-sweep" instead of copying
* for the oldest generation */
bool ringBell;
Time idleGCDelayTime; /* units: TIME_RESOLUTION */
Time interIdleGCWait; /* units: TIME_RESOLUTION */
bool doIdleGC;
Time longGCSync; /* units: TIME_RESOLUTION */
StgWord heapBase; /* address to ask the OS for memory */
StgWord allocLimitGrace; /* units: *blocks*
* After an AllocationLimitExceeded
* exception has been raised, how much
* extra space is given to the thread
* to handle the exception before we
* raise it again.
*/
StgWord heapLimitGrace; /* units: *blocks*
* After a HeapOverflow exception has
* been raised, how much extra space is
* given to the thread to handle the
* exception before we raise it again.
*/
bool numa; /* Use NUMA */
StgWord numaMask;
} GC_FLAGS;
/* See Note [Synchronization of flags and base APIs] */
typedef struct _DEBUG_FLAGS {
/* flags to control debugging output & extra checking in various subsystems */
bool scheduler; /* 's' */
bool interpreter; /* 'i' */
bool weak; /* 'w' */
bool gccafs; /* 'G' */
bool gc; /* 'g' */
bool nonmoving_gc; /* 'n' */
bool block_alloc; /* 'b' */
bool sanity; /* 'S' warning: might be expensive! */
bool zero_on_gc; /* 'Z' */
bool stable; /* 't' */
bool prof; /* 'p' */
bool linker; /* 'l' the object linker */
bool apply; /* 'a' */
bool stm; /* 'm' */
bool squeeze; /* 'z' stack squeezing & lazy blackholing */
bool hpc; /* 'c' coverage */
bool sparks; /* 'r' */
bool numa; /* '--debug-numa' */
bool compact; /* 'C' */
} DEBUG_FLAGS;
/* See Note [Synchronization of flags and base APIs] */
typedef struct _COST_CENTRE_FLAGS {
uint32_t doCostCentres;
# define COST_CENTRES_NONE 0
# define COST_CENTRES_SUMMARY 1
# define COST_CENTRES_VERBOSE 2 /* incl. serial time profile */
# define COST_CENTRES_ALL 3
# define COST_CENTRES_JSON 4
int profilerTicks; /* derived */
int msecsPerTick; /* derived */
char const *outputFileNameStem;
} COST_CENTRE_FLAGS;
/* See Note [Synchronization of flags and base APIs] */
typedef struct _PROFILING_FLAGS {
uint32_t doHeapProfile;
# define NO_HEAP_PROFILING 0 /* N.B. Used as indexes into arrays */
# define HEAP_BY_CCS 1
# define HEAP_BY_MOD 2
# define HEAP_BY_DESCR 4
# define HEAP_BY_TYPE 5
# define HEAP_BY_RETAINER 6
# define HEAP_BY_LDV 7
# define HEAP_BY_CLOSURE_TYPE 8
Time heapProfileInterval; /* time between samples */
uint32_t heapProfileIntervalTicks; /* ticks between samples (derived) */
bool includeTSOs;
bool showCCSOnException;
uint32_t maxRetainerSetSize;
uint32_t ccsLength;
const char* modSelector;
const char* descrSelector;
const char* typeSelector;
const char* ccSelector;
const char* ccsSelector;
const char* retainerSelector;
const char* bioSelector;
} PROFILING_FLAGS;
#define TRACE_NONE 0
#define TRACE_EVENTLOG 1
#define TRACE_STDERR 2
/* See Note [Synchronization of flags and base APIs] */
typedef struct _TRACE_FLAGS {
int tracing;
bool timestamp; /* show timestamp in stderr output */
bool scheduler; /* trace scheduler events */
bool gc; /* trace GC events */
bool nonmoving_gc; /* trace nonmoving GC events */
bool sparks_sampled; /* trace spark events by a sampled method */
bool sparks_full; /* trace spark events 100% accurately */
bool user; /* trace user events (emitted from Haskell code) */
char *trace_output; /* output filename for eventlog */
} TRACE_FLAGS;
/* See Note [Synchronization of flags and base APIs] */
typedef struct _CONCURRENT_FLAGS {
Time ctxtSwitchTime; /* units: TIME_RESOLUTION */
int ctxtSwitchTicks; /* derived */
} CONCURRENT_FLAGS;
/*
* The tickInterval is the time interval between "ticks", ie.
* timer signals (see Timer.{c,h}). It is the frequency at
* which we sample CCCS for profiling.
*
* It is changed by the +RTS -V<secs> flag.
*/
#define DEFAULT_TICK_INTERVAL USToTime(10000)
/*
* When linkerAlwaysPic is true, the runtime linker assume that all object
* files were compiled with -fPIC -fexternal-dynamic-refs and load them
* anywhere in the address space.
* Note that there is no 32bit darwin system we can realistically expect to
* run on or compile for.
*/
#if defined(darwin_HOST_OS) || defined(aarch64_HOST_ARCH) || defined(arm_HOST_ARCH)
#define DEFAULT_LINKER_ALWAYS_PIC true
#else
#define DEFAULT_LINKER_ALWAYS_PIC false
#endif
/* See Note [Synchronization of flags and base APIs] */
typedef struct _MISC_FLAGS {
Time tickInterval; /* units: TIME_RESOLUTION */
bool install_signal_handlers;
bool install_seh_handlers;
bool generate_dump_file;
bool generate_stack_trace;
bool machineReadable;
bool disableDelayedOsMemoryReturn; /* See Note [MADV_FREE and MADV_DONTNEED].
It's in `MiscFlags` instead of
`GcFlags` because if GHC used madvise()
memory management for non-GC related
tasks in the future, we'd respect it
there as well. */
bool internalCounters; /* See Note [Internal Counter Stats] */
bool linkerAlwaysPic; /* Assume the object code is always PIC */
StgWord linkerMemBase; /* address to ask the OS for memory
* for the linker, NULL ==> off */
} MISC_FLAGS;
/* See Note [Synchronization of flags and base APIs] */
typedef struct _PAR_FLAGS {
uint32_t nCapabilities; /* number of threads to run simultaneously */
bool migrate; /* migrate threads between capabilities */
uint32_t maxLocalSparks;
bool parGcEnabled; /* enable parallel GC */
uint32_t parGcGen; /* do parallel GC in this generation
* and higher only */
bool parGcLoadBalancingEnabled;
/* enable load-balancing in the
* parallel GC */
uint32_t parGcLoadBalancingGen;
/* do load-balancing in this
* generation and higher only */
uint32_t parGcNoSyncWithIdle;
/* if a Capability has been idle for
* this many GCs, do not try to wake
* it up when doing a
* non-load-balancing parallel GC.
* (zero disables) */
uint32_t parGcThreads;
/* Use this many threads for parallel
* GC (default: use all nNodes). */
bool setAffinity; /* force thread affinity with CPUs */
} PAR_FLAGS;
/* See Note [Synchronization of flags and base APIs] */
typedef struct _TICKY_FLAGS {
bool showTickyStats;
FILE *tickyFile;
} TICKY_FLAGS;
/* Put them together: */
/* See Note [Synchronization of flags and base APIs] */
typedef struct _RTS_FLAGS {
/* The first portion of RTS_FLAGS is invariant. */
GC_FLAGS GcFlags;
CONCURRENT_FLAGS ConcFlags;
MISC_FLAGS MiscFlags;
DEBUG_FLAGS DebugFlags;
COST_CENTRE_FLAGS CcFlags;
PROFILING_FLAGS ProfFlags;
TRACE_FLAGS TraceFlags;
TICKY_FLAGS TickyFlags;
PAR_FLAGS ParFlags;
} RTS_FLAGS;
#if defined(COMPILING_RTS_MAIN)
extern DLLIMPORT RTS_FLAGS RtsFlags;
#elif IN_STG_CODE
/* Note [RtsFlags is a pointer in STG code]
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* When compiling with IN_STG_CODE the RtsFlags symbol is defined as a pointer.
* This is necessary because the C code generator can't generate '&label'.
*/
extern RTS_FLAGS RtsFlags[];
#else
extern RTS_FLAGS RtsFlags;
#endif
/*
* The printf formats are here, so we are less likely to make
* overly-long filenames (with disastrous results). No more than 128
* chars, please!
*/
#define STATS_FILENAME_MAXLEN 128
#define GR_FILENAME_FMT "%0.124s.gr"
#define HP_FILENAME_FMT "%0.124s.hp"
#define LIFE_FILENAME_FMT "%0.122s.life"
#define PROF_FILENAME_FMT "%0.122s.prof"
#define PROF_FILENAME_FMT_GUM "%0.118s.%03d.prof"
#define QP_FILENAME_FMT "%0.124s.qp"
#define STAT_FILENAME_FMT "%0.122s.stat"
#define TICKY_FILENAME_FMT "%0.121s.ticky"
#define TIME_FILENAME_FMT "%0.122s.time"
#define TIME_FILENAME_FMT_GUM "%0.118s.%03d.time"
/* an "int" so as to match normal "argc" */
/* Now defined in Stg.h (lib/std/cbits need these too.)
extern int prog_argc;
extern char **prog_argv;
*/
extern int rts_argc; /* ditto */
extern char **rts_argv;