Add getNumberOfProcessors(), FIX MacOS X build problem (hopefully)
[ghc-hetmet.git] / rts / RtsFlags.c
index a2d699d..b3b95b3 100644 (file)
 #include <ctype.h>
 #endif
 
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 
@@ -147,6 +155,7 @@ void initRtsFlagsDefaults(void)
 #endif
     RtsFlags.GcFlags.compact            = rtsFalse;
     RtsFlags.GcFlags.compactThreshold   = 30.0;
+    RtsFlags.GcFlags.sweep              = rtsFalse;
 #ifdef RTS_GTK_FRONTPANEL
     RtsFlags.GcFlags.frontpanel         = rtsFalse;
 #endif
@@ -177,6 +186,7 @@ void initRtsFlagsDefaults(void)
     RtsFlags.DebugFlags.prof           = rtsFalse;
     RtsFlags.DebugFlags.gran           = rtsFalse;
     RtsFlags.DebugFlags.par            = rtsFalse;
+    RtsFlags.DebugFlags.apply          = rtsFalse;
     RtsFlags.DebugFlags.linker         = rtsFalse;
     RtsFlags.DebugFlags.squeeze                = rtsFalse;
     RtsFlags.DebugFlags.hpc            = rtsFalse;
@@ -203,15 +213,20 @@ void initRtsFlagsDefaults(void)
     RtsFlags.ProfFlags.bioSelector        = NULL;
 #endif
 
-    RtsFlags.MiscFlags.tickInterval    = 50;  /* In milliseconds */
-    RtsFlags.ConcFlags.ctxtSwitchTime  = 50;  /* In milliseconds */
+    RtsFlags.MiscFlags.tickInterval    = 20;  /* In milliseconds */
+    RtsFlags.ConcFlags.ctxtSwitchTime  = 20;  /* In milliseconds */
 
     RtsFlags.MiscFlags.install_signal_handlers = rtsTrue;
+    RtsFlags.MiscFlags.machineReadable = rtsFalse;
+    RtsFlags.MiscFlags.linkerMemBase    = 0;
 
 #ifdef THREADED_RTS
     RtsFlags.ParFlags.nNodes           = 1;
     RtsFlags.ParFlags.migrate           = rtsTrue;
     RtsFlags.ParFlags.wakeupMigrate     = rtsFalse;
+    RtsFlags.ParFlags.parGcEnabled      = 1;
+    RtsFlags.ParFlags.parGcGen          = 1;
+    RtsFlags.ParFlags.parGcLoadBalancing = 1;
 #endif
 
 #ifdef PAR
@@ -316,10 +331,12 @@ void initRtsFlagsDefaults(void)
 
     RtsFlags.TraceFlags.timestamp      = rtsFalse;
     RtsFlags.TraceFlags.sched          = rtsFalse;
+    RtsFlags.TraceFlags.gc             = rtsFalse;
 
 #ifdef USE_PAPI
     /* By default no special measurements taken */
     RtsFlags.PapiFlags.eventType        = 0;
+    RtsFlags.PapiFlags.numUserEvents    = 0;
 #endif
 }
 
