/* -----------------------------------------------------------------------------
- * $Id: RtsFlags.c,v 1.29 2000/04/03 15:54:50 simonmar Exp $
+ * $Id: RtsFlags.c,v 1.38 2001/03/22 03:51:10 hwloidl Exp $
*
* (c) The AQUA Project, Glasgow University, 1994-1997
* (c) The GHC Team, 1998-1999
#include "RtsFlags.h"
#include "RtsUtils.h"
#include "BlockAlloc.h"
+#include "Itimer.h" /* CS_MIN_MILLISECS */
#include "Profiling.h"
#if defined(PROFILING)
#include "Itimer.h"
#endif
-#if HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#ifdef HAVE_STRING_H
-#include <string.h>
+#ifdef HAVE_CTYPE_H
+#include <ctype.h>
#endif
extern struct RTS_FLAGS RtsFlags;
"DEBUG (-D256): stable\n",
"DEBUG (-D512): prof\n",
"DEBUG (-D1024): gran\n",
- "DEBUG (-D2048): par\n"
+ "DEBUG (-D2048): par\n",
+ "DEBUG (-D4096): linker\n"
};
char *debug_opts_prefix[] = {
"_!", /* prof */
"_=", /* gran */
"_=" /* par */
+ "_*" /* linker */
};
#if defined(GRAN)
char *par_debug_opts_strs[] = {
"DEBUG (-qDv, -qD1): verbose; be generally verbose with parallel related stuff.\n",
- "DEBUG (-qDt, -qD2): trace; trace messages.\n",
+ "DEBUG (-qDq, -qD2): bq; print blocking queues.\n",
"DEBUG (-qDs, -qD4): schedule; scheduling of parallel threads.\n",
"DEBUG (-qDe, -qD8): free; free messages.\n",
"DEBUG (-qDr, -qD16): resume; resume messages.\n",
//"DEBUG (-qDo, -qD512): forward; forwarding messages to other PEs.\n",
"DEBUG (-qDl, -qD256): tables; print internal LAGA etc tables.\n",
"DEBUG (-qDo, -qD512): packet; packets and graph structures when packing.\n",
- "DEBUG (-qDp, -qD1024): pack; packing and unpacking graphs.\n"
+ "DEBUG (-qDp, -qD1024): pack; packing and unpacking graphs.\n",
+ "DEBUG (-qDz, -qD2048): paranoia; ridiculously detailed output (excellent for filling a partition).\n"
};
/* one character codes for the available debug options */
char par_debug_opts_flags[] = {
- 'v', 't', 's', 'e', 'r', 'w', 'F', 'f', 'l', 'o', 'p'
+ 'v', 'q', 's', 'e', 'r', 'w', 'F', 'f', 'l', 'o', 'p', 'z'
};
/* prefix strings printed with the debug messages of the corresponding type */
char *par_debug_opts_prefix[] = {
" ", /* verbose */
- "..", /* trace */
+ "##", /* bq */
"--", /* schedule */
"!!", /* free */
"[]", /* resume */
"", /* tables */
"**", /* packet */
"**" /* pack */
+ ":(" /* paranoia */
};
#endif /* PAR */
RtsFlags.GcFlags.heapSizeSuggestion = 0; /* none */
RtsFlags.GcFlags.pcFreeHeap = 3; /* 3% */
RtsFlags.GcFlags.oldGenFactor = 2;
+#if defined(PAR)
+ /* A hack currently needed for GUM -- HWL */
+ RtsFlags.GcFlags.generations = 1;
+ RtsFlags.GcFlags.steps = 2;
+ RtsFlags.GcFlags.squeezeUpdFrames = rtsFalse;
+#else
RtsFlags.GcFlags.generations = 2;
RtsFlags.GcFlags.steps = 2;
-
RtsFlags.GcFlags.squeezeUpdFrames = rtsTrue;
+#endif
+#ifdef RTS_GTK_FRONTPANEL
+ RtsFlags.GcFlags.frontpanel = rtsFalse;
+#endif
#if defined(PROFILING) || defined(PAR)
RtsFlags.CcFlags.doCostCentres = 0;
#endif /* PROFILING or PAR */
#ifdef PROFILING
- RtsFlags.ProfFlags.doHeapProfile = rtsFalse;
+ RtsFlags.ProfFlags.doHeapProfile = rtsFalse;
RtsFlags.ProfFlags.showCCSOnException = rtsFalse;
-
- RtsFlags.ProfFlags.ccSelector = NULL;
- RtsFlags.ProfFlags.modSelector = NULL;
- RtsFlags.ProfFlags.descrSelector = NULL;
- RtsFlags.ProfFlags.typeSelector = NULL;
- RtsFlags.ProfFlags.kindSelector = NULL;
+ RtsFlags.ProfFlags.modSelector = NULL;
+ RtsFlags.ProfFlags.descrSelector = NULL;
+ RtsFlags.ProfFlags.typeSelector = NULL;
+ RtsFlags.ProfFlags.ccSelector = NULL;
#elif defined(DEBUG)
- RtsFlags.ProfFlags.doHeapProfile = rtsFalse;
+ RtsFlags.ProfFlags.doHeapProfile = rtsFalse;
#endif
RtsFlags.ConcFlags.ctxtSwitchTime = CS_MIN_MILLISECS; /* In milliseconds */
#ifdef PAR
RtsFlags.ParFlags.ParStats.Full = rtsFalse;
+ RtsFlags.ParFlags.ParStats.Suppressed = rtsFalse;
RtsFlags.ParFlags.ParStats.Binary = rtsFalse;
RtsFlags.ParFlags.ParStats.Sparks = rtsFalse;
RtsFlags.ParFlags.ParStats.Heap = rtsFalse;
RtsFlags.ParFlags.ParStats.Global = rtsFalse;
RtsFlags.ParFlags.outputDisabled = rtsFalse;
+#ifdef DIST
+ RtsFlags.ParFlags.doFairScheduling = rtsTrue; /* fair sched by def */
+#else
+ RtsFlags.ParFlags.doFairScheduling = rtsFalse; /* unfair sched by def */
+#endif
RtsFlags.ParFlags.packBufferSize = 1024;
-
+ RtsFlags.ParFlags.thunksToPack = 1; /* 0 ... infinity; */
+ RtsFlags.ParFlags.globalising = 1; /* 0 ... everything */
RtsFlags.ParFlags.maxThreads = 1024;
RtsFlags.ParFlags.maxFishes = MAX_FISHES;
RtsFlags.ParFlags.fishDelay = FISH_DELAY;
#if defined(GRAN)
/* ToDo: check defaults for GranSim and GUM */
- RtsFlags.ConcFlags.ctxtSwitchTime = CS_MIN_MILLISECS; /* In milliseconds */
RtsFlags.GcFlags.maxStkSize = (1024 * 1024) / sizeof(W_);
RtsFlags.GcFlags.initialStkSize = 1024 / sizeof(W_);
"",
"The following run time system options are available:",
"",
-" -? -f Prints this message and exits; the program is not executed",
+" -? Prints this message and exits; the program is not executed",
"",
" -K<size> Sets the maximum stack size (default 1M) Egs: -K32k -K512k",
" -k<size> Sets the initial thread stack size (default 1k) Egs: -K4k -K2m",
" -m<n>% Minimum % of heap which must be available (default 3%)",
" -G<n> Number of generations (default: 2)",
" -T<n> Number of steps in younger generations (default: 2)",
-" -s<file> Summary GC statistics (default file: <program>.stat)",
-" -S<file> Detailed GC statistics (with -Sstderr going to stderr)",
+"",
+" -t<file> One-line GC statistics (default file: <program>.stat)",
+" -s<file> Summary GC statistics (with -Sstderr going to stderr)",
+" -S<file> Detailed GC statistics",
+#ifdef RTS_GTK_FRONTPANEL
+" -f Display front panel (requires X11 & GTK+)",
+#endif
"",
"",
" -Z Don't squeeze out update frames on stack overflow",
" -px Time/allocation profile (XML) (output file <program>.prof)",
" -p<sort> Time/allocation profile (output file <program>.prof)",
" sort: T = time (default), A = alloc, C = cost centre label",
-" -P<sort> More detailed Time/Allocation profile"
+" -P<sort> More detailed Time/Allocation profile",
+
# if defined(PROFILING)
"",
" -hx Heap residency profile (XML) (output file <program>.prof)",
" -h<break-down> Heap residency profile (text) (output file <program>.prof)",
" break-down: C = cost centre stack (default), M = module",
" D = closure description, Y = type description",
+" A subset of closures may be selected thusly:",
+" -hc{cc, cc ...} specific cost centre(s) (NOT STACKS!)",
+" -hm{mod,mod...} all cost centres from the specified modules(s)",
+" -hd{des,des...} closures with specified closure descriptions",
+" -hy{typ,typ...} closures with specified type descriptions",
"",
" -xc Show current cost centre stack on raising an exception",
# endif
#endif
" -C<secs> Context-switch interval in seconds",
" (0 or no argument means switch as often as possible)",
-" the default is .01 sec; resolution is .01 sec",
+" the default is .02 sec; resolution is .02 sec",
#if defined(SMP)
" -N<n> Use <n> OS threads (default: 1)",
#endif
# define SMP_BUILD_ONLY(x) x
#else
# define SMP_BUILD_ONLY(x) \
-prog_belch("GHC not built for: -parallel"); \
+prog_belch("GHC not built for: -smp"); \
error = rtsTrue;
#endif
/* =========== GENERAL ========================== */
case '?':
- case 'f':
error = rtsTrue;
break;
}
break;
+#ifdef RTS_GTK_FRONTPANEL
+ case 'f':
+ RtsFlags.GcFlags.frontpanel = rtsTrue;
+ break;
+#endif
+
case 'S':
- RtsFlags.GcFlags.giveStats ++;
+ RtsFlags.GcFlags.giveStats = VERBOSE_GC_STATS;
+ goto stats;
case 's':
- RtsFlags.GcFlags.giveStats ++;
+ RtsFlags.GcFlags.giveStats = SUMMARY_GC_STATS;
+ goto stats;
+
+ case 't':
+ RtsFlags.GcFlags.giveStats = ONELINE_GC_STATS;
+ goto stats;
+
+ stats:
#ifdef PAR
/* Opening all those files would almost certainly fail... */
- RtsFlags.ParFlags.ParStats.Full = rtsTrue;
+ // RtsFlags.ParFlags.ParStats.Full = rtsTrue;
RtsFlags.GcFlags.statsFile = stderr; /* temporary; ToDo: rm */
#else
- RtsFlags.GcFlags.statsFile
- = open_stats_file(arg, *argc, argv,
- *rts_argc, rts_argv, STAT_FILENAME_FMT);
-
- if (RtsFlags.GcFlags.statsFile == NULL) error = rtsTrue;
+ RtsFlags.GcFlags.statsFile
+ = open_stats_file(arg, *argc, argv,
+ *rts_argc, rts_argv, STAT_FILENAME_FMT);
+
+ if (RtsFlags.GcFlags.statsFile == NULL) error = rtsTrue;
#endif
- break;
+ break;
case 'Z':
RtsFlags.GcFlags.squeezeUpdFrames = rtsFalse;
case TYPEchar:
RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_TYPE;
break;
+ case 'c': /* cost centre label select */
+ case 'm': /* cost centre module select */
+ case 'd': /* closure descr select */
+ case 'y': /* closure type select */
+ {char *left = strchr(rts_argv[arg], '{');
+ char *right = strrchr(rts_argv[arg], '}');
+ if (! left || ! right ||
+ strrchr(rts_argv[arg], '{') != left ||
+ strchr(rts_argv[arg], '}') != right) {
+ prog_belch(
+ "Invalid heap profiling selection bracketing\n %s\n",
+ rts_argv[arg]);
+ error = rtsTrue;
+ } else {
+ *right = '\0';
+ switch (rts_argv[arg][2]) {
+ case 'c': /* cost centre label select */
+ RtsFlags.ProfFlags.ccSelector = left + 1;
+ break;
+ case 'm': /* cost centre module select */
+ RtsFlags.ProfFlags.modSelector = left + 1;
+ break;
+ case 'd': /* closure descr select */
+ RtsFlags.ProfFlags.descrSelector = left + 1;
+ break;
+ case 'y': /* closure type select */
+ RtsFlags.ProfFlags.typeSelector = left + 1;
+ break;
+ }
+ }
+ }
+ break;
default:
prog_belch("invalid heap profile option: %s",rts_argv[arg]);
error = rtsTrue;
}
)
+
#endif
break;
/* Convert to milliseconds */
cst = (I_) ((atof(rts_argv[arg]+2) * 1000));
cst = (cst / CS_MIN_MILLISECS) * CS_MIN_MILLISECS;
- if (cst < CS_MIN_MILLISECS)
+ if (cst != 0 && cst < CS_MIN_MILLISECS)
cst = CS_MIN_MILLISECS;
RtsFlags.ConcFlags.ctxtSwitchTime = cst;
case 'q':
PAR_BUILD_ONLY(
- process_par_option(arg, rts_argc, rts_argv, &error);
+ process_par_option(arg, rts_argc, rts_argv, &error);
) break;
/* =========== GRAN =============================== */
case 'b':
GRAN_BUILD_ONLY(
- process_gran_option(arg, rts_argc, rts_argv, &error);
+ process_gran_option(arg, rts_argc, rts_argv, &error);
) break;
/* =========== TICKY ============================== */
static void
process_par_option(int arg, int *rts_argc, char *rts_argv[], rtsBool *error)
{
- if (rts_argv[arg][1] != 'q') /* All GUM options start with -q */
+
+ if (rts_argv[arg][1] != 'q') { /* All GUM options start with -q */
+ belch("Warning: GUM option does not start with -q: %s", rts_argv[arg]);
return;
-
+ }
+
/* Communication and task creation cost parameters */
switch(rts_argv[arg][2]) {
case 'e': /* -qe<n> ... allow <n> local sparks */
RtsFlags.ParFlags.maxFishes));
break;
-
- case 'd':
+ case 'F':
if (rts_argv[arg][3] != '\0') {
RtsFlags.ParFlags.fishDelay
= strtol(rts_argv[arg]+3, (char **) NULL, 10);
} else {
- belch("setupRtsFlags: missing fish delay time for -qd\n");
+ belch("setupRtsFlags: missing fish delay time for -qF\n");
*error = rtsTrue;
}
IF_PAR_DEBUG(verbose,
- belch("-qd<n>: fish delay time %d",
+ belch("-qF<n>: fish delay time %d us",
RtsFlags.ParFlags.fishDelay));
break;
belch("-qO: output disabled"));
break;
+ case 'g': /* -qg<n> ... globalisation scheme */
+ if (rts_argv[arg][3] != '\0') {
+ RtsFlags.ParFlags.globalising = decode(rts_argv[arg]+3);
+ } else {
+ belch("setupRtsFlags: missing identifier for globalisation scheme (for -qg)\n");
+ *error = rtsTrue;
+ }
+ IF_PAR_DEBUG(verbose,
+ belch("-qg<n>: globalisation scheme set to %d",
+ RtsFlags.ParFlags.globalising));
+ break;
+
+ case 'h': /* -qh<n> ... max number of thunks (except root) in packet */
+ if (rts_argv[arg][3] != '\0') {
+ RtsFlags.ParFlags.thunksToPack = decode(rts_argv[arg]+3);
+ } else {
+ belch("setupRtsFlags: missing number of thunks per packet (for -qh)\n");
+ *error = rtsTrue;
+ }
+ IF_PAR_DEBUG(verbose,
+ belch("-qh<n>: thunks per packet set to %d",
+ RtsFlags.ParFlags.thunksToPack));
+ break;
+
case 'P': /* -qP for writing a log file */
- RtsFlags.ParFlags.ParStats.Full = rtsTrue;
+ //RtsFlags.ParFlags.ParStats.Full = rtsFalse;
/* same encoding as in GranSim after -bP */
switch(rts_argv[arg][3]) {
- case '\0': break; // nothing special, just an ordinary profile
- //case '0': RtsFlags.ParFlags.ParStats.Suppressed = rtsTrue;
- // break;
+ case '\0': RtsFlags.ParFlags.ParStats.Full = rtsTrue;
+ break; // nothing special, just an ordinary profile
+ case '0': RtsFlags.ParFlags.ParStats.Suppressed = rtsTrue;
+ RtsFlags.ParFlags.ParStats.Full = rtsFalse;
+ break;
case 'b': RtsFlags.ParFlags.ParStats.Binary = rtsTrue;
break;
case 's': RtsFlags.ParFlags.ParStats.Sparks = rtsTrue;
// break;
case 'n': RtsFlags.ParFlags.ParStats.NewLogfile = rtsTrue;
break;
- case 'g': RtsFlags.ParFlags.ParStats.Global = rtsTrue;
+ case 'g':
+# if defined(PAR_TICKY)
+ RtsFlags.ParFlags.ParStats.Global = rtsTrue;
+# else
+ fprintf(stderr,"-qPg is only possible for a PAR_TICKY RTS, which this is not");
+ stg_exit(EXIT_FAILURE);
+# endif
break;
default: barf("Unknown option -qP%c", rts_argv[arg][2]);
}
if (rts_argv[arg][3] != '\0') {
RtsFlags.ParFlags.packBufferSize = decode(rts_argv[arg]+3);
} else {
- belch("setupRtsFlags: missing size of PackBuffer (for -Q)\n");
- error = rtsTrue;
+ belch("setupRtsFlags: missing size of PackBuffer (for -qQ)\n");
+ *error = rtsTrue;
}
IF_PAR_DEBUG(verbose,
belch("-qQ<n>: pack buffer size set to %d",
RtsFlags.ParFlags.packBufferSize));
break;
+ case 'R':
+ RtsFlags.ParFlags.doFairScheduling = rtsTrue;
+ IF_PAR_DEBUG(verbose,
+ belch("-qR: fair-ish scheduling"));
+ break;
+
# if defined(DEBUG)
case 'w':
if (rts_argv[arg][3] != '\0') {
break;
# endif
default:
- belch("Unknown option -q%c", rts_argv[arg][2]);
+ belch("Unknown option -q%c (%d opts in total)",
+ rts_argv[arg][2], *rts_argc);
break;
} /* switch */
}
fprintf(stderr, par_debug_opts_strs[i]);
switch (i) {
case 0: RtsFlags.ParFlags.Debug.verbose = rtsTrue; break;
- case 1: RtsFlags.ParFlags.Debug.trace = rtsTrue; break;
+ case 1: RtsFlags.ParFlags.Debug.bq = rtsTrue; break;
case 2: RtsFlags.ParFlags.Debug.schedule = rtsTrue; break;
case 3: RtsFlags.ParFlags.Debug.free = rtsTrue; break;
case 4: RtsFlags.ParFlags.Debug.resume = rtsTrue; break;
case 7: RtsFlags.ParFlags.Debug.fish = rtsTrue; break;
case 8: RtsFlags.ParFlags.Debug.tables = rtsTrue; break;
case 9: RtsFlags.ParFlags.Debug.packet = rtsTrue; break;
- case 10: RtsFlags.ParFlags.Debug.pack = rtsTrue; break;
- default: barf("set_par_debug_options: only %d debug options expected");
+ case 10: RtsFlags.ParFlags.Debug.pack = rtsTrue; break;
+ case 11: RtsFlags.ParFlags.Debug.paranoia = rtsTrue; break;
+ default: barf("set_par_debug_options: only %d debug options expected",
+ MAX_PAR_DEBUG_OPTION);
} /* switch */
} /* if */
}
case 9: RtsFlags.DebugFlags.prof = rtsTrue; break;
case 10: RtsFlags.DebugFlags.gran = rtsTrue; break;
case 11: RtsFlags.DebugFlags.par = rtsTrue; break;
+ default: barf("set_debug_options: only %d debug options expected",
+ MAX_DEBUG_OPTION);
} /* switch */
} /* if */
}