summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-16 19:17:47 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2016-09-16 19:17:47 +0000
commit69ea99083f1e327672b01b223939f3b93fd20eb0 (patch)
tree66a335c06c85833590a8c8c17b8332a42d78e963
parent29ff19b82569254ede5eb8c6134863d2e059fca4 (diff)
downloadgcc-69ea99083f1e327672b01b223939f3b93fd20eb0.tar.gz
PR libgcc/71744
* unwind-dw2-fde.c (ATOMIC_FDE_FAST_PATH): Define if __register_frame* is not the primary registry and atomics are available. (any_objects_registered): New variable. (__register_frame_info_bases, __register_frame_info_table_bases): Atomically store 1 to any_objects_registered after registering first unwind info. (_Unwind_Find_FDE): Return early if any_objects_registered is 0. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@240193 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libgcc/ChangeLog11
-rw-r--r--libgcc/unwind-dw2-fde.c41
2 files changed, 52 insertions, 0 deletions
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 73e3a4f6d6f..b5c7ea4a9af 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,14 @@
+2016-09-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR libgcc/71744
+ * unwind-dw2-fde.c (ATOMIC_FDE_FAST_PATH): Define if __register_frame*
+ is not the primary registry and atomics are available.
+ (any_objects_registered): New variable.
+ (__register_frame_info_bases, __register_frame_info_table_bases):
+ Atomically store 1 to any_objects_registered after registering first
+ unwind info.
+ (_Unwind_Find_FDE): Return early if any_objects_registered is 0.
+
2016-09-09 James Greenhalgh <james.greenhalgh@arm.com>
PR target/63250
diff --git a/libgcc/unwind-dw2-fde.c b/libgcc/unwind-dw2-fde.c
index 5b16a1f87e2..be82f65b916 100644
--- a/libgcc/unwind-dw2-fde.c
+++ b/libgcc/unwind-dw2-fde.c
@@ -35,6 +35,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include "unwind-pe.h"
#include "unwind-dw2-fde.h"
#include "gthr.h"
+#else
+#if (defined(__GTHREAD_MUTEX_INIT) || defined(__GTHREAD_MUTEX_INIT_FUNCTION)) \
+ && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+#define ATOMIC_FDE_FAST_PATH 1
+#endif
#endif
/* The unseen_objects list contains objects that have been registered
@@ -43,6 +48,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
by decreasing value of pc_begin. */
static struct object *unseen_objects;
static struct object *seen_objects;
+#ifdef ATOMIC_FDE_FAST_PATH
+static int any_objects_registered;
+#endif
#ifdef __GTHREAD_MUTEX_INIT
static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT;
@@ -96,6 +104,16 @@ __register_frame_info_bases (const void *begin, struct object *ob,
ob->next = unseen_objects;
unseen_objects = ob;
+#ifdef ATOMIC_FDE_FAST_PATH
+ /* Set flag that at least one library has registered FDEs.
+ Use relaxed MO here, it is up to the app to ensure that the library
+ loading/initialization happens-before using that library in other
+ threads (in particular unwinding with that library's functions
+ appearing in the backtraces). Calling that library's functions
+ without waiting for the library to initialize would be racy. */
+ if (!any_objects_registered)
+ __atomic_store_n (&any_objects_registered, 1, __ATOMIC_RELAXED);
+#endif
__gthread_mutex_unlock (&object_mutex);
}
@@ -140,6 +158,16 @@ __register_frame_info_table_bases (void *begin, struct object *ob,
ob->next = unseen_objects;
unseen_objects = ob;
+#ifdef ATOMIC_FDE_FAST_PATH
+ /* Set flag that at least one library has registered FDEs.
+ Use relaxed MO here, it is up to the app to ensure that the library
+ loading/initialization happens-before using that library in other
+ threads (in particular unwinding with that library's functions
+ appearing in the backtraces). Calling that library's functions
+ without waiting for the library to initialize would be racy. */
+ if (!any_objects_registered)
+ __atomic_store_n (&any_objects_registered, 1, __ATOMIC_RELAXED);
+#endif
__gthread_mutex_unlock (&object_mutex);
}
@@ -1001,6 +1029,19 @@ _Unwind_Find_FDE (void *pc, struct dwarf_eh_bases *bases)
struct object *ob;
const fde *f = NULL;
+#ifdef ATOMIC_FDE_FAST_PATH
+ /* For targets where unwind info is usually not registered through these
+ APIs anymore, avoid taking a global lock.
+ Use relaxed MO here, it is up to the app to ensure that the library
+ loading/initialization happens-before using that library in other
+ threads (in particular unwinding with that library's functions
+ appearing in the backtraces). Calling that library's functions
+ without waiting for the library to initialize would be racy. */
+ if (__builtin_expect (!__atomic_load_n (&any_objects_registered,
+ __ATOMIC_RELAXED), 1))
+ return NULL;
+#endif
+
init_object_mutex_once ();
__gthread_mutex_lock (&object_mutex);