summaryrefslogtreecommitdiff
path: root/gjs/profiler.cpp
diff options
context:
space:
mode:
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2020-09-19 14:57:22 -0300
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2020-09-19 14:57:22 -0300
commit607f9aa66192d4955f7daf5906b5053c30ce8ff2 (patch)
tree7eba447778dc077005015dae375fd974868456c9 /gjs/profiler.cpp
parentd32c24e520ab660b0eaf0f68b7ded17b20b271b1 (diff)
downloadgjs-607f9aa66192d4955f7daf5906b5053c30ce8ff2.tar.gz
profiler: Support external SysprofCaptureWritersgbsneto/external-capture-writer
Using environment variables to control the profiler is limiting, and when it comes to GNOME Shell, it adds an extra level of complexity, since it forces us to start GNOME Shell with the right environment set. Add support for setting a caller-controlled SysprofCaptureWriter. The header file treats it as a gpointer to avoid including config.h. If an external capture writer is set, it takes precedence over the filename and the file descriptor.
Diffstat (limited to 'gjs/profiler.cpp')
-rw-r--r--gjs/profiler.cpp31
1 files changed, 30 insertions, 1 deletions
diff --git a/gjs/profiler.cpp b/gjs/profiler.cpp
index c5113bec..d7c90ef5 100644
--- a/gjs/profiler.cpp
+++ b/gjs/profiler.cpp
@@ -105,6 +105,8 @@ struct _GjsProfiler {
/* Buffers and writes our sampled stacks */
SysprofCaptureWriter* capture;
GSource* periodic_flush;
+
+ SysprofCaptureWriter* target_capture;
#endif /* ENABLE_PROFILER */
/* The filename to write to */
@@ -259,6 +261,7 @@ _gjs_profiler_free(GjsProfiler *self)
#ifdef ENABLE_PROFILER
g_clear_pointer(&self->capture, sysprof_capture_writer_unref);
g_clear_pointer(&self->periodic_flush, g_source_destroy);
+ g_clear_pointer(&self->target_capture, sysprof_capture_writer_unref);
if (self->fd != -1)
close(self->fd);
@@ -429,7 +432,9 @@ gjs_profiler_start(GjsProfiler *self)
struct itimerspec its = { 0 };
struct itimerspec old_its;
- if (self->fd != -1) {
+ if (self->target_capture) {
+ self->capture = sysprof_capture_writer_ref(self->target_capture);
+ } else if (self->fd != -1) {
self->capture = sysprof_capture_writer_new_from_fd(self->fd, 0);
self->fd = -1;
} else {
@@ -673,6 +678,30 @@ gjs_profiler_chain_signal(GjsContext *context,
}
/**
+ * gjs_profiler_set_capture_writer:
+ * @self: A #GjsProfiler
+ * @capture: (nullable): A #SysprofCaptureWriter
+ *
+ * Set the capture writer to which profiling data is written when the @self
+ * is stopped.
+ */
+void gjs_profiler_set_capture_writer(GjsProfiler* self, gpointer capture) {
+ g_return_if_fail(self);
+ g_return_if_fail(!self->running);
+
+#ifdef ENABLE_PROFILER
+ g_clear_pointer(&self->target_capture, sysprof_capture_writer_unref);
+ self->target_capture =
+ capture ? sysprof_capture_writer_ref(
+ reinterpret_cast<SysprofCaptureWriter*>(capture))
+ : NULL;
+#else
+ // Unused in the no-profiler case
+ (void)capture;
+#endif
+}
+
+/**
* gjs_profiler_set_filename:
* @self: A #GjsProfiler
* @filename: string containing a filename