public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Thomas Neumann <thomas.neumann@in.tum.de>
To: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>
Cc: "H.J. Lu" <hjl.tools@gmail.com>, Jakub Jelinek <jakub@redhat.com>,
	Tamar Christina <Tamar.Christina@arm.com>,
	Jason Merrill <jason@redhat.com>,
	Jonathan Wakely <jwakely.gcc@gmail.com>,
	Florian Weimer <fweimer@redhat.com>
Subject: [PATCH] initialize fde objects lazily
Date: Fri, 9 Dec 2022 18:34:18 +0100	[thread overview]
Message-ID: <7d18f085-ae46-138d-4f04-df5857b7b014@in.tum.de> (raw)
In-Reply-To: <87sfibqu1s.fsf@oldenburg.str.redhat.com>

When registering an unwind frame with __register_frame_info_bases
we currently initialize that fde object eagerly. This has the
advantage that it is immutable afterwards and we can safely
access it from multiple threads, but it has the disadvantage
that we pay the initialization cost even if the application
never throws an exception.

This commit changes the logic to initialize the objects lazily.
The objects themselves are inserted into the b-tree when
registering the frame, but the sorted fde_vector is
not constructed yet. Only on the first time that an
exception tries to pass through the registered code the
object is initialized. We notice that with a double checking,
first doing a relaxed load of the sorted bit and then re-checking
under a mutex when the object was not initialized yet.

Note that the check must implicitly be safe concering a concurrent
frame deregistration, as trying the deregister a frame that is
on the unwinding path of a concurrent exception is inherently racy.

libgcc/ChangeLog:
         * unwind-dw2-fde.c: Initialize fde object lazily when
         the first exception tries to pass through.
---
  libgcc/unwind-dw2-fde.c | 52 ++++++++++++++++++++++++++++++++---------
  1 file changed, 41 insertions(+), 11 deletions(-)

diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
index 3c0cc654ec0..6f69c20ff4b 100644
--- a/libgcc/unwind-dw2-fde.c
+++ b/libgcc/unwind-dw2-fde.c
@@ -63,8 +63,6 @@ release_registered_frames (void)
  
  static void
  get_pc_range (const struct object *ob, uintptr_type *range);
-static void
-init_object (struct object *ob);
  
  #else
  /* Without fast path frame deregistration must always succeed.  */
@@ -76,6 +74,7 @@ static const int in_shutdown = 0;
     by decreasing value of pc_begin.  */
  static struct object *unseen_objects;
  static struct object *seen_objects;
+#endif
  
  #ifdef __GTHREAD_MUTEX_INIT
  static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
@@ -103,7 +102,6 @@ init_object_mutex_once (void)
  static __gthread_mutex_t object_mutex;
  #endif
  #endif
-#endif
  
  /* Called from crtbegin.o to register the unwind info for an object.  */
  
@@ -126,10 +124,7 @@ __register_frame_info_bases (const void *begin, struct object *ob,
  #endif
  
  #ifdef ATOMIC_FDE_FAST_PATH
-  // Initialize eagerly to avoid locking later
-  init_object (ob);
-
-  // And register the frame
+  // Register the frame in the b-tree
    uintptr_type range[2];
    get_pc_range (ob, range);
    btree_insert (&registered_frames, range[0], range[1] - range[0], ob);
@@ -180,10 +175,7 @@ __register_frame_info_table_bases (void *begin, struct object *ob,
    ob->s.b.encoding = DW_EH_PE_omit;
  
  #ifdef ATOMIC_FDE_FAST_PATH
-  // Initialize eagerly to avoid locking later
-  init_object (ob);
-
-  // And register the frame
+  // Register the frame in the b-tree
    uintptr_type range[2];
    get_pc_range (ob, range);
    btree_insert (&registered_frames, range[0], range[1] - range[0], ob);
@@ -892,7 +884,15 @@ init_object (struct object* ob)
    accu.linear->orig_data = ob->u.single;
    ob->u.sort = accu.linear;
  
+#ifdef ATOMIC_FDE_FAST_PATH
+  // We must update the sorted bit with an atomic operation
+  struct object tmp;
+  tmp.s.b = ob->s.b;
+  tmp.s.b.sorted = 1;
+  __atomic_store (&(ob->s.b), &(tmp.s.b), __ATOMIC_SEQ_CST);
+#else
    ob->s.b.sorted = 1;
+#endif
  }
  
  #ifdef ATOMIC_FDE_FAST_PATH
@@ -1130,6 +1130,21 @@ search_object (struct object* ob, void *pc)
      }
  }
  
