diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-09-16 19:17:47 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-09-16 19:17:47 +0000 |
commit | 69ea99083f1e327672b01b223939f3b93fd20eb0 (patch) | |
tree | 66a335c06c85833590a8c8c17b8332a42d78e963 | |
parent | 29ff19b82569254ede5eb8c6134863d2e059fca4 (diff) | |
download | gcc-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/ChangeLog | 11 | ||||
-rw-r--r-- | libgcc/unwind-dw2-fde.c | 41 |
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); |