From 15854645a451f349662f7de7d6dae2fa86c84cd2 Mon Sep 17 00:00:00 2001 From: Kalev Lember Date: May 15 2017 08:54:10 +0000 Subject: Backport a gmain GWakeup patch to fix timedatex high CPU usage https://bugzilla.redhat.com/show_bug.cgi?id=1450628 --- diff --git a/0001-gmain-only-signal-GWakeup-right-before-or-during-a-b.patch b/0001-gmain-only-signal-GWakeup-right-before-or-during-a-b.patch new file mode 100644 index 0000000..400645b --- /dev/null +++ b/0001-gmain-only-signal-GWakeup-right-before-or-during-a-b.patch @@ -0,0 +1,106 @@ +From 5d74233476d61771b4d67d50bec5420f551ef922 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Tue, 4 Apr 2017 09:56:47 +0200 +Subject: [PATCH] gmain: only signal GWakeup right before or during a blocking + poll + +Since commit e4ee307 ("Do not wake up main loop if change is from same +thread", bug 761102), GMainContext uses context->owner to decide if the +event loop is being run in the current thread. However, what really +matters is the phase in the prepare/query/poll/check/dispatch sequence. +Wakeups are only needed between the end of prepare and the end of poll, +and then only if prepare found that no sources were ready. + +There is no need to take threads into account, because prepare, check +and all callers of conditional_wakeup all look at the new need_wakeup +flag inside LOCK_CONTEXT/UNLOCK_CONTEXT. + +With this change, g_main_context_is_owner and g_main_context_wait are +the only functions for which acquire/release matters, just like before +commit e4ee307. + +Signed-off-by: Paolo Bonzini +--- + glib/gmain.c | 30 +++++++++++++++++++----------- + 1 file changed, 19 insertions(+), 11 deletions(-) + +diff --git a/glib/gmain.c b/glib/gmain.c +index ab2908e52..af0a29ae5 100644 +--- a/glib/gmain.c ++++ b/glib/gmain.c +@@ -277,7 +277,8 @@ struct _GMainContext + + guint next_id; + GList *source_lists; +- gint in_check_or_prepare; ++ gboolean in_check_or_prepare; ++ gboolean need_wakeup; + + GPollRec *poll_records; + guint n_poll_records; +@@ -651,6 +652,7 @@ g_main_context_new (void) + + context->pending_dispatches = g_ptr_array_new (); + ++ context->need_wakeup = FALSE; + context->time_is_fresh = FALSE; + + context->wakeup = g_wakeup_new (); +@@ -1127,17 +1129,11 @@ source_remove_from_context (GSource *source, + static void + conditional_wakeup (GMainContext *context) + { +- /* We want to signal wakeups in two cases: +- * 1 When the context is owned by another thread +- * 2 When the context owner is NULL (two subcases) +- * 2a Possible if the context has never been acquired +- * 2b Or if the context has no current owner +- * +- * At least case 2a) is necessary to ensure backwards compatibility with +- * qemu's use of GMainContext. +- * https://bugzilla.gnome.org/show_bug.cgi?id=761102#c14 ++ /* This flag is set if at the start of prepare() we have no other ready ++ * sources, and hence would wait in poll(). In that case, any other threads ++ * attaching sources will need to signal a wakeup. + */ +- if (context->owner != G_THREAD_SELF) ++ if (context->need_wakeup) + g_wakeup_signal (context->wakeup); + } + +@@ -3469,6 +3465,10 @@ g_main_context_prepare (GMainContext *context, + + LOCK_CONTEXT (context); + ++ /* context->need_wakeup is protected by LOCK_CONTEXT/UNLOCK_CONTEXT, ++ * so need not set it yet. ++ */ ++ + context->time_is_fresh = FALSE; + + if (context->in_check_or_prepare) +@@ -3594,6 +3594,8 @@ g_main_context_prepare (GMainContext *context, + } + } + g_source_iter_clear (&iter); ++ /* See conditional_wakeup() where this is used */ ++ context->need_wakeup = (n_ready == 0); + + TRACE (GLIB_MAIN_CONTEXT_AFTER_PREPARE (context, current_priority, n_ready)); + +@@ -3728,6 +3730,12 @@ g_main_context_check (GMainContext *context, + + TRACE (GLIB_MAIN_CONTEXT_BEFORE_CHECK (context, max_priority, fds, n_fds)); + ++ /* We don't need to wakeup during check or dispatch, because ++ * all sources will be re-evaluated during prepare/query. ++ */ ++ context->need_wakeup = FALSE; ++ ++ /* And if we have a wakeup pending, acknowledge it */ + for (i = 0; i < n_fds; i++) + { + if (fds[i].fd == context->wake_up_rec.fd) +-- +2.12.2 + diff --git a/glib2.spec b/glib2.spec index 1efc9ea..9f3dc7c 100644 --- a/glib2.spec +++ b/glib2.spec @@ -5,13 +5,15 @@ Name: glib2 Version: 2.52.2 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A library of handy utility functions License: LGPLv2+ URL: http://www.gtk.org Source0: http://download.gnome.org/sources/glib/2.52/glib-%{version}.tar.xz +Patch0: 0001-gmain-only-signal-GWakeup-right-before-or-during-a-b.patch + BuildRequires: chrpath BuildRequires: gettext BuildRequires: perl-generators @@ -81,6 +83,7 @@ the functionality of the installed glib2 package. %prep %setup -q -n glib-%{version} +%patch0 -p1 %build # Bug 1324770: Also explicitly remove PCRE sources since we use --with-pcre=system @@ -229,6 +232,9 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %{_datadir}/installed-tests %changelog +* Mon May 15 2017 Kalev Lember - 2.52.2-2 +- Backport a gmain GWakeup patch to fix timedatex high CPU usage (#1450628) + * Tue May 09 2017 Kalev Lember - 2.52.2-1 - Update to 2.52.2