diff options
author | Simon Marlow <marlowsd@gmail.com> | 2014-06-09 09:18:12 +0100 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2015-04-07 09:57:49 +0100 |
commit | a7ab161602aa0b5833d22c66e64eebb1d9275235 (patch) | |
tree | 22db09216cbd2165359d8add08b5cf4cdbf5041f /rts/RtsFlags.c | |
parent | 72092904e0ac1725c05c0447e1efe7ab541faa95 (diff) | |
download | haskell-a7ab161602aa0b5833d22c66e64eebb1d9275235.tar.gz |
Replace hooks by callbacks in RtsConfig (#8785)
Summary:
Hooks rely on static linking semantics, and are broken by -Bsymbolic
which we need when using dynamic linking.
Test Plan: Built it
Reviewers: austin, hvr, tibbe
Differential Revision: https://phabricator.haskell.org/D8
Diffstat (limited to 'rts/RtsFlags.c')
-rw-r--r-- | rts/RtsFlags.c | 153 |
1 files changed, 97 insertions, 56 deletions
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index d7114bf88b..ef01ccb3ab 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -14,6 +14,7 @@ #include "Profiling.h" #include "RtsFlags.h" #include "sm/OSMem.h" +#include "hooks/Hooks.h" #ifdef HAVE_CTYPE_H #include <ctype.h> @@ -52,6 +53,22 @@ int win32_prog_argc = 0; wchar_t **win32_prog_argv = NULL; #endif +// The global rtsConfig, set from the RtsConfig supplied by the call +// to hs_init_ghc(). +RtsConfig rtsConfig; + +const RtsConfig defaultRtsConfig = { + .rts_opts_enabled = RtsOptsSafeOnly, + .rts_opts = NULL, + .rts_hs_main = rtsFalse, + .defaultsHook = FlagDefaultsHook, + .onExitHook = OnExitHook, + .stackOverflowHook = StackOverflowHook, + .outOfHeapHook = OutOfHeapHook, + .mallocFailHook = MallocFailHook, + .gcDoneHook = NULL +}; + /* * constants, used later */ @@ -62,31 +79,31 @@ wchar_t **win32_prog_argv = NULL; Static function decls -------------------------------------------------------------------------- */ -static void procRtsOpts (HsBool is_hs_main, int rts_argc0, RtsOptsEnabledEnum enabled); +static void procRtsOpts (int rts_argc0, RtsOptsEnabledEnum enabled); static void normaliseRtsOpts (void); -static void initStatsFile (FILE *f); +static void initStatsFile (FILE *f); -static int openStatsFile (char *filename, const char *FILENAME_FMT, - FILE **file_ret); +static int openStatsFile ( + char *filename, const char *FILENAME_FMT, FILE **file_ret); -static StgWord64 decodeSize (const char *flag, nat offset, - StgWord64 min, StgWord64 max); +static StgWord64 decodeSize ( + const char *flag, nat offset, StgWord64 min, StgWord64 max); -static void bad_option (const char *s); +static void bad_option (const char *s); #ifdef TRACING static void read_trace_flags(char *arg); #endif -static void errorUsage (void) GNU_ATTRIBUTE(__noreturn__); +static void errorUsage (void) GNU_ATTRIBUTE(__noreturn__); -static char * copyArg (char *arg); +static char * copyArg (char *arg); static char ** copyArgv (int argc, char *argv[]); static void freeArgv (int argc, char *argv[]); -static void errorRtsOptsDisabled(HsBool is_hs_main, const char *s); +static void errorRtsOptsDisabled (const char *s); /* ----------------------------------------------------------------------------- * Command-line option parsing routines. @@ -416,8 +433,7 @@ usage_text[] = { 0 }; -STATIC_INLINE rtsBool -strequal(const char *a, const char * b) +STATIC_INLINE rtsBool strequal(const char *a, const char * b) { return(strcmp(a, b) == 0); } @@ -457,10 +473,10 @@ static void splitRtsFlags(const char *s) } while (*c1 != '\0'); } -static void -errorRtsOptsDisabled(HsBool is_hs_main, const char *s) { +static void errorRtsOptsDisabled(const char *s) +{ char *advice; - if (is_hs_main) { + if (rtsConfig.rts_hs_main) { advice = "Link with -rtsopts to enable them."; } else { advice = "Use hs_init_with_rtsopts() to enable them."; @@ -483,17 +499,18 @@ errorRtsOptsDisabled(HsBool is_hs_main, const char *s) { - prog_name (global) contains the basename of prog_argv[0] + - rtsConfig (global) contains the supplied RtsConfig + -------------------------------------------------------------------------- */ -void setupRtsFlags (int *argc, char *argv[], - RtsOptsEnabledEnum rtsOptsEnabled, - const char *ghc_rts_opts, - HsBool is_hs_main) +void setupRtsFlags (int *argc, char *argv[], RtsConfig rts_config) { nat mode; nat total_arg; nat arg, rts_argc0; + rtsConfig = rts_config; + setProgName (argv); total_arg = *argc; arg = 1; @@ -510,10 +527,10 @@ void setupRtsFlags (int *argc, char *argv[], // (arguments from the GHCRTS environment variable and the command // line override these). { - if (ghc_rts_opts != NULL) { - splitRtsFlags(ghc_rts_opts); - // opts from ghc_rts_opts are always enabled: - procRtsOpts(is_hs_main, rts_argc0, RtsOptsAll); + if (rtsConfig.rts_opts != NULL) { + splitRtsFlags(rtsConfig.rts_opts); + // opts from rts_opts are always enabled: + procRtsOpts(rts_argc0, RtsOptsAll); rts_argc0 = rts_argc; } } @@ -524,12 +541,13 @@ void setupRtsFlags (int *argc, char *argv[], char *ghc_rts = getenv("GHCRTS"); if (ghc_rts != NULL) { - if (rtsOptsEnabled == RtsOptsNone) { - errorRtsOptsDisabled(is_hs_main, "Warning: Ignoring GHCRTS variable as RTS options are disabled.\n %s"); + if (rtsConfig.rts_opts_enabled == RtsOptsNone) { + errorRtsOptsDisabled( + "Warning: Ignoring GHCRTS variable as RTS options are disabled.\n %s"); // We don't actually exit, just warn } else { splitRtsFlags(ghc_rts); - procRtsOpts(is_hs_main, rts_argc0, rtsOptsEnabled); + procRtsOpts(rts_argc0, rtsConfig.rts_opts_enabled); rts_argc0 = rts_argc; } } @@ -568,7 +586,7 @@ void setupRtsFlags (int *argc, char *argv[], } argv[*argc] = (char *) 0; - procRtsOpts(is_hs_main, rts_argc0, rtsOptsEnabled); + procRtsOpts(rts_argc0, rtsConfig.rts_opts_enabled); appendRtsArg((char *)0); rts_argc--; // appendRtsArg will have bumped it for the NULL (#7227) @@ -590,32 +608,34 @@ void setupRtsFlags (int *argc, char *argv[], * -------------------------------------------------------------------------- */ #if defined(HAVE_UNISTD_H) && defined(HAVE_SYS_TYPES_H) && !defined(mingw32_HOST_OS) -static void checkSuid(HsBool is_hs_main, RtsOptsEnabledEnum enabled) +static void checkSuid(RtsOptsEnabledEnum enabled) { if (enabled == RtsOptsSafeOnly) { /* This doesn't cover linux/posix capabilities like CAP_DAC_OVERRIDE, we'd have to link with -lcap for that. */ if ((getuid() != geteuid()) || (getgid() != getegid())) { - errorRtsOptsDisabled(is_hs_main, "RTS options are disabled for setuid binaries. %s"); + errorRtsOptsDisabled( + "RTS options are disabled for setuid binaries. %s"); stg_exit(EXIT_FAILURE); } } } #else -static void checkSuid(HsBool is_hs_main STG_UNUSED, RtsOptsEnabledEnum enabled STG_UNUSED) +static void checkSuid (RtsOptsEnabledEnum enabled STG_UNUSED) { } #endif -static void checkUnsafe(HsBool is_hs_main, RtsOptsEnabledEnum enabled) +static void checkUnsafe(RtsOptsEnabledEnum enabled) { if (enabled == RtsOptsSafeOnly) { - errorRtsOptsDisabled(is_hs_main, "Most RTS options are disabled. %s"); + errorRtsOptsDisabled("Most RTS options are disabled. %s"); stg_exit(EXIT_FAILURE); } } -static void procRtsOpts (HsBool is_hs_main, int rts_argc0, RtsOptsEnabledEnum rtsOptsEnabled) +static void procRtsOpts (int rts_argc0, + RtsOptsEnabledEnum rtsOptsEnabled) { rtsBool error = rtsFalse; int arg; @@ -623,11 +643,11 @@ static void procRtsOpts (HsBool is_hs_main, int rts_argc0, RtsOptsEnabledEnum rt if (!(rts_argc0 < rts_argc)) return; if (rtsOptsEnabled == RtsOptsNone) { - errorRtsOptsDisabled(is_hs_main, "RTS options are disabled. %s"); + errorRtsOptsDisabled("RTS options are disabled. %s"); stg_exit(EXIT_FAILURE); } - checkSuid(is_hs_main, rtsOptsEnabled); + checkSuid(rtsOptsEnabled); // Process RTS (rts_argv) part: mainly to determine statsfile for (arg = rts_argc0; arg < rts_argc; arg++) { @@ -639,7 +659,7 @@ static void procRtsOpts (HsBool is_hs_main, int rts_argc0, RtsOptsEnabledEnum rt rtsBool option_checked = rtsFalse; #define OPTION_SAFE option_checked = rtsTrue; -#define OPTION_UNSAFE checkUnsafe(is_hs_main, rtsOptsEnabled); option_checked = rtsTrue; +#define OPTION_UNSAFE checkUnsafe(rtsOptsEnabled); option_checked = rtsTrue; if (rts_argv[arg][0] != '-') { fflush(stdout); @@ -661,7 +681,8 @@ static void procRtsOpts (HsBool is_hs_main, int rts_argc0, RtsOptsEnabledEnum rt # define TICKY_BUILD_ONLY(x) x #else # define TICKY_BUILD_ONLY(x) \ -errorBelch("the flag %s requires the program to be built with -ticky", rts_argv[arg]); \ +errorBelch("the flag %s requires the program to be built with -ticky", \ + rts_argv[arg]); \ error = rtsTrue; #endif @@ -669,7 +690,8 @@ error = rtsTrue; # define PROFILING_BUILD_ONLY(x) x #else # define PROFILING_BUILD_ONLY(x) \ -errorBelch("the flag %s requires the program to be built with -prof", rts_argv[arg]); \ +errorBelch("the flag %s requires the program to be built with -prof", \ + rts_argv[arg]); \ error = rtsTrue; #endif @@ -677,7 +699,8 @@ error = rtsTrue; # define TRACING_BUILD_ONLY(x) x #else # define TRACING_BUILD_ONLY(x) \ -errorBelch("the flag %s requires the program to be built with -eventlog or -debug", rts_argv[arg]); \ +errorBelch("the flag %s requires the program to be built with -eventlog or -debug", \ + rts_argv[arg]); \ error = rtsTrue; #endif @@ -685,7 +708,8 @@ error = rtsTrue; # define THREADED_BUILD_ONLY(x) x #else # define THREADED_BUILD_ONLY(x) \ -errorBelch("the flag %s requires the program to be built with -threaded", rts_argv[arg]); \ +errorBelch("the flag %s requires the program to be built with -threaded", \ + rts_argv[arg]); \ error = rtsTrue; #endif @@ -693,7 +717,8 @@ error = rtsTrue; # define DEBUG_BUILD_ONLY(x) x #else # define DEBUG_BUILD_ONLY(x) \ -errorBelch("the flag %s requires the program to be built with -debug", rts_argv[arg]); \ +errorBelch("the flag %s requires the program to be built with -debug", \ + rts_argv[arg]); \ error = rtsTrue; #endif @@ -882,7 +907,8 @@ error = rtsTrue; case 'K': OPTION_UNSAFE; RtsFlags.GcFlags.maxStkSize = - decodeSize(rts_argv[arg], 2, sizeof(W_), HS_WORD_MAX) / sizeof(W_); + decodeSize(rts_argv[arg], 2, sizeof(W_), HS_WORD_MAX) + / sizeof(W_); break; case 'k': @@ -890,19 +916,23 @@ error = rtsTrue; switch(rts_argv[arg][2]) { case 'c': RtsFlags.GcFlags.stkChunkSize = - decodeSize(rts_argv[arg], 3, sizeof(W_), HS_WORD_MAX) / sizeof(W_); + decodeSize(rts_argv[arg], 3, sizeof(W_), HS_WORD_MAX) + / sizeof(W_); break; case 'b': RtsFlags.GcFlags.stkChunkBufferSize = - decodeSize(rts_argv[arg], 3, sizeof(W_), HS_WORD_MAX) / sizeof(W_); + decodeSize(rts_argv[arg], 3, sizeof(W_), HS_WORD_MAX) + / sizeof(W_); break; case 'i': RtsFlags.GcFlags.initialStkSize = - decodeSize(rts_argv[arg], 3, sizeof(W_), HS_WORD_MAX) / sizeof(W_); + decodeSize(rts_argv[arg], 3, sizeof(W_), HS_WORD_MAX) + / sizeof(W_); break; default: RtsFlags.GcFlags.initialStkSize = - decodeSize(rts_argv[arg], 2, sizeof(W_), HS_WORD_MAX) / sizeof(W_); + decodeSize(rts_argv[arg], 2, sizeof(W_), HS_WORD_MAX) + / sizeof(W_); break; } break; @@ -910,8 +940,10 @@ error = rtsTrue; case 'M': OPTION_UNSAFE; RtsFlags.GcFlags.maxHeapSize = - decodeSize(rts_argv[arg], 2, BLOCK_SIZE, HS_WORD_MAX) / BLOCK_SIZE; - /* user give size in *bytes* but "maxHeapSize" is in *blocks* */ + decodeSize(rts_argv[arg], 2, BLOCK_SIZE, HS_WORD_MAX) + / BLOCK_SIZE; + /* user give size in *bytes* but "maxHeapSize" is in + * *blocks* */ break; case 'm': @@ -1024,7 +1056,8 @@ error = rtsTrue; case 'R': OPTION_SAFE; PROFILING_BUILD_ONLY( - RtsFlags.ProfFlags.maxRetainerSetSize = atof(rts_argv[arg]+2); + RtsFlags.ProfFlags.maxRetainerSetSize = + atof(rts_argv[arg]+2); ) break; case 'L': OPTION_SAFE; @@ -1207,7 +1240,7 @@ error = rtsTrue; } if (rtsOptsEnabled == RtsOptsSafeOnly && nNodes > (int)getNumberOfProcessors()) { - errorRtsOptsDisabled(is_hs_main, "Using large values for -N is not allowed by default. %s"); + errorRtsOptsDisabled("Using large values for -N is not allowed by default. %s"); stg_exit(EXIT_FAILURE); } RtsFlags.ParFlags.nNodes = (nat)nNodes; @@ -1248,10 +1281,12 @@ error = rtsTrue; break; case 'b': if (rts_argv[arg][3] == '\0') { - RtsFlags.ParFlags.parGcLoadBalancingEnabled = rtsFalse; + RtsFlags.ParFlags.parGcLoadBalancingEnabled = + rtsFalse; } else { - RtsFlags.ParFlags.parGcLoadBalancingEnabled = rtsTrue; + RtsFlags.ParFlags.parGcLoadBalancingEnabled = + rtsTrue; RtsFlags.ParFlags.parGcLoadBalancingGen = strtol(rts_argv[arg]+3, (char **) NULL, 10); } @@ -1365,7 +1400,8 @@ error = rtsTrue; break; #endif - case 'c': /* Debugging tool: show current cost centre on an exception */ + case 'c': /* Debugging tool: show current cost centre on + an exception */ OPTION_SAFE; PROFILING_BUILD_ONLY( RtsFlags.ProfFlags.showCCSOnException = rtsTrue; @@ -1379,7 +1415,10 @@ error = rtsTrue; ); goto check_rest; - /* The option prefix '-xx' is reserved for future extension. KSW 1999-11. */ + /* + * The option prefix '-xx' is reserved for future + * extension. KSW 1999-11. + */ case 'q': OPTION_UNSAFE; @@ -1486,7 +1525,8 @@ static void normaliseRtsOpts (void) if (RtsFlags.GcFlags.stkChunkBufferSize > RtsFlags.GcFlags.stkChunkSize / 2) { - errorBelch("stack chunk buffer size (-kb) must be less than 50%% of the stack chunk size (-kc)"); + errorBelch("stack chunk buffer size (-kb) must be less than 50%%\n" + "of the stack chunk size (-kc)"); errorUsage(); } } @@ -1535,7 +1575,8 @@ openStatsFile (char *filename, // filename, or NULL if (*filename != '\0') { /* stats file specified */ f = fopen(filename,"w"); } else { - char stats_filename[STATS_FILENAME_MAXLEN]; /* default <program>.<ext> */ + /* default <program>.<ext> */ + char stats_filename[STATS_FILENAME_MAXLEN]; sprintf(stats_filename, filename_fmt, prog_name); f = fopen(stats_filename,"w"); } |