From 6f1731812331d4ddb4326fdfcefa095b867547e9 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Mon, 15 Apr 2019 16:42:56 -0400 Subject: NonmovingCensus: Emit samples to eventlog --- includes/rts/EventLogFormat.h | 3 ++- includes/rts/Flags.h | 1 + libraries/base/GHC/RTS/Flags.hsc | 4 ++++ rts/RtsFlags.c | 5 +++++ rts/Trace.c | 10 ++++++++++ rts/Trace.h | 5 +++++ rts/eventlog/EventLog.c | 19 ++++++++++++++++++- rts/eventlog/EventLog.h | 3 +++ rts/sm/NonMovingCensus.c | 18 ++++++++++++++++++ rts/sm/NonMovingCensus.h | 3 +++ 10 files changed, 69 insertions(+), 2 deletions(-) diff --git a/includes/rts/EventLogFormat.h b/includes/rts/EventLogFormat.h index 46d001a0b2..0ffa77a2df 100644 --- a/includes/rts/EventLogFormat.h +++ b/includes/rts/EventLogFormat.h @@ -190,13 +190,14 @@ #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 */ diff --git a/includes/rts/Flags.h b/includes/rts/Flags.h index 4499af9da6..9a039fd95c 100644 --- a/includes/rts/Flags.h +++ b/includes/rts/Flags.h @@ -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) */ diff --git a/libraries/base/GHC/RTS/Flags.hsc b/libraries/base/GHC/RTS/Flags.hsc index 4778eac397..913344c166 100644 --- a/libraries/base/GHC/RTS/Flags.hsc +++ b/libraries/base/GHC/RTS/Flags.hsc @@ -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) @@ -525,6 +527,8 @@ getTraceFlags = do (#{peek TRACE_FLAGS, scheduler} ptr :: IO CBool)) <*> (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 <$> diff --git a/rts/RtsFlags.c b/rts/RtsFlags.c index 7d486824ab..c606d86418 100644 --- a/rts/RtsFlags.c +++ b/rts/RtsFlags.c @@ -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; diff --git a/rts/Trace.c b/rts/Trace.c index 10ad5031ab..ecc28d8fec 100644 --- a/rts/Trace.c +++ b/rts/Trace.c @@ -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) { diff --git a/rts/Trace.h b/rts/Trace.h index 9b52c3cb65..7f72fd8093 100644 --- a/rts/Trace.h +++ b/rts/Trace.h @@ -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 */ diff --git a/rts/eventlog/EventLog.c b/rts/eventlog/EventLog.c index a9bb603523..8683ad9972 100644 --- a/rts/eventlog/EventLog.c +++ b/rts/eventlog/EventLog.c @@ -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) diff --git a/rts/eventlog/EventLog.h b/rts/eventlog/EventLog.h index 16c7670cb3..0d439b836a 100644 --- a/rts/eventlog/EventLog.h +++ b/rts/eventlog/EventLog.h @@ -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 */ diff --git a/rts/sm/NonMovingCensus.c b/rts/sm/NonMovingCensus.c index 1f28f4e813..670d51263c 100644 --- a/rts/sm/NonMovingCensus.c +++ b/rts/sm/NonMovingCensus.c @@ -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 +} diff --git a/rts/sm/NonMovingCensus.h b/rts/sm/NonMovingCensus.h index 1c7c657cc1..7a66dc9b69 100644 --- a/rts/sm/NonMovingCensus.h +++ b/rts/sm/NonMovingCensus.h @@ -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); -- cgit v1.2.1