NonmovingCensus: Emit samples to eventlog wip/gc/instrumentation
authorBen Gamari <ben@smart-cactus.org>
Mon, 15 Apr 2019 20:42:56 +0000 (16:42 -0400)
committerBen Gamari <ben@smart-cactus.org>
Tue, 22 Oct 2019 16:17:00 +0000 (12:17 -0400)
includes/rts/EventLogFormat.h
includes/rts/Flags.h
libraries/base/GHC/RTS/Flags.hsc
rts/RtsFlags.c
rts/Trace.c
rts/Trace.h
rts/eventlog/EventLog.c
rts/eventlog/EventLog.h
rts/sm/NonMovingCensus.c
rts/sm/NonMovingCensus.h

index 46d001a..0ffa77a 100644 (file)
 #define EVENT_CONC_SWEEP_BEGIN             204
 #define EVENT_CONC_SWEEP_END               205
 #define EVENT_CONC_UPD_REM_SET_FLUSH       206
+#define EVENT_NONMOVING_HEAP_CENSUS        207
 
 /*
  * The highest event code +1 that ghc itself emits. Note that some event
  * ranges higher than this are reserved but not currently emitted by ghc.
  * This must match the size of the EventDesc[] array in EventLog.c
  */
-#define NUM_GHC_EVENT_TAGS        207
+#define NUM_GHC_EVENT_TAGS        208
 
 #if 0  /* DEPRECATED EVENTS: */
 /* we don't actually need to record the thread, it's implicit */
