re PR libgcc/71744 (Concurrently throwing exceptions is not scalable)

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.

From-SVN: r240193
This commit is contained in:
Jakub Jelinek 2016-09-16 21:17:47 +02:00 committed by Jakub Jelinek
parent 84c08ec96a
commit 299910482f
2 changed files with 52 additions and 0 deletions

View File

@ -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

View File

@ -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);