summaryrefslogtreecommitdiff
path: root/rts/RtsFlags.c
diff options
context:
space:
mode:
authorSimon Marlow <marlowsd@gmail.com>2014-06-09 09:18:12 +0100
committerSimon Marlow <marlowsd@gmail.com>2015-04-07 09:57:49 +0100
commita7ab161602aa0b5833d22c66e64eebb1d9275235 (patch)
tree22db09216cbd2165359d8add08b5cf4cdbf5041f /rts/RtsFlags.c
parent72092904e0ac1725c05c0447e1efe7ab541faa95 (diff)
downloadhaskell-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.c153
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");
}