Fixed uninitialised FunBind fun_tick field
[ghc-hetmet.git] / rts / RtsFlags.c
index 7e836af..ddc1928 100644 (file)
@@ -11,8 +11,6 @@
 #include "Rts.h"
 #include "RtsFlags.h"
 #include "RtsUtils.h"
-#include "BlockAlloc.h"
-#include "Timer.h"             /* CS_MIN_MILLISECS */
 #include "Profiling.h"
 
 #ifdef HAVE_CTYPE_H
@@ -150,7 +148,7 @@ void initRtsFlagsDefaults(void)
 #ifdef RTS_GTK_FRONTPANEL
     RtsFlags.GcFlags.frontpanel         = rtsFalse;
 #endif
-    RtsFlags.GcFlags.idleGCDelayTicks   = 300 / TICK_MILLISECS; /* ticks */
+    RtsFlags.GcFlags.idleGCDelayTime    = 300; /* millisecs */
 
 #ifdef DEBUG
     RtsFlags.DebugFlags.scheduler      = rtsFalse;
@@ -179,6 +177,7 @@ void initRtsFlagsDefaults(void)
     RtsFlags.ProfFlags.includeTSOs        = rtsFalse;
     RtsFlags.ProfFlags.showCCSOnException = rtsFalse;
     RtsFlags.ProfFlags.maxRetainerSetSize = 8;
+    RtsFlags.ProfFlags.ccsLength          = 25;
     RtsFlags.ProfFlags.modSelector        = NULL;
     RtsFlags.ProfFlags.descrSelector      = NULL;
     RtsFlags.ProfFlags.typeSelector       = NULL;
@@ -191,7 +190,8 @@ void initRtsFlagsDefaults(void)
     RtsFlags.ProfFlags.doHeapProfile      = rtsFalse;
 #endif
 
-    RtsFlags.ConcFlags.ctxtSwitchTime  = CS_MIN_MILLISECS;  /* In milliseconds */
+    RtsFlags.MiscFlags.tickInterval    = 50;  /* In milliseconds */
+    RtsFlags.ConcFlags.ctxtSwitchTime  = 50;  /* In milliseconds */
 
 #ifdef THREADED_RTS
     RtsFlags.ParFlags.nNodes           = 1;
@@ -301,6 +301,11 @@ void initRtsFlagsDefaults(void)
 
     RtsFlags.TraceFlags.timestamp      = rtsFalse;
     RtsFlags.TraceFlags.sched          = rtsFalse;
+
+#ifdef USE_PAPI
+    /* By default no special measurements taken */
+    RtsFlags.PapiFlags.eventType        = 0;
+#endif
 }
 
 static const char *
