Commit c294d95d authored by Mikolaj Konarski's avatar Mikolaj Konarski Committed by Duncan Coutts

Add the GC_GLOBAL_SYNC event marking that all caps are stopped for GC

Quoting design rationale by dcoutts: The event indicates that we're doing
a stop-the-world GC and all other HECs should be between their GC_START
and GC_END events at that moment. We don't want to use GC_STATS_GHC
for that, because GC_STATS_GHC is for extra GHC-specific info,
not something we have to rely on to be able to match the GC pauses
across HECs to a particular global GC.
parent 598109eb
...@@ -157,8 +157,9 @@ ...@@ -157,8 +157,9 @@
copied_bytes, slop_bytes, frag_bytes, copied_bytes, slop_bytes, frag_bytes,
par_n_threads, par_n_threads,
par_max_copied, par_tot_copied) */ par_max_copied, par_tot_copied) */
#define EVENT_GC_GLOBAL_SYNC 54 /* () */
/* Range 54 - 59 is available for new GHC and common events */ /* Range 55 - 59 is available for new GHC and common events */
/* Range 60 - 80 is used by eden for parallel tracing /* Range 60 - 80 is used by eden for parallel tracing
* see http://www.mathematik.uni-marburg.de/~eden/ * see http://www.mathematik.uni-marburg.de/~eden/
...@@ -171,7 +172,7 @@ ...@@ -171,7 +172,7 @@
* ranges higher than this are reserved but not currently emitted by ghc. * ranges higher than this are reserved but not currently emitted by ghc.
* This must match the size of the EventDesc[] array in EventLog.c * This must match the size of the EventDesc[] array in EventLog.c
*/ */
#define NUM_GHC_EVENT_TAGS 54 #define NUM_GHC_EVENT_TAGS 55
#if 0 /* DEPRECATED EVENTS: */ #if 0 /* DEPRECATED EVENTS: */
/* we don't actually need to record the thread, it's implicit */ /* we don't actually need to record the thread, it's implicit */
......
...@@ -55,6 +55,7 @@ provider HaskellEvent { ...@@ -55,6 +55,7 @@ provider HaskellEvent {
probe gc__idle (EventCapNo); probe gc__idle (EventCapNo);
probe gc__work (EventCapNo); probe gc__work (EventCapNo);
probe gc__done (EventCapNo); probe gc__done (EventCapNo);
probe gc__sync (EventCapNo);
probe gc__stats (CapsetID, StgWord, StgWord, StgWord, StgWord, StgWord, StgWord, StgWord); probe gc__stats (CapsetID, StgWord, StgWord, StgWord, StgWord, StgWord, StgWord, StgWord);
probe heap__info (CapsetID, StgWord, StgWord, StgWord, StgWord, StgWord); probe heap__info (CapsetID, StgWord, StgWord, StgWord, StgWord, StgWord);
probe heap__allocated (EventCapNo, CapsetID, StgWord64); probe heap__allocated (EventCapNo, CapsetID, StgWord64);
......
...@@ -349,6 +349,13 @@ stat_endGC (Capability *cap, gc_thread *gct, ...@@ -349,6 +349,13 @@ stat_endGC (Capability *cap, gc_thread *gct,
{ {
Time cpu, elapsed, gc_cpu, gc_elapsed; Time cpu, elapsed, gc_cpu, gc_elapsed;
// Has to be emitted while all caps stopped for GC, but before GC_END.
// See trac.haskell.org/ThreadScope/wiki/RTSsummaryEvents
// for a detailed design rationale of the current setup
// of GC eventlog events.
traceEventGcGlobalSync(cap);
// Emitted before GC_END on all caps, which simplifies tools code.
traceEventGcStats(cap, traceEventGcStats(cap,
CAPSET_HEAP_DEFAULT, CAPSET_HEAP_DEFAULT,
gen, gen,
...@@ -360,7 +367,7 @@ stat_endGC (Capability *cap, gc_thread *gct, ...@@ -360,7 +367,7 @@ stat_endGC (Capability *cap, gc_thread *gct,
par_n_threads, par_n_threads,
par_max_copied * sizeof(W_), par_max_copied * sizeof(W_),
par_tot_copied * sizeof(W_)); par_tot_copied * sizeof(W_));
getProcessTimes(&cpu, &elapsed); getProcessTimes(&cpu, &elapsed);
// Post EVENT_GC_END with the same timestamp as used for stats // Post EVENT_GC_END with the same timestamp as used for stats
......
...@@ -282,6 +282,9 @@ static void traceGcEvent_stderr (Capability *cap, EventTypeNum tag) ...@@ -282,6 +282,9 @@ static void traceGcEvent_stderr (Capability *cap, EventTypeNum tag)
case EVENT_GC_DONE: // (cap) case EVENT_GC_DONE: // (cap)
debugBelch("cap %d: GC done\n", cap->no); debugBelch("cap %d: GC done\n", cap->no);
break; break;
case EVENT_GC_GLOBAL_SYNC: // (cap)
debugBelch("cap %d: all caps stopped for GC\n", cap->no);
break;
default: default:
barf("traceGcEvent: unknown event tag %d", tag); barf("traceGcEvent: unknown event tag %d", tag);
break; break;
......
...@@ -350,6 +350,8 @@ INLINE_HEADER void dtraceStartup (int num_caps) { ...@@ -350,6 +350,8 @@ INLINE_HEADER void dtraceStartup (int num_caps) {
HASKELLEVENT_GC_WORK(cap) HASKELLEVENT_GC_WORK(cap)
#define dtraceGcDone(cap) \ #define dtraceGcDone(cap) \
HASKELLEVENT_GC_DONE(cap) HASKELLEVENT_GC_DONE(cap)
#define dtraceGcGlobalSync(cap) \
HASKELLEVENT_GC_GLOBAL_SYNC(cap)
#define dtraceEventGcStats(heap_capset, gens, \ #define dtraceEventGcStats(heap_capset, gens, \
copies, slop, fragmentation, \ copies, slop, fragmentation, \
par_n_threads, \ par_n_threads, \
...@@ -419,6 +421,7 @@ INLINE_HEADER void dtraceStartup (int num_caps STG_UNUSED) {}; ...@@ -419,6 +421,7 @@ INLINE_HEADER void dtraceStartup (int num_caps STG_UNUSED) {};
#define dtraceGcIdle(cap) /* nothing */ #define dtraceGcIdle(cap) /* nothing */
#define dtraceGcWork(cap) /* nothing */ #define dtraceGcWork(cap) /* nothing */
#define dtraceGcDone(cap) /* nothing */ #define dtraceGcDone(cap) /* nothing */
#define dtraceGcGlobalSync(cap) /* nothing */
#define dtraceEventGcStats(heap_capset, gens, \ #define dtraceEventGcStats(heap_capset, gens, \
copies, slop, fragmentation, \ copies, slop, fragmentation, \
par_n_threads, \ par_n_threads, \
...@@ -610,6 +613,12 @@ INLINE_HEADER void traceEventGcDone(Capability *cap STG_UNUSED) ...@@ -610,6 +613,12 @@ INLINE_HEADER void traceEventGcDone(Capability *cap STG_UNUSED)
dtraceGcDone((EventCapNo)cap->no); dtraceGcDone((EventCapNo)cap->no);
} }
INLINE_HEADER void traceEventGcGlobalSync(Capability *cap STG_UNUSED)
{
traceGcEvent(cap, EVENT_GC_GLOBAL_SYNC);
dtraceGcGlobalSync((EventCapNo)cap->no);
}
INLINE_HEADER void traceEventGcStats(Capability *cap STG_UNUSED, INLINE_HEADER void traceEventGcStats(Capability *cap STG_UNUSED,
CapsetID heap_capset STG_UNUSED, CapsetID heap_capset STG_UNUSED,
nat gen STG_UNUSED, nat gen STG_UNUSED,
......
...@@ -71,6 +71,7 @@ char *EventDesc[] = { ...@@ -71,6 +71,7 @@ char *EventDesc[] = {
[EVENT_GC_END] = "Finished GC", [EVENT_GC_END] = "Finished GC",
[EVENT_REQUEST_SEQ_GC] = "Request sequential GC", [EVENT_REQUEST_SEQ_GC] = "Request sequential GC",
[EVENT_REQUEST_PAR_GC] = "Request parallel GC", [EVENT_REQUEST_PAR_GC] = "Request parallel GC",
[EVENT_GC_GLOBAL_SYNC] = "Synchronise stop-the-world GC",
[EVENT_GC_STATS_GHC] = "GC statistics", [EVENT_GC_STATS_GHC] = "GC statistics",
[EVENT_HEAP_INFO_GHC] = "Heap static parameters", [EVENT_HEAP_INFO_GHC] = "Heap static parameters",
[EVENT_HEAP_ALLOCATED] = "Total heap mem ever allocated", [EVENT_HEAP_ALLOCATED] = "Total heap mem ever allocated",
...@@ -341,6 +342,7 @@ initEventLogging(void) ...@@ -341,6 +342,7 @@ initEventLogging(void)
case EVENT_GC_IDLE: case EVENT_GC_IDLE:
case EVENT_GC_WORK: case EVENT_GC_WORK:
case EVENT_GC_DONE: case EVENT_GC_DONE:
case EVENT_GC_GLOBAL_SYNC: // (cap)
case EVENT_SPARK_CREATE: // (cap) case EVENT_SPARK_CREATE: // (cap)
case EVENT_SPARK_DUD: // (cap) case EVENT_SPARK_DUD: // (cap)
case EVENT_SPARK_OVERFLOW: // (cap) case EVENT_SPARK_OVERFLOW: // (cap)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment