text: /* -----------------------------------------------------------------------------
   *
   * (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 ticky;          /* trace ticky-ticky samples */
      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)
  #define DEFAULT_LINKER_ALWAYS_PIC true
  #else
  #define DEFAULT_LINKER_ALWAYS_PIC false
  #endif
  
  /* Which I/O Manager to use in the target program.  */
  typedef enum _IO_MANAGER { IO_MNGR_NATIVE, IO_MNGR_POSIX } IO_MANAGER;
  
  /* 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 */
      IO_MANAGER ioManager;        /* The I/O manager to use.  */
      uint32_t numIoWorkerThreads; /* Number of I/O worker threads to use.  */
  } 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;
  