[mutter/gbsneto/tracing: 1/7] profile: Add a Sysprof-based profiler
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gbsneto/tracing: 1/7] profile: Add a Sysprof-based profiler
- Date: Wed, 29 May 2019 22:47:15 +0000 (UTC)
commit 98fe69398360a402ea2c42baae12bcb138336842
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Fri Aug 10 17:42:12 2018 -0300
profile: Add a Sysprof-based profiler
This exposes the /org/gnome/Sysprof3/Profiler object
inside Mutter to allow initiating a Sysprof capture.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/197
src/backends/meta-backend.c | 5 ++
src/backends/meta-profiler.c | 193 +++++++++++++++++++++++++++++++++++++++++++
src/backends/meta-profiler.h | 41 +++++++++
src/meson.build | 17 ++++
4 files changed, 256 insertions(+)
---
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 23ab2faec..e6db720f2 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);
}
@@ -841,6 +844,8 @@ meta_backend_initable_init (GInitable *initable,
system_bus_gotten_cb,
backend);
+ priv->profiler = meta_profiler_new ();
+
return TRUE;
}
diff --git a/src/backends/meta-profiler.c b/src/backends/meta-profiler.c
new file mode 100644
index 000000000..112a62519
--- /dev/null
+++ b/src/backends/meta-profiler.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2019 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 "config.h"
+
+#include "src/backends/meta-profiler.h"
+
+#include <glib-unix.h>
+#include <gio/gunixfdlist.h>
+
+#include "cogl/cogl-trace.h"
+
+#define META_SYSPROF_PROFILER_DBUS_PATH "/org/gnome/Sysprof3/Profiler"
+
+struct _MetaProfiler
+{
+ MetaDBusSysprof3ProfilerSkeleton parent_instance;
+
+ GDBusConnection *connection;
+ GCancellable *cancellable;
+
+ gboolean running;
+};
+
+static void
+meta_sysprof_capturer_init_iface (MetaDBusSysprof3ProfilerIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (MetaProfiler,
+ meta_profiler,
+ META_DBUS_TYPE_SYSPROF3_PROFILER_SKELETON,
+ G_IMPLEMENT_INTERFACE (META_DBUS_TYPE_SYSPROF3_PROFILER,
+ meta_sysprof_capturer_init_iface))
+
+static gboolean
+handle_start (MetaDBusSysprof3Profiler *dbus_profiler,
+ GDBusMethodInvocation *invocation,
+ GVariant *options,
+ GVariant *fd_variant)
+{
+ MetaProfiler *profiler = META_PROFILER (dbus_profiler);
+ GMainContext *main_context = g_main_context_default ();
+ GDBusMessage *message;
+ GUnixFDList *fd_list;
+ int position;
+ int fd = -1;
+
+ if (profiler->running)
+ {
+ g_dbus_method_invocation_return_error (invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Profiler already running");
+ return TRUE;
+ }
+
+ g_variant_get (fd_variant, "h", &position);
+
+ message = g_dbus_method_invocation_get_message (invocation);
+ fd_list = g_dbus_message_get_unix_fd_list (message);
+ if (fd_list)
+ fd = g_unix_fd_list_get (fd_list, position, NULL);
+
+ if (fd != -1)
+ cogl_set_tracing_enabled_on_thread_with_fd (main_context, fd);
+ else
+ cogl_set_tracing_enabled_on_thread (main_context, "mutter-profile.syscap");
+
+ profiler->running = TRUE;
+
+ g_debug ("Profiler running");
+
+ meta_dbus_sysprof3_profiler_complete_start (dbus_profiler, invocation);
+ return TRUE;
+}
+
+static gboolean
+handle_stop (MetaDBusSysprof3Profiler *dbus_profiler,
+ GDBusMethodInvocation *invocation)
+{
+ MetaProfiler *profiler = META_PROFILER (dbus_profiler);
+
+ if (!profiler->running)
+ {
+ g_dbus_method_invocation_return_error (invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Profiler not running");
+ return TRUE;
+ }
+
+ cogl_set_tracing_disabled_on_thread (g_main_context_default ());
+ profiler->running = FALSE;
+
+ g_debug ("Stopping profiler");
+
+ meta_dbus_sysprof3_profiler_complete_stop (dbus_profiler, invocation);
+ return TRUE;
+}
+
+static void
+meta_sysprof_capturer_init_iface (MetaDBusSysprof3ProfilerIface *iface)
+{
+ iface->handle_start = handle_start;
+ iface->handle_stop = handle_stop;
+}
+
+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 *profiler;
+
+ 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;
+ }
+
+ profiler = META_PROFILER (user_data);
+ interface_skeleton = G_DBUS_INTERFACE_SKELETON (profiler);
+
+ 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;
+ }
+
+ profiler->connection = g_steal_pointer (&connection);
+}
+
+static void
+meta_profiler_finalize (GObject *object)
+{
+ MetaProfiler *self = (MetaProfiler *)object;
+
+ g_cancellable_cancel (self->cancellable);
+
+ 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..aa0d72640
--- /dev/null
+++ b/src/backends/meta-profiler.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 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-sysprof3-profiler.h"
+
+G_BEGIN_DECLS
+
+#define META_TYPE_PROFILER (meta_profiler_get_type())
+
+G_DECLARE_FINAL_TYPE (MetaProfiler,
+ meta_profiler,
+ META,
+ PROFILER,
+ MetaDBusSysprof3ProfilerSkeleton)
+
+MetaProfiler * meta_profiler_new (void);
+
+G_END_DECLS
+
+#endif /* META_PROFILER_H */
diff --git a/src/meson.build b/src/meson.build
index 5007b5cab..5bb9afc49 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -625,6 +625,23 @@ dbus_idle_monitor_built_sources = gnome.gdbus_codegen('meta-dbus-idle-monitor',
)
mutter_built_sources += dbus_idle_monitor_built_sources
+if have_tracing
+ mutter_sources += [
+ 'backends/meta-profiler.c',
+ 'backends/meta-profiler.h',
+ ]
+
+ dbus_interfaces_dir = join_paths(datadir, 'dbus-1', 'interfaces')
+ sysprof3_dbus_file = join_paths(dbus_interfaces_dir, 'org.gnome.Sysprof3.Profiler.xml')
+
+ dbus_sysprof3_profiler_built_sources = gnome.gdbus_codegen('meta-dbus-sysprof3-profiler',
+ sysprof3_dbus_file,
+ interface_prefix: 'org.gnome.',
+ namespace: 'MetaDBus',
+ )
+ mutter_built_sources += dbus_sysprof3_profiler_built_sources
+endif
+
if have_native_backend
cvt = find_program('cvt')
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]