[mutter/gbsneto/tracing: 65/68] profile: Add a Sysprof-based profiler (WIP)
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gbsneto/tracing: 65/68] profile: Add a Sysprof-based profiler (WIP)
- Date: Wed, 12 Sep 2018 11:56:04 +0000 (UTC)
commit e4abb2b7bfc823b3b92fe62ca8f0a722c6e553a2
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Fri Aug 10 17:42:12 2018 -0300
profile: Add a Sysprof-based profiler (WIP)
This exposes the /org/gnome/Sysprof/Capturer object
inside Mutter to allow initiating a Sysprof capture.
The D-Bus interface is still WIP, and needs to be
evaluated by the Sysprof team before this branch can
be accepted.
src/Makefile.am | 14 +++
src/backends/meta-backend.c | 5 +
src/backends/meta-profiler.c | 223 +++++++++++++++++++++++++++++++++++++
src/backends/meta-profiler.h | 43 +++++++
src/org.gnome.Sysprof.Capturer.xml | 15 +++
5 files changed, 300 insertions(+)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 811e2b86b..2ebf973fd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -49,6 +49,7 @@ mutter_built_sources = \
$(dbus_idle_built_sources) \
$(dbus_display_config_built_sources) \
$(dbus_login1_built_sources) \
+ $(dbus_sysprof_capturer_built_sources) \
meta/meta-enum-types.h \
meta-enum-types.c \
$(NULL)
@@ -159,6 +160,8 @@ libmutter_@LIBMUTTER_API_VERSION@_la_SOURCES = \
backends/meta-orientation-manager.h \
backends/meta-output.c \
backends/meta-output.h \
+ backends/meta-profiler.c \
+ backends/meta-profiler.h \
backends/meta-pointer-constraint.c \
backends/meta-pointer-constraint.h \
backends/meta-settings.c \
@@ -682,6 +685,7 @@ EXTRA_DIST += \
org.gnome.Mutter.IdleMonitor.xml \
org.gnome.Mutter.RemoteDesktop.xml \
org.gnome.Mutter.ScreenCast.xml \
+ org.gnome.Sysprof.Capturer.xml \
backends/native/gen-default-modes.py \
$(NULL)
@@ -760,6 +764,16 @@ $(dbus_login1_built_sources) : Makefile.am org.freedesktop.login1.xml
--c-generate-autocleanup all \
$(srcdir)/org.freedesktop.login1.xml
+dbus_sysprof_capturer_built_sources = meta-dbus-sysprof-capturer.c meta-dbus-sysprof-capturer.h
+
+$(dbus_sysprof_capturer_built_sources) : Makefile.am org.gnome.Sysprof.Capturer.xml
+ $(AM_V_GEN)gdbus-codegen \
+ --interface-prefix org.gnome \
+ --c-namespace MetaDBus \
+ --generate-c-code meta-dbus-sysprof-capturer \
+ --c-generate-autocleanup all \
+ $(srcdir)/org.gnome.Sysprof.Capturer.xml
+
backends/native/meta-default-modes.h: backends/native/gen-default-modes.py Makefile.am
@if test -n "$(CVT)"; then \
if $(AM_V_P); then PS4= set -x; else echo " GEN $@"; fi; \
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 6d1c22e65..165be776d 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -50,6 +50,7 @@
#include "backends/meta-idle-monitor-private.h"
#include "backends/meta-logical-monitor.h"
#include "backends/meta-monitor-manager-dummy.h"
+#include "backends/meta-profiler.h"
#include "backends/meta-settings-private.h"
#define META_IDLE_MONITOR_CORE_DEVICE 0
@@ -99,6 +100,7 @@ struct _MetaBackendPrivate
MetaScreenCast *screen_cast;
MetaRemoteDesktop *remote_desktop;
#endif
+ MetaProfiler *profiler;
ClutterBackend *clutter_backend;
ClutterActor *stage;
@@ -163,6 +165,7 @@ meta_backend_finalize (GObject *object)
g_hash_table_destroy (priv->device_monitors);
g_clear_object (&priv->settings);
+ g_clear_object (&priv->profiler);
G_OBJECT_CLASS (meta_backend_parent_class)->finalize (object);
}
@@ -471,6 +474,8 @@ meta_backend_real_post_init (MetaBackend *backend)
reset_pointer_position (backend);
priv->is_pointer_position_initialized = TRUE;
}
+
+ priv->profiler = meta_profiler_new ();
}
static MetaCursorRenderer *
diff --git a/src/backends/meta-profiler.c b/src/backends/meta-profiler.c
new file mode 100644
index 000000000..73f23449e
--- /dev/null
+++ b/src/backends/meta-profiler.c
@@ -0,0 +1,223 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2018 Endless, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include <glib-unix.h>
+#include <gio/gunixfdlist.h>
+
+#include "meta-profiler.h"
+
+#include "cogl/cogl-trace.h"
+
+#define META_SYSPROF_PROFILER_DBUS_PATH "/org/gnome/Sysprof/Profiler"
+
+struct _MetaProfiler
+{
+ MetaDBusSysprofCapturerSkeleton parent_instance;
+
+ GCancellable *cancellable;
+ GDBusConnection *connection;
+
+ guint capture_timeout_id;
+};
+
+static void
+meta_sysprof_capturer_init_iface (MetaDBusSysprofCapturerIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (MetaProfiler,
+ meta_profiler,
+ META_DBUS_TYPE_SYSPROF_CAPTURER_SKELETON,
+ G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SYSPROF_CAPTURER,
+ meta_sysprof_capturer_init_iface))
+
+static gboolean
+on_capture_timeout_cb (gpointer user_data)
+{
+ MetaProfiler *self = META_PROFILER (user_data);
+
+ g_debug ("Stopping profiler");
+
+ cogl_set_tracing_disabled_on_thread (g_main_context_default ());
+
+ self->capture_timeout_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
+static gboolean
+handle_get_capabilities (MetaDBusSysprofCapturer *capturer,
+ GDBusMethodInvocation *invocation)
+{
+ GVariantBuilder builder;
+ GVariant *capabilities;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
+ g_variant_builder_add (&builder, "{sv}", "Name",
+ g_variant_new_string ("Mutter"));
+ g_variant_builder_add (&builder, "{sv}", "Interface-Version",
+ g_variant_new_uint32 (1));
+
+ capabilities = g_variant_builder_end (&builder);
+
+ meta_dbus_sysprof_capturer_complete_get_capabilities (capturer,
+ invocation,
+ capabilities);
+ return TRUE;
+}
+
+static gboolean
+handle_capture (MetaDBusSysprofCapturer *capturer,
+ GDBusMethodInvocation *invocation,
+ GVariant *parameters)
+{
+ MetaProfiler *self = META_PROFILER (capturer);
+ guint timeout = 0;
+
+ g_debug ("Starting profiler");
+
+ g_variant_lookup (parameters, "timeout", "u", &timeout);
+
+ if (timeout == 0)
+ {
+ g_autoptr (GUnixFDList) fd_list = NULL;
+ g_autoptr (GVariant) fd_variant = NULL;
+ g_autoptr (GError) error = NULL;
+ int capture_pipe[2];
+ int fd_index;
+
+ if (!g_unix_open_pipe (capture_pipe, FD_CLOEXEC, &error))
+ {
+ g_critical ("Error opening pipe: %s", error->message);
+
+ g_dbus_method_invocation_return_error (invocation,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Error opening pipe");
+ return TRUE;
+ }
+
+ cogl_set_tracing_enabled_on_thread (g_main_context_default (),
+ capture_pipe[1]);
+
+ fd_list = g_unix_fd_list_new ();
+ fd_index = g_unix_fd_list_append (fd_list, capture_pipe[0], &error);
+ fd_variant = g_variant_new_handle (fd_index);
+
+ close (capture_pipe[0]);
+
+ g_dbus_method_invocation_return_value_with_unix_fd_list (invocation,
+ fd_variant,
+ fd_list);
+ return TRUE;
+ }
+ else if (self->capture_timeout_id == 0)
+ {
+ cogl_set_tracing_enabled_on_thread (g_main_context_default (), -1);
+
+ self->capture_timeout_id =
+ g_timeout_add_seconds (timeout, on_capture_timeout_cb, self);
+
+ g_debug ("Capturing profiling data for %u seconds", timeout);
+ }
+
+ meta_dbus_sysprof_capturer_complete_capture (capturer, invocation,
+ g_variant_new_handle (-1));
+ return TRUE;
+}
+
+static void
+meta_sysprof_capturer_init_iface (MetaDBusSysprofCapturerIface *iface)
+{
+ iface->handle_get_capabilities = handle_get_capabilities;
+ iface->handle_capture = handle_capture;
+}
+
+static void
+on_bus_acquired_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ g_autoptr (GDBusConnection) connection = NULL;
+ GDBusInterfaceSkeleton *interface_skeleton;
+ g_autoptr (GError) error = NULL;
+ MetaProfiler *self;
+
+ connection = g_bus_get_finish (result, &error);
+
+ if (error)
+ {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning ("Failed to get session bus: %s\n", error->message);
+ return;
+ }
+
+ self = META_PROFILER (user_data);
+ interface_skeleton = G_DBUS_INTERFACE_SKELETON (self);
+
+ if (!g_dbus_interface_skeleton_export (interface_skeleton,
+ connection,
+ META_SYSPROF_PROFILER_DBUS_PATH,
+ &error))
+ {
+ g_warning ("Failed to export profiler object: %s\n", error->message);
+ return;
+ }
+
+ self->connection = g_steal_pointer (&connection);
+}
+
+static void
+meta_profiler_finalize (GObject *object)
+{
+ MetaProfiler *self = (MetaProfiler *)object;
+
+ g_cancellable_cancel (self->cancellable);
+
+ g_clear_handle_id (&self->capture_timeout_id, g_source_remove);
+ g_clear_object (&self->cancellable);
+ g_clear_object (&self->connection);
+
+ G_OBJECT_CLASS (meta_profiler_parent_class)->finalize (object);
+}
+
+static void
+meta_profiler_class_init (MetaProfilerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meta_profiler_finalize;
+}
+
+static void
+meta_profiler_init (MetaProfiler *self)
+{
+ self->cancellable = g_cancellable_new ();
+
+ g_bus_get (G_BUS_TYPE_SESSION,
+ self->cancellable,
+ on_bus_acquired_cb,
+ self);
+}
+
+MetaProfiler *
+meta_profiler_new (void)
+{
+ return g_object_new (META_TYPE_PROFILER, NULL);
+}
+
diff --git a/src/backends/meta-profiler.h b/src/backends/meta-profiler.h
new file mode 100644
index 000000000..a94b75826
--- /dev/null
+++ b/src/backends/meta-profiler.h
@@ -0,0 +1,43 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/*
+ * Copyright (C) 2018 Endless, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_PROFILER_H
+#define META_PROFILER_H
+
+#include <glib-object.h>
+
+#include "meta-dbus-sysprof-capturer.h"
+
+G_BEGIN_DECLS
+
+#define META_TYPE_PROFILER (meta_profiler_get_type())
+
+G_DECLARE_FINAL_TYPE (MetaProfiler,
+ meta_profiler,
+ META,
+ PROFILER,
+ MetaDBusSysprofCapturerSkeleton)
+
+MetaProfiler * meta_profiler_new (void);
+
+G_END_DECLS
+
+#endif /* META_PROFILER_H */
diff --git a/src/org.gnome.Sysprof.Capturer.xml b/src/org.gnome.Sysprof.Capturer.xml
new file mode 100644
index 000000000..1754d7dba
--- /dev/null
+++ b/src/org.gnome.Sysprof.Capturer.xml
@@ -0,0 +1,15 @@
+<!DOCTYPE node PUBLIC
+'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'
+'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>
+
+<node>
+ <interface name='org.gnome.Sysprof.Capturer'>
+ <method name="GetCapabilities">
+ <arg type='a{sv}' name='parameters' direction='out'/>
+ </method>
+ <method name="Capture">
+ <arg type='a{sv}' name='parameters' direction='in'/>
+ <arg type='h' name='fd' direction='out'/>
+ </method>
+ </interface>
+</node>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]