[gjs: 5/7] profiler: Define sysprof counters for the GObject wrapper counts
- From: Philip Chimento <pchimento src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs: 5/7] profiler: Define sysprof counters for the GObject wrapper counts
- Date: Sun, 4 Jul 2021 19:09:38 +0000 (UTC)
commit 8879b6bc258a08bd5cbc0ba43eb2d6b375d40ca4
Author: Philip Chimento <philip endlessm com>
Date: Fri Dec 6 16:35:42 2019 -0800
profiler: Define sysprof counters for the GObject wrapper counts
This sends the current values of the counts from mem.cpp to sysprof along
with every profiler sample.
gjs/mem-private.h | 26 +++++++++++++++++++++++++
gjs/profiler.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 83 insertions(+), 1 deletion(-)
---
diff --git a/gjs/mem-private.h b/gjs/mem-private.h
index 8c6caca5..adb07ad6 100644
--- a/gjs/mem-private.h
+++ b/gjs/mem-private.h
@@ -6,6 +6,8 @@
#ifndef GJS_MEM_PRIVATE_H_
#define GJS_MEM_PRIVATE_H_
+#include <stddef.h> // for size_t
+
#include <atomic>
// clang-format off
@@ -59,6 +61,30 @@ constexpr void dec() {
} // namespace Memory
} // namespace Gjs
+#define COUNT(name, ix) +1
+static constexpr size_t GJS_N_COUNTERS = 0 GJS_FOR_EACH_COUNTER(COUNT);
+#undef COUNT
+
+static constexpr const char GJS_COUNTER_DESCRIPTIONS[GJS_N_COUNTERS][52] = {
+ // max length of description string ---------------v
+ "Number of boxed type wrapper objects",
+ "Number of boxed type prototype objects",
+ "Number of signal handlers",
+ "Number of introspected functions",
+ "Number of fundamental type wrapper objects",
+ "Number of fundamental type prototype objects",
+ "Number of GError wrapper objects",
+ "Number of GError prototype objects",
+ "Number of GObject interface objects",
+ "Number of modules",
+ "Number of GI namespace objects",
+ "Number of GObject wrapper objects",
+ "Number of GObject prototype objects",
+ "Number of GParamSpec wrapper objects",
+ "Number of C union wrapper objects",
+ "Number of C union prototype objects",
+};
+
#define GJS_INC_COUNTER(name) \
(Gjs::Memory::Counters::inc<&Gjs::Memory::Counters::name>());
diff --git a/gjs/profiler.cpp b/gjs/profiler.cpp
index 2d342498..c4518bfa 100644
--- a/gjs/profiler.cpp
+++ b/gjs/profiler.cpp
@@ -34,6 +34,7 @@
#include "gjs/context.h"
#include "gjs/jsapi-util.h"
+#include "gjs/mem-private.h"
#include "gjs/profiler.h"
#define FLUSH_DELAY_SECONDS 3
@@ -104,6 +105,7 @@ struct _GjsProfiler {
/* GLib signal handler ID for SIGUSR2 */
unsigned sigusr2_id;
+ unsigned counter_base; // index of first GObject memory counter
#endif /* ENABLE_PROFILER */
/* If we are currently sampling */
@@ -164,6 +166,38 @@ static GjsContext *profiling_context;
return true;
}
+
+static void setup_counter_helper(SysprofCaptureCounter* counter,
+ const char* counter_name,
+ unsigned counter_base, size_t ix) {
+ g_snprintf(counter->category, sizeof counter->category, "GJS");
+ g_snprintf(counter->name, sizeof counter->name, "%s", counter_name);
+ g_snprintf(counter->description, sizeof counter->description, "%s",
+ GJS_COUNTER_DESCRIPTIONS[ix]);
+ counter->id = uint32_t(counter_base + ix);
+ counter->type = SYSPROF_CAPTURE_COUNTER_INT64;
+ counter->value.v64 = 0;
+}
+
+[[nodiscard]] static bool gjs_profiler_define_counters(GjsProfiler* self) {
+ int64_t now = g_get_monotonic_time() * 1000L;
+
+ g_assert(self && "Profiler must be set up before defining counters");
+
+ SysprofCaptureCounter counters[GJS_N_COUNTERS];
+ self->counter_base =
+ sysprof_capture_writer_request_counter(self->capture, GJS_N_COUNTERS);
+
+# define SETUP_COUNTER(counter_name, ix) \
+ setup_counter_helper(&counters[ix], #counter_name, self->counter_base, \
+ ix);
+ GJS_FOR_EACH_COUNTER(SETUP_COUNTER);
+# undef SETUP_COUNTER
+
+ return sysprof_capture_writer_define_counters(
+ self->capture, now, -1, self->pid, counters, GJS_N_COUNTERS);
+}
+
#endif /* ENABLE_PROFILER */
/*
@@ -364,7 +398,22 @@ static void gjs_profiler_sigprof(int signum [[maybe_unused]], siginfo_t* info,
}
if (!sysprof_capture_writer_add_sample(self->capture, now, -1, self->pid,
- -1, addrs, depth))
+ -1, addrs, depth)) {
+ gjs_profiler_stop(self);
+ return;
+ }
+
+ unsigned ids[GJS_N_COUNTERS];
+ SysprofCaptureCounterValue values[GJS_N_COUNTERS];
+
+# define FETCH_COUNTERS(name, ix) \
+ ids[ix] = self->counter_base + ix; \
+ values[ix].v64 = GJS_GET_COUNTER(name);
+ GJS_FOR_EACH_COUNTER(FETCH_COUNTERS);
+# undef FETCH_COUNTERS
+
+ if (!sysprof_capture_writer_set_counters(self->capture, now, -1, self->pid,
+ ids, values, GJS_N_COUNTERS))
gjs_profiler_stop(self);
}
@@ -451,6 +500,13 @@ gjs_profiler_start(GjsProfiler *self)
return;
}
+ if (!gjs_profiler_define_counters(self)) {
+ g_warning("Failed to define sysprof counters");
+ g_clear_pointer(&self->capture, sysprof_capture_writer_unref);
+ g_clear_pointer(&self->periodic_flush, g_source_destroy);
+ return;
+ }
+
/* Setup our signal handler for SIGPROF delivery */
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sa.sa_sigaction = gjs_profiler_sigprof;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]