diff options
author | Christian Hergert <chergert@redhat.com> | 2023-02-21 14:30:58 -0800 |
---|---|---|
committer | Christian Hergert <chergert@redhat.com> | 2023-02-21 14:30:58 -0800 |
commit | df80f432f0f9cdeb161b01bb5abd5aac4743509a (patch) | |
tree | 95e514e0a1a1fec358f5808c1d6136403180fe8c | |
parent | 378f1421f0a290d753eea672fb49a2545c3788c8 (diff) | |
download | gtk+-wip/chergert/profiler-stack.tar.gz |
-rw-r--r-- | gdk/backtrace-helper.h | 81 | ||||
-rw-r--r-- | gdk/gdkprofiler.c | 19 | ||||
-rw-r--r-- | gdk/gdkprofilerprivate.h | 4 | ||||
-rw-r--r-- | gtk/gtkrange.c | 34 | ||||
-rw-r--r-- | meson.build | 1 |
5 files changed, 124 insertions, 15 deletions
diff --git a/gdk/backtrace-helper.h b/gdk/backtrace-helper.h new file mode 100644 index 0000000000..04e5263550 --- /dev/null +++ b/gdk/backtrace-helper.h @@ -0,0 +1,81 @@ +/* backtrace-helper.h + * + * Copyright 2020-2023 Christian Hergert <chergert@redhat.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#pragma once + +#include <sysprof-capture.h> + +#ifdef HAVE_EXECINFO_H +# include <execinfo.h> +#endif +#ifdef ENABLE_LIBUNWIND +# define UNW_LOCAL_ONLY +# include <libunwind.h> +#endif + +static void +backtrace_init (void) +{ +#ifdef ENABLE_LIBUNWIND + unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); +# ifdef HAVE_UNW_SET_CACHE_SIZE + unw_set_cache_size (unw_local_addr_space, 1024, 0); +#endif +#endif +} + +static int +backtrace_func (SysprofCaptureAddress *addrs, + guint n_addrs, + G_GNUC_UNUSED gpointer user_data) +{ +#if defined(ENABLE_LIBUNWIND) +# if GLIB_SIZEOF_VOID_P == 8 + /* We know that collector will overwrite fields *AFTER* it + * has called the backtrace function allowing us to cheat + * and subtract an offset from addrs to avoid having to + * copy frame pointers around. + */ + return unw_backtrace ((void **)addrs - 2, n_addrs) - 2; +# else + static const int skip = 2; + void **stack = alloca (n_addrs * sizeof (gpointer)); + int n = unw_backtrace (stack, n_addrs); + for (guint i = skip; i < n; i++) + addrs[i-skip] = GPOINTER_TO_SIZE (stack[i]); + return MAX (0, n - skip); +# endif +#elif defined(HAVE_EXECINFO_H) +# if GLIB_SIZEOF_VOID_P == 8 + /* See note on unw_backtrace() */ + return backtrace ((void **)addrs - 2, n_addrs) - 2; +# else /* GLIB_SIZEOF_VOID_P != 8 */ + static const int skip = 2; + void **stack = alloca (n_addrs * sizeof (gpointer)); + int n = backtrace (stack, n_addrs); + for (guint i = skip; i < n; i++) + addrs[i-skip] = GPOINTER_TO_SIZE (stack[i]); + return MAX (0, n - skip); +# endif /* GLIB_SIZEOF_VOID_P */ +#else + return 0; +#endif +} + diff --git a/gdk/gdkprofiler.c b/gdk/gdkprofiler.c index b51cd7eb37..015fd9957d 100644 --- a/gdk/gdkprofiler.c +++ b/gdk/gdkprofiler.c @@ -32,6 +32,9 @@ #include "gdkversionmacros.h" #include "gdkframeclockprivate.h" +#ifdef HAVE_SYSPROF +# include "backtrace-helper.h" +#endif gboolean gdk_profiler_is_running (void) @@ -160,3 +163,19 @@ void sysprof_collector_set_counters (&id, &value, 1); #endif } + +void +(gdk_profiler_add_stacktrace) (void) +{ +#ifdef HAVE_SYSPROF + static gsize did_init; + + if (!did_init) + { + did_init = TRUE; + backtrace_init (); + } + + sysprof_collector_sample (backtrace_func, NULL); +#endif +} diff --git a/gdk/gdkprofilerprivate.h b/gdk/gdkprofilerprivate.h index 897f4f804e..96fb26531c 100644 --- a/gdk/gdkprofilerprivate.h +++ b/gdk/gdkprofilerprivate.h @@ -63,6 +63,8 @@ void gdk_profiler_end_markf (gint64 begin_time, const gchar *message_format, ...) G_GNUC_PRINTF (3, 4); +void gdk_profiler_add_stacktrace (void); + guint gdk_profiler_define_counter (const char *name, const char *description); guint gdk_profiler_define_int_counter (const char *name, @@ -86,6 +88,8 @@ void gdk_profiler_set_int_counter (guint id, /* no varargs macro support; the call will have to be optimised out by the compiler */ #endif +#define gdk_profiler_add_stacktrace() G_STMT_START {} G_STMT_END + #define gdk_profiler_define_counter(n, d) 0 #define gdk_profiler_define_int_counter(n, d) 0 #define gdk_profiler_set_counter(i, v) G_STMT_START {} G_STMT_END diff --git a/gtk/gtkrange.c b/gtk/gtkrange.c index ebe4cb706b..9876ea1966 100644 --- a/gtk/gtkrange.c +++ b/gtk/gtkrange.c @@ -20,13 +20,15 @@ * Modified by the GTK+ Team and others 1997-2004. See the AUTHORS * file for a list of people on the GTK+ Team. See the ChangeLog * files for a list of changes. These files are distributed with - * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */ #include "config.h" #include "gtkrangeprivate.h" +#include "gdkprofilerprivate.h" + #include "gtkaccessible.h" #include "gtkaccessiblerange.h" #include "gtkadjustmentprivate.h" @@ -688,7 +690,7 @@ gtk_range_set_adjustment (GtkRange *range, priv->adjustment = adjustment; g_object_ref_sink (adjustment); - + g_signal_connect (adjustment, "changed", G_CALLBACK (gtk_range_adjustment_changed), range); @@ -1069,7 +1071,7 @@ gtk_range_set_range (GtkRange *range, GtkRangePrivate *priv = gtk_range_get_instance_private (range); GtkAdjustment *adjustment; double value; - + g_return_if_fail (GTK_IS_RANGE (range)); g_return_if_fail (min <= max); @@ -1548,7 +1550,7 @@ clamp_dimensions (int range_width, *width += extra; } } - + /* See if we can fit rect, if not kill the border */ shortage = *width - range_width; if (shortage > 0) @@ -1585,7 +1587,7 @@ clamp_dimensions (int range_width, border->bottom += extra / 2 + extra % 2; } } - + /* See if we can fit rect, if not kill the border */ shortage = *height - range_height; if (shortage > 0) @@ -2348,6 +2350,8 @@ gtk_range_adjustment_changed (GtkAdjustment *adjustment, double upper = gtk_adjustment_get_upper (priv->adjustment); double lower = gtk_adjustment_get_lower (priv->adjustment); + gdk_profiler_add_stacktrace (); + gtk_widget_set_visible (priv->slider_widget, upper != lower || !GTK_IS_SCALE (range)); gtk_widget_queue_allocate (priv->trough_widget); @@ -2391,7 +2395,7 @@ gtk_range_adjustment_value_changed (GtkAdjustment *adjustment, } static void -apply_marks (GtkRange *range, +apply_marks (GtkRange *range, double oldval, double *newval) { @@ -2502,7 +2506,7 @@ gtk_range_scroll (GtkRange *range, else step_back (range); break; - + case GTK_SCROLL_STEP_UP: if (should_invert_move (range, GTK_ORIENTATION_VERTICAL)) step_forward (range); @@ -2516,18 +2520,18 @@ gtk_range_scroll (GtkRange *range, else step_forward (range); break; - + case GTK_SCROLL_STEP_DOWN: if (should_invert_move (range, GTK_ORIENTATION_VERTICAL)) step_back (range); else step_forward (range); break; - + case GTK_SCROLL_STEP_BACKWARD: step_back (range); break; - + case GTK_SCROLL_STEP_FORWARD: step_forward (range); break; @@ -2538,7 +2542,7 @@ gtk_range_scroll (GtkRange *range, else page_back (range); break; - + case GTK_SCROLL_PAGE_UP: if (should_invert_move (range, GTK_ORIENTATION_VERTICAL)) page_forward (range); @@ -2552,18 +2556,18 @@ gtk_range_scroll (GtkRange *range, else page_forward (range); break; - + case GTK_SCROLL_PAGE_DOWN: if (should_invert_move (range, GTK_ORIENTATION_VERTICAL)) page_back (range); else page_forward (range); break; - + case GTK_SCROLL_PAGE_BACKWARD: page_back (range); break; - + case GTK_SCROLL_PAGE_FORWARD: page_forward (range); break; @@ -2853,7 +2857,7 @@ _gtk_range_set_stop_values (GtkRange *range, priv->n_marks = n_values; - for (i = 0; i < n_values; i++) + for (i = 0; i < n_values; i++) priv->marks[i] = values[i]; gtk_range_calc_marks (range); diff --git a/meson.build b/meson.build index 81c5a459eb..e7254d329c 100644 --- a/meson.build +++ b/meson.build @@ -156,6 +156,7 @@ check_headers = [ 'crt/externs.h', 'dev/evdev/input.h', 'dlfcn.h', + 'execinfo.h', 'ftw.h', 'inttypes.h', 'linux/input.h', |