@@ -370,6 +375,9 @@ usage_text[] = {
 "    -hb<bio>...  closures with specified biographies (lag,drag,void,use)",
 "",
 "  -R<size>       Set the maximum retainer set size (default: 8)",
+"", 
+"  -L<chars>      Maximum length of a cost-centre stack in a heap profile",
+"                 (default: 25)",
 "",
 "  -i<sec>        Time between heap samples (seconds, default: 0.1)",
 "",
@@ -394,9 +402,12 @@ usage_text[] = {
 "  -N<n>     Use <n> PVMish processors in parallel (default: 2)",
 /* NB: the -N<n> is implemented by the driver!! */
 #endif
-"  -C<secs>  Context-switch interval in seconds",
-"                (0 or no argument means switch as often as possible)",
-"                the default is .02 sec; resolution is .02 sec",
+"  -C<secs>  Context-switch interval in seconds.",
+"            0 or no argument means switch as often as possible.",
+"            Default: 0.02 sec; resolution is set by -V below.",
+"  -V<secs>  Master tick interval in seconds.",
+"            This sets the resolution for -C and the profile timer -i.",
+"            Default: 0.02 sec.",
 "",
 "  -vs       Trace scheduler events (see also -Ds with -debug)",
 "  -vt       Time-stamp trace messages",
@@ -418,7 +429,7 @@ usage_text[] = {
 "  -Dz  DEBUG: stack squezing",
 "",
 #endif /* DEBUG */
-#if defined(THREADED_RTS)
+#if defined(THREADED_RTS) && !defined(NOSMP)
 "  -N<n>     Use <n> OS threads (default: 1)",
 "  -qm       Don't automatically migrate threads between CPUs",
 "  -qw       Migrate a thread to the current CPU when it is woken up",
@@ -443,6 +454,16 @@ 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(USE_PAPI)
+"  -aX       CPU performance counter measurements using PAPI",
+"            (use with the -s<file> option).  X is one of:",
+"",
+/* "            y - cycles", */
+"            1 - level 1 cache misses",
+"            2 - level 2 cache misses",
+"            b - branch mispredictions",
+"            s - stalled cycles",
+#endif
 "",
 "RTS options may also be specified using the GHCRTS environment variable.",
 "",
@@ -641,6 +662,27 @@ error = rtsTrue;
                }
                break;
 
+#ifdef USE_PAPI
+             case 'a':
+               switch(rts_argv[arg][2]) {
+               case '1':
+                 RtsFlags.PapiFlags.eventType = PAPI_FLAG_CACHE_L1;
+                 break;
+               case '2':
+                 RtsFlags.PapiFlags.eventType = PAPI_FLAG_CACHE_L2;
+                 break;
+               case 'b':
+                 RtsFlags.PapiFlags.eventType = PAPI_FLAG_BRANCH;
+                 break;
+               case 's':
+                 RtsFlags.PapiFlags.eventType = PAPI_FLAG_STALLS;
+                 break;
+               default:
+                 bad_option( rts_argv[arg] );
+               }
+               break;
+#endif
+
              case 'B':
                RtsFlags.GcFlags.ringBell = rtsTrue;
                break;
@@ -790,14 +832,9 @@ error = rtsTrue;
                } else {
                    I_ cst; /* tmp */
 
-                   /* Convert to ticks */
+                   /* Convert to millisecs */
                    cst = (I_) ((atof(rts_argv[arg]+2) * 1000));
-                   if (cst > 0 && cst < TICK_MILLISECS) {
-                       cst = TICK_MILLISECS;
-                   } else {
-                       cst = cst / TICK_MILLISECS;
-                   }
-                   RtsFlags.GcFlags.idleGCDelayTicks = cst;
+                   RtsFlags.GcFlags.idleGCDelayTime = cst;
                }
                break;
 
@@ -861,7 +898,13 @@ error = rtsTrue;
                  PROFILING_BUILD_ONLY(
                      RtsFlags.ProfFlags.maxRetainerSetSize = atof(rts_argv[arg]+2);
                  ) break;
-
+             case 'L':
+                 PROFILING_BUILD_ONLY(
+                     RtsFlags.ProfFlags.ccsLength = atof(rts_argv[arg]+2);
+                      if(RtsFlags.ProfFlags.ccsLength <= 0) {
+                       bad_option(rts_argv[arg]);
+                      }
+                 ) break;
              case 'h': /* serial heap profile */
 #if !defined(PROFILING) && defined(DEBUG)
                switch (rts_argv[arg][2]) {
@@ -993,10 +1036,6 @@ error = rtsTrue;
 
                    /* Convert to milliseconds */
                    cst = (I_) ((atof(rts_argv[arg]+2) * 1000));
-                   cst = (cst / CS_MIN_MILLISECS) * CS_MIN_MILLISECS;
-                   if (cst != 0 && cst < CS_MIN_MILLISECS)
-                       cst = CS_MIN_MILLISECS;
-
                    RtsFlags.ProfFlags.profileInterval = cst;
                }
                break;
@@ -1011,15 +1050,24 @@ error = rtsTrue;
 
                    /* Convert to milliseconds */
                    cst = (I_) ((atof(rts_argv[arg]+2) * 1000));
-                   cst = (cst / CS_MIN_MILLISECS) * CS_MIN_MILLISECS;
-                   if (cst != 0 && cst < CS_MIN_MILLISECS)
-                       cst = CS_MIN_MILLISECS;
-
                    RtsFlags.ConcFlags.ctxtSwitchTime = cst;
                }
                break;
 
-#ifdef THREADED_RTS
+              case 'V': /* master tick interval */
+                if (rts_argv[arg][2] == '\0') {
+                    // turns off ticks completely
+                    RtsFlags.MiscFlags.tickInterval = 0;
+                } else {
+                    I_ cst; /* tmp */
+
+                    /* Convert to milliseconds */
+                    cst = (I_) ((atof(rts_argv[arg]+2) * 1000));
+                    RtsFlags.MiscFlags.tickInterval = cst;
+                }
+                break;
+
+#if defined(THREADED_RTS) && !defined(NOSMP)
              case 'N':
                THREADED_BUILD_ONLY(
                if (rts_argv[arg][2] != '\0') {
@@ -1153,6 +1201,47 @@ error = rtsTrue;
            }
        }
     }
+
+    // Determine what tick interval we should use for the RTS timer
+    // by taking the shortest of the various intervals that we need to
+    // monitor.
+    if (RtsFlags.MiscFlags.tickInterval <= 0) {
+        RtsFlags.MiscFlags.tickInterval = 50;
+    }
+
+    if (RtsFlags.ConcFlags.ctxtSwitchTime > 0) {
+        RtsFlags.MiscFlags.tickInterval =
+            stg_min(RtsFlags.ConcFlags.ctxtSwitchTime,
+                    RtsFlags.MiscFlags.tickInterval);
+    }
+
+    if (RtsFlags.GcFlags.idleGCDelayTime > 0) {
+        RtsFlags.MiscFlags.tickInterval =
+            stg_min(RtsFlags.GcFlags.idleGCDelayTime,
+                    RtsFlags.MiscFlags.tickInterval);
+    }
+
+#ifdef PROFILING
+    if (RtsFlags.ProfFlags.profileInterval > 0) {
+        RtsFlags.MiscFlags.tickInterval =
+            stg_min(RtsFlags.ProfFlags.profileInterval,
+                    RtsFlags.MiscFlags.tickInterval);
+    }
+#endif
+
+    if (RtsFlags.ConcFlags.ctxtSwitchTime > 0) {
+        RtsFlags.ConcFlags.ctxtSwitchTicks =
+            RtsFlags.ConcFlags.ctxtSwitchTime /
+            RtsFlags.MiscFlags.tickInterval;
+    } else {
+        RtsFlags.ConcFlags.ctxtSwitchTicks = 0;
+    }
+
+#ifdef PROFILING
+    RtsFlags.ProfFlags.profileIntervalTicks =
+        RtsFlags.ProfFlags.profileInterval / RtsFlags.MiscFlags.tickInterval;
+#endif
+
     if (error) {
        const char **p;