in rts/Stats.c [869:1026]
static void report_machine_readable (const RTSSummaryStats * sum)
{
// We should do no calculation, other than unit changes and formatting, and
// we should not not use any data from outside of globals, sum and stats
// here. See Note [RTS Stats Reporting]
uint32_t g;
#define MR_STAT(field_name,format,value) \
statsPrintf(" ,(\"" field_name "\", \"%" format "\")\n", value)
#define MR_STAT_GEN(gen,field_name,format,value) \
statsPrintf(" ,(\"gen_%" FMT_Word32 "_" field_name "\", \"%" \
format "\")\n", g, value)
// These first values are for backwards compatibility.
// Some of these first fields are duplicated with more machine-readable
// names, or to match the name in RtsStats.
// we don't use for the first field helper macro here because the prefix is
// different
statsPrintf(" [(\"%s\", \"%" FMT_Word64 "\")\n", "bytes allocated",
stats.allocated_bytes);
MR_STAT("num_GCs", FMT_Word32, stats.gcs);
MR_STAT("average_bytes_used", FMT_Word64, sum->average_bytes_used);
MR_STAT("max_bytes_used", FMT_Word64, stats.max_live_bytes);
MR_STAT("num_byte_usage_samples", FMT_Word32, stats.major_gcs);
MR_STAT("peak_megabytes_allocated", FMT_Word64,
stats.max_mem_in_use_bytes / (1024 * 1024));
MR_STAT("init_cpu_seconds", "f", TimeToSecondsDbl(stats.init_cpu_ns));
MR_STAT("init_wall_seconds", "f", TimeToSecondsDbl(stats.init_elapsed_ns));
MR_STAT("mut_cpu_seconds", "f", TimeToSecondsDbl(stats.mutator_cpu_ns));
MR_STAT("mut_wall_seconds", "f",
TimeToSecondsDbl(stats.mutator_elapsed_ns));
MR_STAT("GC_cpu_seconds", "f", TimeToSecondsDbl(stats.gc_cpu_ns));
MR_STAT("GC_wall_seconds", "f", TimeToSecondsDbl(stats.gc_elapsed_ns));
// end backward compatibility
// First, the rest of the times
MR_STAT("exit_cpu_seconds", "f", TimeToSecondsDbl(sum->exit_cpu_ns));
MR_STAT("exit_wall_seconds", "f", TimeToSecondsDbl(sum->exit_elapsed_ns));
#if defined(PROFILING)
MR_STAT("rp_cpu_seconds", "f", TimeToSecondsDbl(sum->rp_cpu_ns));
MR_STAT("rp_wall_seconds", "f", TimeToSecondsDbl(sum->rp_elapsed_ns));
MR_STAT("hc_cpu_seconds", "f", TimeToSecondsDbl(sum->hc_cpu_ns));
MR_STAT("hc_wall_seconds", "f", TimeToSecondsDbl(sum->hc_elapsed_ns));
#endif
MR_STAT("total_cpu_seconds", "f", TimeToSecondsDbl(stats.cpu_ns));
MR_STAT("total_wall_seconds", "f",
TimeToSecondsDbl(stats.elapsed_ns));
// next, the remainder of the fields of RTSStats, except internal counters
// The first two are duplicates of those above, but have more machine
// readable names that match the field names in RTSStats.
// gcs has been done as num_GCs above
MR_STAT("major_gcs", FMT_Word32, stats.major_gcs);
MR_STAT("allocated_bytes", FMT_Word64, stats.allocated_bytes);
MR_STAT("max_live_bytes", FMT_Word64, stats.max_live_bytes);
MR_STAT("max_large_objects_bytes", FMT_Word64,
stats.max_large_objects_bytes);
MR_STAT("max_compact_bytes", FMT_Word64, stats.max_compact_bytes);
MR_STAT("max_slop_bytes", FMT_Word64, stats.max_slop_bytes);
// This duplicates, except for unit, peak_megabytes_allocated above
MR_STAT("max_mem_in_use_bytes", FMT_Word64, stats.max_mem_in_use_bytes);
MR_STAT("cumulative_live_bytes", FMT_Word64, stats.cumulative_live_bytes);
MR_STAT("copied_bytes", FMT_Word64, stats.copied_bytes);
MR_STAT("par_copied_bytes", FMT_Word64, stats.par_copied_bytes);
MR_STAT("cumulative_par_max_copied_bytes", FMT_Word64,
stats.cumulative_par_max_copied_bytes);
MR_STAT("cumulative_par_balanced_copied_bytes", FMT_Word64,
stats.cumulative_par_balanced_copied_bytes);
// next, the computed fields in RTSSummaryStats
#if !defined(THREADED_RTS) // THREADED_RTS
MR_STAT("gc_cpu_percent", "f", sum->gc_cpu_percent);
MR_STAT("gc_wall_percent", "f", sum->gc_cpu_percent);
#endif
MR_STAT("fragmentation_bytes", FMT_Word64, sum->fragmentation_bytes);
// average_bytes_used is done above
MR_STAT("alloc_rate", FMT_Word64, sum->alloc_rate);
MR_STAT("productivity_cpu_percent", "f", sum->productivity_cpu_percent);
MR_STAT("productivity_wall_percent", "f",
sum->productivity_elapsed_percent);
// next, the THREADED_RTS fields in RTSSummaryStats
#if defined(THREADED_RTS)
MR_STAT("bound_task_count", FMT_Word32, sum->bound_task_count);
MR_STAT("sparks_count", FMT_Word64, sum->sparks_count);
MR_STAT("sparks_converted", FMT_Word, sum->sparks.converted);
MR_STAT("sparks_overflowed", FMT_Word, sum->sparks.overflowed);
MR_STAT("sparks_dud ", FMT_Word, sum->sparks.dud);
MR_STAT("sparks_gcd", FMT_Word, sum->sparks.gcd);
MR_STAT("sparks_fizzled", FMT_Word, sum->sparks.fizzled);
MR_STAT("work_balance", "f", sum->work_balance);
// next, globals (other than internal counters)
MR_STAT("n_capabilities", FMT_Word32, n_capabilities);
MR_STAT("task_count", FMT_Word32, taskCount);
MR_STAT("peak_worker_count", FMT_Word32, peakWorkerCount);
MR_STAT("worker_count", FMT_Word32, workerCount);
// next, internal counters
#if defined(PROF_SPIN)
MR_STAT("gc_alloc_block_sync_spin", FMT_Word64, gc_alloc_block_sync.spin);
MR_STAT("gc_alloc_block_sync_yield", FMT_Word64,
gc_alloc_block_sync.yield);
MR_STAT("gc_alloc_block_sync_spin", FMT_Word64, gc_alloc_block_sync.spin);
MR_STAT("gc_spin_spin", FMT_Word64, stats.gc_spin_spin);
MR_STAT("gc_spin_yield", FMT_Word64, stats.gc_spin_yield);
MR_STAT("mut_spin_spin", FMT_Word64, stats.mut_spin_spin);
MR_STAT("mut_spin_yield", FMT_Word64, stats.mut_spin_yield);
MR_STAT("waitForGcThreads_spin", FMT_Word64, waitForGcThreads_spin);
MR_STAT("waitForGcThreads_yield", FMT_Word64,
waitForGcThreads_yield);
MR_STAT("whitehole_gc_spin", FMT_Word64, whitehole_gc_spin);
MR_STAT("whitehole_lockClosure_spin", FMT_Word64,
whitehole_lockClosure_spin);
MR_STAT("whitehole_lockClosure_yield", FMT_Word64,
whitehole_lockClosure_yield);
MR_STAT("whitehole_executeMessage_spin", FMT_Word64,
whitehole_executeMessage_spin);
MR_STAT("whitehole_threadPaused_spin", FMT_Word64,
whitehole_threadPaused_spin);
MR_STAT("any_work", FMT_Word64,
stats.any_work);
MR_STAT("no_work", FMT_Word64,
stats.no_work);
MR_STAT("scav_find_work", FMT_Word64,
stats.scav_find_work);
#endif // PROF_SPIN
#endif // THREADED_RTS
// finally, per-generation stats. Named as, for example for generation 0,
// gen_0_collections
for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
const GenerationSummaryStats* gc_sum = &sum->gc_summary_stats[g];
MR_STAT_GEN(g, "collections", FMT_Word32, gc_sum->collections);
MR_STAT_GEN(g, "par_collections", FMT_Word32, gc_sum->par_collections);
MR_STAT_GEN(g, "cpu_seconds", "f", TimeToSecondsDbl(gc_sum->cpu_ns));
MR_STAT_GEN(g, "wall_seconds", "f",
TimeToSecondsDbl(gc_sum->elapsed_ns));
MR_STAT_GEN(g, "max_pause_seconds", "f",
TimeToSecondsDbl(gc_sum->max_pause_ns));
MR_STAT_GEN(g, "avg_pause_seconds", "f",
TimeToSecondsDbl(gc_sum->avg_pause_ns));
#if defined(THREADED_RTS) && defined(PROF_SPIN)
MR_STAT_GEN(g, "sync_spin", FMT_Word64, gc_sum->sync_spin);
MR_STAT_GEN(g, "sync_yield", FMT_Word64, gc_sum->sync_yield);
#endif
}
statsPrintf(" ]\n");
}