[commit: ghc] wip/libdw-prof: StatProf: Add RTS flags to enable particular samplers (99506c3)

git at git.haskell.org git at git.haskell.org
Sat May 6 22:26:48 UTC 2017


Repository : ssh://git@git.haskell.org/ghc

On branch  : wip/libdw-prof
Link       : http://ghc.haskell.org/trac/ghc/changeset/99506c3d575ecd1a5fd0183992bb1593e89a71e6/ghc

>---------------------------------------------------------------

commit 99506c3d575ecd1a5fd0183992bb1593e89a71e6
Author: Ben Gamari <ben at smart-cactus.org>
Date:   Sun Nov 15 12:51:35 2015 +0100

    StatProf: Add RTS flags to enable particular samplers


>---------------------------------------------------------------

99506c3d575ecd1a5fd0183992bb1593e89a71e6
 includes/rts/Flags.h | 24 +++++++++++++++---------
 rts/RtsFlags.c       | 50 ++++++++++++++++++++++++++++++++++++++++++++++++--
 rts/StatProfile.h    |  2 ++
 3 files changed, 65 insertions(+), 11 deletions(-)

diff --git a/includes/rts/Flags.h b/includes/rts/Flags.h
index 6700f9d..3ae0f94 100644
--- a/includes/rts/Flags.h
+++ b/includes/rts/Flags.h
@@ -155,6 +155,11 @@ typedef struct _PROFILING_FLAGS {
 
 } PROFILING_FLAGS;
 
+typedef struct _STAT_PROFILE_FLAGS {
+    bool                heapCheckSampling;
+    bool                blackholeSampling;
+} STAT_PROFILE_FLAGS;
+
 #define TRACE_NONE      0
 #define TRACE_EVENTLOG  1
 #define TRACE_STDERR    2
