[mutter/gbsneto/tracing: 659/662] 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: 659/662] profile: Add a Sysprof-based profiler (WIP)
- Date: Fri, 12 Apr 2019 18:14:32 +0000 (UTC)
commit e61bafc600a168db5feafb8d8b134567d16403dc
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/backends/meta-backend.c | 5 +
src/backends/meta-profiler.c | 223 +++++++++++++++++++++++++++++++++++++
src/backends/meta-profiler.h | 43 +++++++
src/meson.build | 9 ++
src/org.gnome.Sysprof.Capturer.xml | 15 +++
5 files changed, 295 insertions(+)
---
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 23ab2faec..41df968e6 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -64,6 +64,7 @@
#include "clutter/clutter-mutter.h"
#include "meta/main.h"
#include "meta/meta-backend.h"
+#include "backends/meta-profiler.h"
#include "meta/util.h"
#ifdef HAVE_REMOTE_DESKTOP
@@ -126,6 +127,7 @@ struct _MetaBackendPrivate
MetaScreenCast *screen_cast;
MetaRemoteDesktop *remote_desktop;
#endif
+ MetaProfiler *profiler;
ClutterBackend *clutter_backend;
ClutterActor *stage;
@@ -192,6 +194,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);
}
@@ -514,6 +517,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/meson.build b/src/meson.build
index 9919b5cfb..da93d409e 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -212,6 +212,8 @@ mutter_sources = [
'backends/meta-output.h',
'backends/meta-pointer-constraint.c',
'backends/meta-pointer-constraint.h',
+ 'backends/meta-profiler.c',
+ 'backends/meta-profiler.h',
'backends/meta-remote-access-controller-private.h',
'backends/meta-remote-access-controller.c',
'backends/meta-renderer.c',
@@ -604,6 +606,13 @@ dbus_idle_monitor_built_sources = gnome.gdbus_codegen('meta-dbus-idle-monitor',
)
mutter_built_sources += dbus_idle_monitor_built_sources
+dbus_sysprof_capturer_built_sources = gnome.gdbus_codegen('meta-dbus-sysprof-capturer',
+ 'org.gnome.Sysprof.Capturer.xml',
+ interface_prefix: 'org.gnome.',
+ namespace: 'MetaDBus',
+ )
+mutter_built_sources += dbus_sysprof_capturer_built_sources
+
if have_native_backend
cvt = find_program('cvt')
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]