@@ -336,6 +353,7 @@ usage_text[] = {
 "The following run time system options are available:",
 "",
 "  -?       Prints this message and exits; the program is not executed",
+"  --info   Print information about the RTS used by this program",
 "",
 "  -K<size> Sets the maximum stack size (default 8M)  Egs: -K32k   -K512k",
 "  -k<size> Sets the initial thread stack size (default 1k)  Egs: -k4k   -k2m",
@@ -349,13 +367,14 @@ usage_text[] = {
 "  -c<n>    Auto-enable compaction of the oldest generation when live data is",
 "           at least <n>% of the maximum heap size set with -M (default: 30%)",
 "  -c       Enable compaction for all major collections",
+"  -w       Use mark-region for the oldest generation (experimental)",
 #if defined(THREADED_RTS)
 "  -I<sec>  Perform full GC after <sec> idle time (default: 0.3, 0 == off)",
 #endif
 "",
-"  -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",
+"  -t[<file>] One-line GC statistics (if <file> omitted, uses stderr)",
+"  -s[<file>] Summary  GC statistics (if <file> omitted, uses stderr)",
+"  -S[<file>] Detailed GC statistics (if <file> omitted, uses stderr)",
 #ifdef RTS_GTK_FRONTPANEL
 "  -f       Display front panel (requires X11 & GTK+)",
 #endif
@@ -436,6 +455,7 @@ usage_text[] = {
 "  -Dp  DEBUG: prof",
 "  -Dr  DEBUG: gran",
 "  -DP  DEBUG: par",
+"  -Da  DEBUG: apply",
 "  -Dl  DEBUG: linker",
 "  -Dm  DEBUG: stm",
 "  -Dz  DEBUG: stack squezing",
@@ -443,7 +463,10 @@ usage_text[] = {
 "",
 #endif /* DEBUG */
 #if defined(THREADED_RTS) && !defined(NOSMP)
-"  -N<n>     Use <n> OS threads (default: 1)",
+"  -N<n>     Use <n> processors (default: 1)",
+"  -N        Determine the number of processors to use automatically",
+"  -q1       Use one OS thread for GC (turns off parallel GC)",
+"  -qg<n>    Use parallel GC only for generations >= <n> (default: 1)",
 "  -qm       Don't automatically migrate threads between CPUs",
 "  -qw       Migrate a thread to the current CPU when it is woken up",
 #endif
@@ -469,6 +492,10 @@ usage_text[] = {
 #if defined(GRAN)  /* ToDo: fill in decent Docu here */
 "  -b...     All GranSim options start with -b; see GranSim User's Guide for details",
 #endif
+#if defined(x86_64_HOST_ARCH)
+"  -xm       Base address to mmap memory in the GHCi linker",
+"            (hex; must be <80000000)",
+#endif
 #if defined(USE_PAPI)
 "  -aX       CPU performance counter measurements using PAPI",
 "            (use with the -s<file> option).  X is one of:",
@@ -682,6 +709,15 @@ error = rtsTrue;
                                &rts_argv[arg][2])) {
                       RtsFlags.MiscFlags.install_signal_handlers = rtsFalse;
                   }
+                  else if (strequal("machine-readable",
+                               &rts_argv[arg][2])) {
+                      RtsFlags.MiscFlags.machineReadable = rtsTrue;
+                  }
+                  else if (strequal("info",
+                               &rts_argv[arg][2])) {
+                      printRtsInfo();
+                      exit(0);
+                  }
                   else {
                      errorBelch("unknown RTS option: %s",rts_argv[arg]);
                      error = rtsTrue;
@@ -713,6 +749,14 @@ error = rtsTrue;
                case 'e':
                  RtsFlags.PapiFlags.eventType = PAPI_FLAG_CB_EVENTS;
                  break;
+                case '+':
+                  if (RtsFlags.PapiFlags.numUserEvents >= MAX_PAPI_USER_EVENTS) {
+                      errorBelch("maximum number of PAPI events reached");
+                      stg_exit(EXIT_FAILURE);
+                  }
+                  RtsFlags.PapiFlags.eventType = PAPI_USER_EVENTS;
+                  RtsFlags.PapiFlags.userEvents[RtsFlags.PapiFlags.numUserEvents++] = rts_argv[arg] + 3;
+                  break;
                default:
                  bad_option( rts_argv[arg] );
                }
@@ -732,6 +776,10 @@ error = rtsTrue;
                  }
                  break;
 
+              case 'w':
+               RtsFlags.GcFlags.sweep = rtsTrue;
+               break;
+
              case 'F':
                RtsFlags.GcFlags.oldGenFactor = atof(rts_argv[arg]+2);
              
@@ -853,10 +901,6 @@ error = rtsTrue;
              case 'H':
                RtsFlags.GcFlags.heapSizeSuggestion = 
                  decode(rts_argv[arg]+2) / BLOCK_SIZE;
-
-               if (RtsFlags.GcFlags.heapSizeSuggestion <= 0) {
-                 bad_option(rts_argv[arg]);
-               }
                break;
 
 #ifdef RTS_GTK_FRONTPANEL
@@ -898,7 +942,7 @@ error = rtsTrue;
                { 
                    int r;
                    r = open_stats_file(arg, *argc, argv,
-                                       *rts_argc, rts_argv, STAT_FILENAME_FMT,
+                                       *rts_argc, rts_argv, NULL,
                                        &RtsFlags.GcFlags.statsFile);
                    if (r == -1) { error = rtsTrue; }
                }
@@ -1104,22 +1148,63 @@ error = rtsTrue;
 #if defined(THREADED_RTS) && !defined(NOSMP)
              case 'N':
                THREADED_BUILD_ONLY(
-               if (rts_argv[arg][2] != '\0') {
+               if (rts_argv[arg][2] == '\0') {
+#if defined(PROFILING)
+                   RtsFlags.ParFlags.nNodes = 1;
+#else
+                    RtsFlags.ParFlags.nNodes = getNumberOfProcessors();
+#endif
+               } else {
                    RtsFlags.ParFlags.nNodes
                      = strtol(rts_argv[arg]+2, (char **) NULL, 10);
                    if (RtsFlags.ParFlags.nNodes <= 0) {
                      errorBelch("bad value for -N");
                      error = rtsTrue;
                    }
+#if defined(PROFILING)
+                    if (RtsFlags.ParFlags.nNodes > 1) {
+                        errorBelch("bad option %s: only -N1 is supported with profiling", rts_argv[arg]);
+                     error = rtsTrue;
+                    }
+#endif
                }
                ) break;
 
+             case 'g':
+               THREADED_BUILD_ONLY(
+                   switch (rts_argv[arg][2]) {
+                    case '1':
+                        // backwards compat only
+                        RtsFlags.ParFlags.parGcEnabled = rtsFalse;
+                        break;
+                   default:
+                       errorBelch("unknown RTS option: %s",rts_argv[arg]);
+                       error = rtsTrue;
+                       break;
+                    }
+                    ) break;
+
              case 'q':
                    switch (rts_argv[arg][2]) {
                    case '\0':
                        errorBelch("incomplete RTS option: %s",rts_argv[arg]);
                        error = rtsTrue;
                        break;
+                    case '1':
+                        RtsFlags.ParFlags.parGcEnabled = rtsFalse;
+                        break;
+                    case 'g':
+                        if (rts_argv[arg][3] != '\0') {
+                            RtsFlags.ParFlags.parGcGen
+                                = strtol(rts_argv[arg]+3, (char **) NULL, 10);
+                        } else {
+                            errorBelch("bad value for -qg");
+                            error = rtsTrue;
+                        }
+                        break;
+                   case 'b':
+                       RtsFlags.ParFlags.parGcLoadBalancing = rtsFalse;
+                       break;
                    case 'm':
                        RtsFlags.ParFlags.migrate = rtsFalse;
                        break;
@@ -1190,6 +1275,9 @@ error = rtsTrue;
                case 's':
                    RtsFlags.TraceFlags.sched = rtsTrue;
                    break;
+               case 'g':
+                   RtsFlags.TraceFlags.gc = rtsTrue;
+                   break;
                default:
                    errorBelch("unknown RTS option: %s",rts_argv[arg]);
                    error = rtsTrue;
@@ -1216,7 +1304,22 @@ error = rtsTrue;
                     }
                     break;
 
-                  case 'c': /* Debugging tool: show current cost centre on an exception */
+#if defined(x86_64_HOST_ARCH)
+                case 'm': /* linkerMemBase */
+                    if (rts_argv[arg][3] != '\0') {
+                        RtsFlags.MiscFlags.linkerMemBase
+                            = strtol(rts_argv[arg]+3, (char **) NULL, 16);
+                        if (RtsFlags.MiscFlags.linkerMemBase > 0x80000000) {
+                            errorBelch("-xm: value must be <80000000");
+                            error = rtsTrue;
+                        }
+                    } else {
+                        RtsFlags.MiscFlags.linkerMemBase = 0;
+                    }
+                    break;
+#endif
+
+                case 'c': /* Debugging tool: show current cost centre on an exception */
                     PROFILING_BUILD_ONLY(
                        RtsFlags.ProfFlags.showCCSOnException = rtsTrue;
                        );
@@ -2300,16 +2403,17 @@ open_stats_file (
 {
     FILE *f = NULL;
 
-    if (strequal(rts_argv[arg]+2, "stderr")) { /* use debugBelch */
+    if (strequal(rts_argv[arg]+2, "stderr")
+        || (FILENAME_FMT == NULL && rts_argv[arg][2] == '\0')) {
         f = NULL; /* NULL means use debugBelch */
     } else {
-       if (rts_argv[arg][2] != '\0') {  /* stats file specified */
-           f = fopen(rts_argv[arg]+2,"w");
-       } else {
-           char stats_filename[STATS_FILENAME_MAXLEN]; /* default <program>.<ext> */
-           sprintf(stats_filename, FILENAME_FMT, argv[0]);
-           f = fopen(stats_filename,"w");
-       }
+        if (rts_argv[arg][2] != '\0') {  /* stats file specified */
+            f = fopen(rts_argv[arg]+2,"w");
+        } else {
+            char stats_filename[STATS_FILENAME_MAXLEN]; /* default <program>.<ext> */
+            sprintf(stats_filename, FILENAME_FMT, argv[0]);
+            f = fopen(stats_filename,"w");
+        }
        if (f == NULL) {
            errorBelch("Can't open stats file %s\n", rts_argv[arg]+2);
            return -1;