wingo pushed a commit to branch wip-whippet in repository guile. commit 0cff6ffba484e7dd43acc0c5b5c0d1759b58275c Author: Andy Wingo <wi...@igalia.com> AuthorDate: Thu Mar 13 13:43:41 2025 +0100
Basic stats also record CPU time --- api/gc-basic-stats.h | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/api/gc-basic-stats.h b/api/gc-basic-stats.h index 6b39a59c6..055340817 100644 --- a/api/gc-basic-stats.h +++ b/api/gc-basic-stats.h @@ -9,6 +9,7 @@ #include <stdio.h> #include <string.h> #include <sys/time.h> +#include <time.h> GC_DEFINE_HISTOGRAM(gc_latency, 25, 4); @@ -16,8 +17,11 @@ struct gc_basic_stats { uint64_t major_collection_count; uint64_t minor_collection_count; uint64_t last_time_usec; + uint64_t last_cpu_time_usec; uint64_t elapsed_mutator_usec; uint64_t elapsed_collector_usec; + uint64_t cpu_mutator_usec; + uint64_t cpu_collector_usec; size_t heap_size; size_t max_heap_size; size_t max_live_data_size; @@ -33,18 +37,31 @@ static inline uint64_t gc_basic_stats_now(void) { return ret; } +static inline uint64_t gc_basic_stats_cpu_time(void) { + struct timespec ts; + clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &ts); + uint64_t ret = ts.tv_sec; + ret *= 1000 * 1000; + ret += ts.tv_nsec / 1000; + return ret; +} + static inline void gc_basic_stats_init(void *data, size_t heap_size) { struct gc_basic_stats *stats = data; memset(stats, 0, sizeof(*stats)); stats->last_time_usec = gc_basic_stats_now(); + stats->last_cpu_time_usec = gc_basic_stats_cpu_time(); stats->heap_size = stats->max_heap_size = heap_size; } static inline void gc_basic_stats_requesting_stop(void *data) { struct gc_basic_stats *stats = data; uint64_t now = gc_basic_stats_now(); + uint64_t cpu_time = gc_basic_stats_cpu_time(); stats->elapsed_mutator_usec += now - stats->last_time_usec; + stats->cpu_mutator_usec += cpu_time - stats->last_cpu_time_usec; stats->last_time_usec = now; + stats->last_cpu_time_usec = cpu_time; } static inline void gc_basic_stats_waiting_for_stop(void *data) {} static inline void gc_basic_stats_mutators_stopped(void *data) {} @@ -66,10 +83,14 @@ static inline void gc_basic_stats_finalizers_traced(void *data) {} static inline void gc_basic_stats_restarting_mutators(void *data) { struct gc_basic_stats *stats = data; uint64_t now = gc_basic_stats_now(); + uint64_t cpu_time = gc_basic_stats_cpu_time(); uint64_t pause_time = now - stats->last_time_usec; + uint64_t pause_cpu_time = cpu_time - stats->last_cpu_time_usec; stats->elapsed_collector_usec += pause_time; + stats->cpu_collector_usec += pause_cpu_time; gc_latency_record(&stats->pause_times, pause_time); stats->last_time_usec = now; + stats->last_cpu_time_usec = cpu_time; } static inline void* gc_basic_stats_mutator_added(void *data) { @@ -118,8 +139,11 @@ static inline void gc_basic_stats_live_data_size(void *data, size_t size) { static inline void gc_basic_stats_finish(struct gc_basic_stats *stats) { uint64_t now = gc_basic_stats_now(); + uint64_t cpu_time = gc_basic_stats_cpu_time(); stats->elapsed_mutator_usec += now - stats->last_time_usec; + stats->cpu_mutator_usec += cpu_time - stats->last_cpu_time_usec; stats->last_time_usec = now; + stats->last_cpu_time_usec = cpu_time; } static inline void gc_basic_stats_print(struct gc_basic_stats *stats, FILE *f) { @@ -127,10 +151,15 @@ static inline void gc_basic_stats_print(struct gc_basic_stats *stats, FILE *f) { stats->major_collection_count, stats->minor_collection_count); uint64_t stopped = stats->elapsed_collector_usec; uint64_t elapsed = stats->elapsed_mutator_usec + stopped; + uint64_t cpu_stopped = stats->cpu_collector_usec; + uint64_t cpu_total = stats->cpu_mutator_usec + cpu_stopped; uint64_t ms = 1000; // per usec fprintf(f, "%" PRIu64 ".%.3" PRIu64 " ms total time " + "(%" PRIu64 ".%.3" PRIu64 " stopped); " + "%" PRIu64 ".%.3" PRIu64 " ms CPU time " "(%" PRIu64 ".%.3" PRIu64 " stopped).\n", - elapsed / ms, elapsed % ms, stopped / ms, stopped % ms); + elapsed / ms, elapsed % ms, stopped / ms, stopped % ms, + cpu_total / ms, cpu_total % ms, cpu_stopped / ms, cpu_stopped % ms); uint64_t pause_median = gc_latency_median(&stats->pause_times); uint64_t pause_p95 = gc_latency_percentile(&stats->pause_times, 0.95); uint64_t pause_max = gc_latency_max(&stats->pause_times);