[sysprof/wip/chergert/control-fd] capture: simplify collector interface
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sysprof/wip/chergert/control-fd] capture: simplify collector interface
- Date: Sat, 8 Feb 2020 17:32:30 +0000 (UTC)
commit cc2c202cd868840112029eeacd843f1e8ffaf54e
Author: Christian Hergert <chergert redhat com>
Date: Sat Feb 8 09:31:16 2020 -0800
capture: simplify collector interface
This allows us to discover a few scenarios for which might require locking
among contributor threads (when a single capture file is necessary). The
common case, however, should be a multi-threaded capture writing without
locking (using a writer in TLS) which is muxed by Sysprof after the
capture has completed.
src/libsysprof-capture/sysprof-collector.c | 354 ++++++++++++++---------------
src/libsysprof-capture/sysprof-collector.h | 77 +++----
2 files changed, 207 insertions(+), 224 deletions(-)
---
diff --git a/src/libsysprof-capture/sysprof-collector.c b/src/libsysprof-capture/sysprof-collector.c
index e60655c..8239dc0 100644
--- a/src/libsysprof-capture/sysprof-collector.c
+++ b/src/libsysprof-capture/sysprof-collector.c
@@ -75,12 +75,13 @@
#include "sysprof-capture-writer.h"
#include "sysprof-collector.h"
-struct _SysprofCollector
+typedef struct
{
SysprofCaptureWriter *writer;
+ gboolean is_shared;
int tid;
int pid;
-};
+} SysprofCollector;
#ifdef __linux__
# define sysprof_current_cpu (sched_getcpu())
@@ -88,21 +89,27 @@ struct _SysprofCollector
# define sysprof_current_cpu (-1)
#endif
-static SysprofCaptureWriter *request_writer (void);
-static void sysprof_collector_free (gpointer data);
-static SysprofCollector *sysprof_collector_get (void);
+static SysprofCaptureWriter *request_writer (void);
+static void sysprof_collector_free (gpointer data);
+static const SysprofCollector *sysprof_collector_get (void);
+static G_LOCK_DEFINE (control_fd);
static GPrivate collector_key = G_PRIVATE_INIT (sysprof_collector_free);
+static GPrivate single_trace_key = G_PRIVATE_INIT (NULL);
+static SysprofCollector *shared_collector;
+
+static inline gboolean
+use_single_trace (void)
+{
+ return GPOINTER_TO_INT (g_private_get (&single_trace_key));
+}
static SysprofCaptureWriter *
request_writer (void)
{
- static G_LOCK_DEFINE (control_fd);
static GDBusConnection *peer;
SysprofCaptureWriter *writer = NULL;
- G_LOCK (control_fd);
-
if (peer == NULL)
{
const gchar *fdstr = g_getenv ("SYSPROF_CONTROL_FD");
@@ -171,8 +178,6 @@ request_writer (void)
}
}
- G_UNLOCK (control_fd);
-
return g_steal_pointer (&writer);
}
@@ -189,228 +194,221 @@ sysprof_collector_free (gpointer data)
}
}
-static SysprofCollector *
+static const SysprofCollector *
sysprof_collector_get (void)
{
- SysprofCollector *collector = g_private_get (&collector_key);
+ const SysprofCollector *collector = g_private_get (&collector_key);
- if G_UNLIKELY (collector == NULL)
- {
- collector = g_slice_new0 (SysprofCollector);
- collector->writer = request_writer ();
- collector->pid = getpid ();
+ if G_LIKELY (collector != NULL)
+ return collector;
+
+ if (use_single_trace () && shared_collector != NULL)
+ return shared_collector;
+
+ {
+ SysprofCollector *self;
+
+ G_LOCK (control_fd);
+
+ self = g_slice_new0 (SysprofCollector);
+ self->pid = getpid ();
#ifdef __linux__
- collector->tid = syscall (__NR_gettid, 0);
+ self->tid = syscall (__NR_gettid, 0);
#endif
- g_private_replace (&collector_key, collector);
- }
- return collector;
+ /* If we are not profiling under Sysprof directly, then we want to
+ * require synchronization from our threads to a single writer which
+ * matches "capture.$pid.syscap".
+ */
+ if (g_getenv ("SYSPROF_CONTROL_FD") != NULL)
+ {
+ self->writer = request_writer ();
+ }
+ else
+ {
+ /* TODO: Fix envvar name */
+ const gchar *trace_fd = g_getenv ("SYSPROF_TRACE_FD");
+
+ if (trace_fd != NULL)
+ {
+ int fd = atoi (trace_fd);
+
+ if (fd > 0)
+ {
+ self->writer = sysprof_capture_writer_new_from_fd (fd, 0);
+ self->is_shared = TRUE;
+ }
+ }
+
+ if (self->writer == NULL && g_getenv ("SYSPROF_TRACE") != NULL)
+ {
+ g_autofree gchar *filename = g_strdup_printf ("capture.%d.syscap", (int)getpid ());
+
+ self->writer = sysprof_capture_writer_new (filename, 0);
+ self->is_shared = TRUE;
+ }
+ }
+
+ if (self->is_shared)
+ shared_collector = self;
+ else
+ g_private_replace (&collector_key, self);
+
+ G_UNLOCK (control_fd);
+
+ return self;
+ }
}
-SysprofCollector *
-sysprof_collector_get_thread_default (void)
-{
- return sysprof_collector_get ();
-}
+#define ADD_TO_COLLECTOR(func) \
+ G_STMT_START { \
+ const SysprofCollector *collector = sysprof_collector_get (); \
+ if (collector->is_shared) { G_LOCK (control_fd); } \
+ if (collector->writer != NULL) { func; } \
+ if (collector->is_shared) { G_UNLOCK (control_fd); } \
+ } G_STMT_END
void
-sysprof_collector_embed_file (SysprofCollector *collector,
- const gchar *path,
- const guint8 *data,
- gsize data_len)
+sysprof_collector_embed_file (const gchar *path,
+ const guint8 *data,
+ gsize data_len)
{
- if (collector == NULL)
- collector = sysprof_collector_get ();
-
- if (collector->writer != NULL)
- sysprof_capture_writer_add_file (collector->writer,
- SYSPROF_CAPTURE_CURRENT_TIME,
- sysprof_current_cpu,
- collector->pid,
- path,
- TRUE,
- data,
- data_len);
+ ADD_TO_COLLECTOR (sysprof_capture_writer_add_file (collector->writer,
+ SYSPROF_CAPTURE_CURRENT_TIME,
+ sysprof_current_cpu,
+ collector->pid,
+ path,
+ TRUE,
+ data,
+ data_len));
}
void
-sysprof_collector_embed_file_fd (SysprofCollector *collector,
- const gchar *path,
- int fd)
+sysprof_collector_embed_file_fd (const gchar *path,
+ int fd)
{
- if (collector == NULL)
- collector = sysprof_collector_get ();
-
- if (collector->writer != NULL)
- sysprof_capture_writer_add_file_fd (collector->writer,
- SYSPROF_CAPTURE_CURRENT_TIME,
- sysprof_current_cpu,
- collector->pid,
- path,
- fd);
+ ADD_TO_COLLECTOR(sysprof_capture_writer_add_file_fd (collector->writer,
+ SYSPROF_CAPTURE_CURRENT_TIME,
+ sysprof_current_cpu,
+ collector->pid,
+ path,
+ fd));
}
void
-sysprof_collector_mark (SysprofCollector *collector,
- gint64 time,
- guint64 duration,
- const gchar *group,
- const gchar *name,
- const gchar *message)
+sysprof_collector_mark (gint64 time,
+ guint64 duration,
+ const gchar *group,
+ const gchar *name,
+ const gchar *message)
{
- if (collector == NULL)
- collector = sysprof_collector_get ();
-
- if (collector->writer != NULL)
- sysprof_capture_writer_add_mark (collector->writer,
- SYSPROF_CAPTURE_CURRENT_TIME,
- sysprof_current_cpu,
- collector->pid,
- duration,
- group,
- name,
- message);
+ ADD_TO_COLLECTOR (sysprof_capture_writer_add_mark (collector->writer,
+ SYSPROF_CAPTURE_CURRENT_TIME,
+ sysprof_current_cpu,
+ collector->pid,
+ duration,
+ group,
+ name,
+ message));
}
void
-sysprof_collector_set_metadata (SysprofCollector *collector,
- const gchar *id,
- const gchar *value,
- gssize value_len)
+sysprof_collector_set_metadata (const gchar *id,
+ const gchar *value,
+ gssize value_len)
{
- if (collector == NULL)
- collector = sysprof_collector_get ();
-
- if (collector->writer != NULL)
- sysprof_capture_writer_add_metadata (collector->writer,
- SYSPROF_CAPTURE_CURRENT_TIME,
- sysprof_current_cpu,
- collector->pid,
- id,
- value,
- value_len);
+ ADD_TO_COLLECTOR (sysprof_capture_writer_add_metadata (collector->writer,
+ SYSPROF_CAPTURE_CURRENT_TIME,
+ sysprof_current_cpu,
+ collector->pid,
+ id,
+ value,
+ value_len));
}
void
-sysprof_collector_sample (SysprofCollector *collector,
- gint64 time,
+sysprof_collector_sample (gint64 time,
const SysprofCaptureAddress *addrs,
guint n_addrs)
{
- if (collector == NULL)
- collector = sysprof_collector_get ();
-
- if (collector->writer != NULL)
- sysprof_capture_writer_add_sample (collector->writer,
- time,
- sysprof_current_cpu,
- collector->pid,
- collector->tid,
- addrs,
- n_addrs);
+ ADD_TO_COLLECTOR (sysprof_capture_writer_add_sample (collector->writer,
+ time,
+ sysprof_current_cpu,
+ collector->pid,
+ collector->tid,
+ addrs,
+ n_addrs));
}
void
-sysprof_collector_log (SysprofCollector *collector,
- GLogLevelFlags severity,
- const gchar *domain,
- const gchar *message)
+sysprof_collector_log (GLogLevelFlags severity,
+ const gchar *domain,
+ const gchar *message)
{
- if (collector == NULL)
- collector = sysprof_collector_get ();
-
- if (collector->writer != NULL)
- sysprof_capture_writer_add_log (collector->writer,
- SYSPROF_CAPTURE_CURRENT_TIME,
- sysprof_current_cpu,
- collector->pid,
- severity,
- domain,
- message);
+ ADD_TO_COLLECTOR (sysprof_capture_writer_add_log (collector->writer,
+ SYSPROF_CAPTURE_CURRENT_TIME,
+ sysprof_current_cpu,
+ collector->pid,
+ severity,
+ domain,
+ message));
}
SysprofCaptureAddress
-sysprof_collector_map_jitted_ip (SysprofCollector *collector,
- const gchar *name)
+sysprof_collector_map_jitted_ip (const gchar *name)
{
- if (collector == NULL)
- collector = sysprof_collector_get ();
-
- if (collector->writer != NULL)
- return sysprof_capture_writer_add_jitmap (collector->writer, name);
-
- return 0;
+ SysprofCaptureAddress ret = 0;
+ ADD_TO_COLLECTOR ((ret = sysprof_capture_writer_add_jitmap (collector->writer, name)));
+ return ret;
}
void
-sysprof_collector_allocate (SysprofCollector *collector,
- SysprofCaptureAddress alloc_addr,
- gint64 alloc_size,
- SysprofBacktraceFunc backtrace_func,
- gpointer backtrace_data)
+sysprof_collector_allocate (SysprofCaptureAddress alloc_addr,
+ gint64 alloc_size,
+ SysprofBacktraceFunc backtrace_func,
+ gpointer backtrace_data)
{
- if (collector == NULL)
- collector = sysprof_collector_get ();
-
- if (collector->writer != NULL)
- sysprof_capture_writer_add_allocation (collector->writer,
- SYSPROF_CAPTURE_CURRENT_TIME,
- sysprof_current_cpu,
- collector->pid,
- collector->tid,
- alloc_addr,
- alloc_size,
- backtrace_func,
- backtrace_data);
+ ADD_TO_COLLECTOR (sysprof_capture_writer_add_allocation (collector->writer,
+ SYSPROF_CAPTURE_CURRENT_TIME,
+ sysprof_current_cpu,
+ collector->pid,
+ collector->tid,
+ alloc_addr,
+ alloc_size,
+ backtrace_func,
+ backtrace_data));
}
guint
-sysprof_collector_reserve_counters (SysprofCollector *collector,
- guint n_counters)
+sysprof_collector_reserve_counters (guint n_counters)
{
- if (collector == NULL)
- collector = sysprof_collector_get ();
-
- if (collector->writer != NULL)
- return sysprof_capture_writer_request_counter (collector->writer,
- n_counters);
-
- return 1;
+ guint ret = 1;
+ ADD_TO_COLLECTOR ((ret = sysprof_capture_writer_request_counter (collector->writer, n_counters)));
+ return ret;
}
void
-sysprof_collector_define_counters (SysprofCollector *collector,
- const SysprofCaptureCounter *counters,
+sysprof_collector_define_counters (const SysprofCaptureCounter *counters,
guint n_counters)
{
- if (collector == NULL)
- collector = sysprof_collector_get ();
-
- if (collector->writer != NULL)
- sysprof_capture_writer_define_counters (collector->writer,
- SYSPROF_CAPTURE_CURRENT_TIME,
- sysprof_current_cpu,
- collector->pid,
- counters,
- n_counters);
+ ADD_TO_COLLECTOR (sysprof_capture_writer_define_counters (collector->writer,
+ SYSPROF_CAPTURE_CURRENT_TIME,
+ sysprof_current_cpu,
+ collector->pid,
+ counters,
+ n_counters));
}
void
-sysprof_collector_publish_counters (SysprofCollector *collector,
- const guint *counters_ids,
+sysprof_collector_publish_counters (const guint *counters_ids,
const SysprofCaptureCounterValue *values,
guint n_counters)
{
- if (collector == NULL)
- collector = sysprof_collector_get ();
-
- if (collector->writer != NULL)
- sysprof_capture_writer_set_counters (collector->writer,
- SYSPROF_CAPTURE_CURRENT_TIME,
- sysprof_current_cpu,
- collector->pid,
- counters_ids,
- values,
- n_counters);
+ ADD_TO_COLLECTOR (sysprof_capture_writer_set_counters (collector->writer,
+ SYSPROF_CAPTURE_CURRENT_TIME,
+ sysprof_current_cpu,
+ collector->pid,
+ counters_ids,
+ values,
+ n_counters));
}
diff --git a/src/libsysprof-capture/sysprof-collector.h b/src/libsysprof-capture/sysprof-collector.h
index 143dde4..ca7b1d5 100644
--- a/src/libsysprof-capture/sysprof-collector.h
+++ b/src/libsysprof-capture/sysprof-collector.h
@@ -57,65 +57,50 @@
#pragma once
#include "sysprof-capture-types.h"
-#include "sysprof-version-macros.h"
+#include "sysprof-capture-writer.h"
G_BEGIN_DECLS
-typedef struct _SysprofCollector SysprofCollector;
-
-SYSPROF_AVAILABLE_IN_3_36
-SysprofCollector *sysprof_collector_get_thread_default (void);
SYSPROF_AVAILABLE_IN_3_36
-void sysprof_collector_embed_file (SysprofCollector *collector,
- const gchar *path,
- const guint8 *data,
- gsize data_len);
+void sysprof_collector_embed_file (const gchar *path,
+ const guint8 *data,
+ gsize data_len);
SYSPROF_AVAILABLE_IN_3_36
-void sysprof_collector_embed_file_fd (SysprofCollector *collector,
- const gchar *path,
- gint fd);
+void sysprof_collector_embed_file_fd (const gchar *path,
+ gint fd);
SYSPROF_AVAILABLE_IN_3_36
-void sysprof_collector_mark (SysprofCollector *collector,
- gint64 time,
- guint64 duration,
- const gchar *group,
- const gchar *name,
- const gchar *mesage);
+void sysprof_collector_mark (gint64 time,
+ guint64 duration,
+ const gchar *group,
+ const gchar *name,
+ const gchar *mesage);
SYSPROF_AVAILABLE_IN_3_36
-void sysprof_collector_set_metadata (SysprofCollector *collector,
- const gchar *id,
- const gchar *value,
- gssize value_len);
+void sysprof_collector_set_metadata (const gchar *id,
+ const gchar *value,
+ gssize value_len);
SYSPROF_AVAILABLE_IN_3_36
-void sysprof_collector_sample (SysprofCollector *collector,
- gint64 time,
- const SysprofCaptureAddress *addrs,
- guint n_addrs);
+void sysprof_collector_sample (gint64 time,
+ const SysprofCaptureAddress *addrs,
+ guint n_addrs);
SYSPROF_AVAILABLE_IN_3_36
-void sysprof_collector_log (SysprofCollector *collector,
- GLogLevelFlags severity,
- const gchar *domain,
- const gchar *message);
+void sysprof_collector_log (GLogLevelFlags severity,
+ const gchar *domain,
+ const gchar *message);
SYSPROF_AVAILABLE_IN_3_36
-SysprofCaptureAddress sysprof_collector_map_jitted_ip (SysprofCollector *collector,
- const gchar *name);
+SysprofCaptureAddress sysprof_collector_map_jitted_ip (const gchar *name);
SYSPROF_AVAILABLE_IN_3_36
-void sysprof_collector_allocate (SysprofCollector *collector,
- SysprofCaptureAddress alloc_addr,
- gint64 alloc_size,
- SysprofBacktraceFunc
backtrace_func,
- gpointer
backtrace_data);
+void sysprof_collector_allocate (SysprofCaptureAddress alloc_addr,
+ gint64 alloc_size,
+ SysprofBacktraceFunc backtrace_func,
+ gpointer backtrace_data);
SYSPROF_AVAILABLE_IN_3_36
-guint sysprof_collector_reserve_counters (SysprofCollector *collector,
- guint n_counters);
+guint sysprof_collector_reserve_counters (guint n_counters);
SYSPROF_AVAILABLE_IN_3_36
-void sysprof_collector_define_counters (SysprofCollector *collector,
- const SysprofCaptureCounter *counters,
- guint n_counters);
+void sysprof_collector_define_counters (const SysprofCaptureCounter *counters,
+ guint n_counters);
SYSPROF_AVAILABLE_IN_3_36
-void sysprof_collector_publish_counters (SysprofCollector *collector,
- const guint *counters_ids,
- const SysprofCaptureCounterValue *values,
- guint n_counters);
+void sysprof_collector_publish_counters (const guint *counters_ids,
+ const SysprofCaptureCounterValue *values,
+ guint n_counters);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]