index 4499af9..9a039fd 100644 (file)
@@ -170,6 +170,7 @@ typedef struct _TRACE_FLAGS {
     bool timestamp;      /* show timestamp in stderr output */
     bool scheduler;      /* trace scheduler events */
     bool gc;             /* trace GC events */
+    bool nonmoving_gc;   /* trace nonmoving GC events */
     bool sparks_sampled; /* trace spark events by a sampled method */
     bool sparks_full;    /* trace spark events 100% accurately */
     bool user;           /* trace user events (emitted from Haskell code) */
index 4778eac..913344c 100644 (file)
@@ -292,6 +292,8 @@ data TraceFlags = TraceFlags
     , timestamp      :: Bool -- ^ show timestamp in stderr output
     , traceScheduler :: Bool -- ^ trace scheduler events
     , traceGc        :: Bool -- ^ trace GC events
+    , traceNonmovingGc
+                     :: Bool -- ^ trace nonmoving GC heap census samples
     , sparksSampled  :: Bool -- ^ trace spark events by a sampled method
     , sparksFull     :: Bool -- ^ trace spark events 100% accurately
     , user           :: Bool -- ^ trace user events (emitted from Haskell code)
@@ -526,6 +528,8 @@ getTraceFlags = do
              <*> (toBool <$>
                    (#{peek TRACE_FLAGS, gc} ptr :: IO CBool))
              <*> (toBool <$>
+                   (#{peek TRACE_FLAGS, nonmoving_gc} ptr :: IO CBool))
+             <*> (toBool <$>
                    (#{peek TRACE_FLAGS, sparks_sampled} ptr :: IO CBool))
              <*> (toBool <$>
                    (#{peek TRACE_FLAGS, sparks_full} ptr :: IO CBool))
index 7d48682..c606d86 100644 (file)
@@ -222,6 +222,7 @@ void initRtsFlagsDefaults(void)
     RtsFlags.TraceFlags.timestamp     = false;
     RtsFlags.TraceFlags.scheduler     = false;
     RtsFlags.TraceFlags.gc            = false;
+    RtsFlags.TraceFlags.nonmoving_gc  = false;
     RtsFlags.TraceFlags.sparks_sampled= false;
     RtsFlags.TraceFlags.sparks_full   = false;
     RtsFlags.TraceFlags.user          = false;
@@ -2131,6 +2132,10 @@ static void read_trace_flags(const char *arg)
             RtsFlags.TraceFlags.gc        = enabled;
             enabled = true;
             break;
+        case 'n':
+            RtsFlags.TraceFlags.nonmoving_gc = enabled;
+            enabled = true;
+            break;
         case 'u':
             RtsFlags.TraceFlags.user      = enabled;
             enabled = true;
index 10ad503..ecc28d8 100644 (file)
@@ -30,6 +30,7 @@
 // events
 int TRACE_sched;
 int TRACE_gc;
+int TRACE_nonmoving_gc;
 int TRACE_spark_sampled;
 int TRACE_spark_full;
 int TRACE_user;
@@ -72,6 +73,9 @@ void initTracing (void)
         RtsFlags.GcFlags.giveStats = COLLECT_GC_STATS;
     }
 
+    TRACE_nonmoving_gc =
+        RtsFlags.TraceFlags.nonmoving_gc;
+
     TRACE_spark_sampled =
         RtsFlags.TraceFlags.sparks_sampled;
 
@@ -844,6 +848,12 @@ void traceConcUpdRemSetFlush(Capability *cap)
         postConcUpdRemSetFlush(cap);
 }
 
+void traceNonmovingHeapCensus(uint32_t log_blk_size,
+                              const struct NonmovingAllocCensus *census)
+{
+    if (eventlog_enabled && TRACE_nonmoving_gc)
+        postNonmovingHeapCensus(log_blk_size, census);
+}
 
 void traceThreadStatus_ (StgTSO *tso USED_IF_DEBUG)
 {
index 9b52c3c..7f72fd8 100644 (file)
@@ -9,6 +9,7 @@
 #pragma once
 
 #include "rts/EventLogFormat.h"
+#include "sm/NonMovingCensus.h"
 #include "Capability.h"
 
 #if defined(DTRACE)
@@ -72,6 +73,7 @@ extern int TRACE_spark_sampled;
 extern int TRACE_spark_full;
 /* extern int TRACE_user; */  // only used in Trace.c
 extern int TRACE_cap;
+extern int TRACE_nonmoving_gc;
 
 // -----------------------------------------------------------------------------
 // Posting events
@@ -311,6 +313,8 @@ void traceConcSyncEnd(void);
 void traceConcSweepBegin(void);
 void traceConcSweepEnd(void);
 void traceConcUpdRemSetFlush(Capability *cap);
+void traceNonmovingHeapCensus(uint32_t log_blk_size,
+                              const struct NonmovingAllocCensus *census);
 
 void flushTrace(void);
 
@@ -359,6 +363,7 @@ void flushTrace(void);
 #define traceConcSweepBegin() /* nothing */
 #define traceConcSweepEnd() /* nothing */
 #define traceConcUpdRemSetFlush(cap) /* nothing */
+#define traceNonmovingHeapCensus(blk_size, census) /* nothing */
 
 #define flushTrace() /* nothing */
 
index a9bb603..8683ad9 100644 (file)
@@ -114,7 +114,8 @@ char *EventDesc[] = {
   [EVENT_CONC_SYNC_END]          = "End concurrent GC synchronisation",
   [EVENT_CONC_SWEEP_BEGIN]       = "Begin concurrent sweep",
   [EVENT_CONC_SWEEP_END]         = "End concurrent sweep",
-  [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed"
+  [EVENT_CONC_UPD_REM_SET_FLUSH] = "Update remembered set flushed",
+  [EVENT_NONMOVING_HEAP_CENSUS]  = "Nonmoving heap census"
 };
 
 // Event type.
@@ -470,6 +471,10 @@ init_event_types(void)
                 sizeof(EventCapNo);
             break;
 
+        case EVENT_NONMOVING_HEAP_CENSUS: // (cap, blk_size, active_segs, filled_segs, live_blks)
+            eventTypes[t].size = 13;
+            break;
+
         default:
             continue; /* ignore deprecated events */
         }
@@ -1182,6 +1187,18 @@ void postConcMarkEnd(StgWord32 marked_obj_count)
     RELEASE_LOCK(&eventBufMutex);
 }
 
+void postNonmovingHeapCensus(int log_blk_size,
+                             const struct NonmovingAllocCensus *census)
+{
+    ACQUIRE_LOCK(&eventBufMutex);
+    postEventHeader(&eventBuf, EVENT_NONMOVING_HEAP_CENSUS);
+    postWord8(&eventBuf, log_blk_size);
+    postWord32(&eventBuf, census->n_active_segs);
+    postWord32(&eventBuf, census->n_filled_segs);
+    postWord32(&eventBuf, census->n_live_blocks);
+    RELEASE_LOCK(&eventBufMutex);
+}
+
 void closeBlockMarker (EventsBuf *ebuf)
 {
     if (ebuf->marker)
index 16c7670..0d439b8 100644 (file)
@@ -11,6 +11,7 @@
 #include "rts/EventLogFormat.h"
 #include "rts/EventLogWriter.h"
 #include "Capability.h"
+#include "sm/NonMovingCensus.h"
 
 #include "BeginPrivate.h"
 
@@ -162,6 +163,8 @@ void postHeapProfSampleCostCentre(StgWord8 profile_id,
 
 void postConcUpdRemSetFlush(Capability *cap);
 void postConcMarkEnd(StgWord32 marked_obj_count);
+void postNonmovingHeapCensus(int log_blk_size,
+                             const struct NonmovingAllocCensus *census);
 
 #else /* !TRACING */
 
index 1f28f4e..670d512 100644 (file)
@@ -90,6 +90,9 @@ nonmovingAllocatorCensus(struct NonmovingAllocator *alloc)
 
 void nonmovingPrintAllocatorCensus()
 {
+    if (!RtsFlags.GcFlags.useNonmoving)
+        return;
+
     for (int i=0; i < NONMOVING_ALLOCA_CNT; i++) {
         struct NonmovingAllocCensus census =
             nonmovingAllocatorCensus(nonmovingHeap.allocators[i]);
@@ -109,3 +112,18 @@ void nonmovingPrintAllocatorCensus()
                    occupancy);
     }
 }
+
+void nonmovingTraceAllocatorCensus()
+{
+#if defined(TRACING)
+    if (!RtsFlags.GcFlags.useNonmoving && !TRACE_nonmoving_gc)
+        return;
+
+    for (int i=0; i < NONMOVING_ALLOCA_CNT; i++) {
+        const struct NonmovingAllocCensus census =
+            nonmovingAllocatorCensus(nonmovingHeap.allocators[i]);
+        const uint32_t log_blk_size = i + NONMOVING_ALLOCA0;
+        traceNonmovingHeapCensus(log_blk_size, &census);
+    }
+#endif
+}
index 1c7c657..7a66dc9 100644 (file)
@@ -8,6 +8,8 @@
 
 #pragma once
 
+#include "NonMoving.h"
+
 struct NonmovingAllocCensus {
     uint32_t n_active_segs;
     uint32_t n_filled_segs;
@@ -23,3 +25,4 @@ struct NonmovingAllocCensus
 nonmovingAllocatorCensus(struct NonmovingAllocator *alloc);
 
 void nonmovingPrintAllocatorCensus(void);
+void nonmovingTraceAllocatorCensus(void);