@@ -234,15 +239,16 @@ typedef struct _TICKY_FLAGS {
 /* See Note [Synchronization of flags and base APIs] */
 typedef struct _RTS_FLAGS {
     /* The first portion of RTS_FLAGS is invariant. */
-    GC_FLAGS	      GcFlags;
-    CONCURRENT_FLAGS  ConcFlags;
-    MISC_FLAGS        MiscFlags;
-    DEBUG_FLAGS	      DebugFlags;
-    COST_CENTRE_FLAGS CcFlags;
-    PROFILING_FLAGS   ProfFlags;
-    TRACE_FLAGS       TraceFlags;
-    TICKY_FLAGS	      TickyFlags;
-    PAR_FLAGS	      ParFlags;
+    GC_FLAGS	       GcFlags;
+    CONCURRENT_FLAGS   ConcFlags;
+    MISC_FLAGS         MiscFlags;
+    DEBUG_FLAGS	       DebugFlags;
+    COST_CENTRE_FLAGS  CcFlags;
+    PROFILING_FLAGS    ProfFlags;
+    STAT_PROFILE_FLAGS StatProfileFlags;
+    TRACE_FLAGS        TraceFlags;
+    TICKY_FLAGS	       TickyFlags;
+    PAR_FLAGS	       ParFlags;
 } RTS_FLAGS;
 
 #if defined(COMPILING_RTS_MAIN)
diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c
index b51d644..3693620 100644
--- a/rts/RtsFlags.c
+++ b/rts/RtsFlags.c
@@ -106,6 +106,7 @@ static bool read_heap_profiling_flag(const char *arg);
 #endif
 
 #if defined(TRACING)
+static bool read_stat_profiler_flag(const char *arg);
 static void read_trace_flags(const char *arg);
 #endif
 
@@ -203,6 +204,11 @@ void initRtsFlagsDefaults(void)
     RtsFlags.ProfFlags.bioSelector        = NULL;
 #endif
 
+#if defined(STAT_PROFILE)
+    RtsFlags.StatProfileFlags.blackholeSampling = false;
+    RtsFlags.StatProfileFlags.heapCheckSampling = false;
+#endif
+
 #if defined(TRACING)
     RtsFlags.TraceFlags.tracing       = TRACE_NONE;
     RtsFlags.TraceFlags.timestamp     = false;
@@ -306,6 +312,15 @@ usage_text[] = {
 "  -P         More detailed Time/Allocation profile in tree format",
 "  -Pa        Give information about *all* cost centres in tree format",
 "  -pj        Output cost-center profile in JSON format",
+#ifdef STAT_PROFILE
+"",
+"  -pS<sampler>"
+"             Enable recording of statistical profiler samples from",
+"             the given sample source. May be given multiple times.",
+"             The valid samplers are,",
+"               h = heap check (indicative of heap allocations)",
+"               b = black hole blocking (indicative of poor parallelism)",
+#endif
 "",
 "  -h<break-down> Heap residency profile (hp2ps) (output file <program>.hp)",
 "     break-down: c = cost centre stack (default)",
@@ -1058,8 +1073,21 @@ error = true;
               case 'P': /* detailed cost centre profiling (time/alloc) */
               case 'p': /* cost centre profiling (time/alloc) */
                 OPTION_SAFE;
-                PROFILING_BUILD_ONLY(
                 switch (rts_argv[arg][2]) {
+                  case 's':
+#ifdef TRACING
+                    error = read_stat_profiler_flag(rts_argv[arg]);
+#else
+                    errorBelch(
+                        "statistical profiling flag %s given but program was"
+                        " not built with tracing. Build with -eventlog to use"
+                        " statistical profiling.",
+                        rts_argv[arg]);
+                    error = true;
+#endif
+                    break;
+
+                  PROFILING_BUILD_ONLY(
                   case 'a':
                     RtsFlags.CcFlags.doCostCentres = COST_CENTRES_ALL;
                     if (rts_argv[arg][3] != '\0') {
@@ -1079,11 +1107,12 @@ error = true;
                           RtsFlags.CcFlags.doCostCentres = COST_CENTRES_SUMMARY;
                       }
                       break;
+                  )
                   default:
                     unchecked_arg_start++;
                     goto check_rest;
                 }
-                ) break;
+                break;
 
               case 'R':
                   OPTION_SAFE;
@@ -1819,6 +1848,23 @@ static bool read_heap_profiling_flag(const char *arg)
 #endif
 
 #if defined(TRACING)
+// Returns whether the parse resulted in an error.
+static bool read_stat_profiler_flag(const char *arg)
+{
+    switch (arg[2]) {
+    case 'h':
+        RtsFlags.StatProfileFlags.heapCheckSampling = true;
+        break;
+    case 'b':
+        RtsFlags.StatProfileFlags.blackholeSampling = true;
+        break;
+    default:
+        errorBelch("Unknown statistical profiler sampler flag %s", arg);
+        return true;
+    }
+    return false;
+}
+
 static void read_trace_flags(const char *arg)
 {
     const char *c;
diff --git a/rts/StatProfile.h b/rts/StatProfile.h
index f1f0476..c7fc4e5 100644
--- a/rts/StatProfile.h
+++ b/rts/StatProfile.h
@@ -20,6 +20,7 @@ INLINE_HEADER void
 statProfileDumpHeapSamples(Capability *cap)
 {
     // See Note [Statistical profiling of heap allocations]
+    if (!RtsFlags.StatProfileFlags.heapCheckSampling) return;
     if (cap->heap_sample_count) {
         traceStatProfileSamples(cap, rtsTrue, SAMPLE_BY_HEAP_ALLOC,
                                 SAMPLE_TYPE_INSTR_PTR,
@@ -33,6 +34,7 @@ INLINE_HEADER void
 statProfileDumpBlackholeSamples(Capability *cap)
 {
     // See Note [Statistical profiling of black-hole allocations]
+    if (!RtsFlags.StatProfileFlags.blackholeSampling) return;
     if (cap->blackhole_sample_count) {
         traceStatProfileSamples(cap, rtsTrue, SAMPLE_BY_BLACKHOLE,
                                 SAMPLE_TYPE_INSTR_PTR,



More information about the ghc-commits mailing list