+#ifdef ATOMIC_FDE_FAST_PATH
+
+// Check if the object was already initialized
+static inline bool
+is_object_initialized (struct object *ob)
+{
+  // We have to use relaxed atomics for the read, which
+  // is a bit involved as we read from a bitfield
+  struct object tmp;
+  __atomic_load (&(ob->s.b), &(tmp.s.b), __ATOMIC_RELAXED);
+  return tmp.s.b.sorted;
+}
+
+#endif
+
  const fde *
  _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
  {
@@ -1141,6 +1156,21 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
    if (!ob)
      return NULL;
  
+  // Initialize the object lazily
+  if (!is_object_initialized (ob))
+    {
+      // Check again under mutex
+      init_object_mutex_once ();
+      __gthread_mutex_lock (&object_mutex);
+
+      if (!ob->s.b.sorted)
+	{
+	  init_object (ob);
+	}
+
+      __gthread_mutex_unlock (&object_mutex);
+    }
+
    f = search_object (ob, pc);
  #else
  
-- 
2.37.2


  parent reply	other threads:[~2022-12-09 17:34 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-16 10:19 [PATCH v4] eliminate mutex in fast path of __register_frame Thomas Neumann
2022-09-16 14:49 ` Jason Merrill
2022-09-18  8:59 ` Dimitar Dimitrov
2022-09-18  9:20   ` Thomas Neumann
2022-09-18 10:02   ` Thomas Neumann
2022-09-19 13:46 ` Stephan Bergmann
2022-09-19 13:55   ` Thomas Neumann
2022-09-19 14:00     ` Stephan Bergmann
2022-09-19 15:33   ` Thomas Neumann
2022-09-20  5:39     ` Stephan Bergmann
2022-11-21 11:14 ` Tamar Christina
2022-11-21 11:22   ` Thomas Neumann
2022-11-21 11:48     ` Jakub Jelinek
2022-11-21 17:13       ` H.J. Lu
2022-11-22  0:31         ` Thomas Neumann
2022-11-22  8:20           ` Florian Weimer
2022-11-22  9:12             ` Thomas Neumann
2022-12-09 17:34             ` Thomas Neumann [this message]
2022-12-15 16:11               ` [PATCH] initialize fde objects lazily Tamar Christina
2022-12-16 17:25               ` Jason Merrill
2023-05-02 14:32             ` [PATCH] release the sorted FDE array when deregistering a frame [PR109685] Thomas Neumann
2023-05-10 10:49             ` [PATCH] fix radix sort on 32bit platforms [PR109670] Thomas Neumann
2023-08-10 11:33             ` [PATCH] preserve base pointer for __deregister_frame [PR110956] Thomas Neumann
2023-08-11 15:21               ` Jeff Law
2024-03-15 10:29             ` [PATCH] handle unwind tables that are embedded within unwinding code, [PR111731] Thomas Neumann
2024-03-20  8:25               ` Richard Biener
2024-03-22 13:35               ` Jeff Law
2024-03-22 13:36               ` Jeff Law
2024-03-22 14:43                 ` Thomas Neumann
2022-11-22  8:00         ` [PATCH] speed up end_fde_sort using radix sort Thomas Neumann
2022-12-16 18:02           ` Jason Merrill
2022-11-21 11:49     ` [PATCH v4] eliminate mutex in fast path of __register_frame Tamar Christina
2022-11-21 11:53       ` Thomas Neumann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7d18f085-ae46-138d-4f04-df5857b7b014@in.tum.de \
    --to=thomas.neumann@in.tum.de \
    --cc=Tamar.Christina@arm.com \
    --cc=fweimer@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=hjl.tools@gmail.com \
    --cc=jakub@redhat.com \
    --cc=jason@redhat.com \
    --cc=jwakely.gcc@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).