1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-16 21:27:38 +01:00

Bring back support for UNW_CACHE_PER_THREAD.

Needs to be build with --enable-per-thread-cache. Default caching policy
is also UNW_CACHE_PER_THREAD than.
This commit is contained in:
Bert Wesarg 2017-03-27 10:24:26 +02:00 committed by Dave Watson
parent ac1427d87f
commit 57257060c9
21 changed files with 50 additions and 31 deletions

View file

@ -298,7 +298,16 @@ fi
AC_SUBST([LIBLZMA]) AC_SUBST([LIBLZMA])
AM_CONDITIONAL(HAVE_LZMA, test x$enable_minidebuginfo = xyes) AM_CONDITIONAL(HAVE_LZMA, test x$enable_minidebuginfo = xyes)
AC_MSG_CHECKING([whether to support UNW_CACHE_PER_THREAD])
AC_ARG_ENABLE([per-thread-cache],
AS_HELP_STRING([--enable-per-thread-cache], [build with support for UNW_CACHE_PER_THREAD (which imposes a hight TLS memory usage) (default: disabled)]))
AC_MSG_RESULT([$enable_per_thread_cache])
AS_IF([test x$enable_per_thread_cache = xyes], [
LIBUNWIND___THREAD LIBUNWIND___THREAD
AS_IF([test x$libc_cv_gcc___thread = xno], [
AC_MSG_FAILURE([UNW_CACHE_PER_THREAD requires __thread])
])
])
AC_MSG_CHECKING([for Intel compiler]) AC_MSG_CHECKING([for Intel compiler])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[#ifndef __INTEL_COMPILER AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[#ifndef __INTEL_COMPILER

View file

@ -37,13 +37,6 @@ struct elf_dyn_info;
# include "config.h" # include "config.h"
#endif #endif
#ifdef HAVE___THREAD
/* For now, turn off per-thread caching. It uses up too much TLS
memory per thread even when the thread never uses libunwind at
all. */
# undef HAVE___THREAD
#endif
#ifndef UNW_REMOTE_ONLY #ifndef UNW_REMOTE_ONLY
#if defined(HAVE_LINK_H) #if defined(HAVE_LINK_H)
#include <link.h> #include <link.h>

View file

@ -37,11 +37,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "compiler.h" #include "compiler.h"
#ifdef HAVE___THREAD #if defined(HAVE___THREAD) && HAVE___THREAD
/* For now, turn off per-thread caching. It uses up too much TLS #define UNWI_DEFAULT_CACHING_POLICY UNW_CACHE_PER_THREAD
memory per thread even when the thread never uses libunwind at #else
all. */ #define UNWI_DEFAULT_CACHING_POLICY UNW_CACHE_GLOBAL
# undef HAVE___THREAD
#endif #endif
/* Platform-independent libunwind-internal declarations. */ /* Platform-independent libunwind-internal declarations. */

View file

@ -36,10 +36,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "mempool.h" #include "mempool.h"
#include "dwarf.h" #include "dwarf.h"
#ifdef HAVE___THREAD
# undef HAVE___THREAD
#endif
typedef struct typedef struct
{ {
/* no Tilegx-specific fast trace */ /* no Tilegx-specific fast trace */

View file

@ -172,7 +172,7 @@ HIDDEN void
aarch64_local_addr_space_init (void) aarch64_local_addr_space_init (void)
{ {
memset (&local_addr_space, 0, sizeof (local_addr_space)); memset (&local_addr_space, 0, sizeof (local_addr_space));
local_addr_space.caching_policy = UNW_CACHE_GLOBAL; local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY;
local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.put_unwind_info = put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;

View file

@ -220,7 +220,7 @@ HIDDEN void
arm_local_addr_space_init (void) arm_local_addr_space_init (void)
{ {
memset (&local_addr_space, 0, sizeof (local_addr_space)); memset (&local_addr_space, 0, sizeof (local_addr_space));
local_addr_space.caching_policy = UNW_CACHE_GLOBAL; local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY;
local_addr_space.acc.find_proc_info = arm_find_proc_info; local_addr_space.acc.find_proc_info = arm_find_proc_info;
local_addr_space.acc.put_unwind_info = arm_put_unwind_info; local_addr_space.acc.put_unwind_info = arm_put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;

View file

@ -606,7 +606,17 @@ get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp)
if (caching == UNW_CACHE_NONE) if (caching == UNW_CACHE_NONE)
return NULL; return NULL;
#if defined(HAVE___THREAD) && HAVE___THREAD
if (likely (caching == UNW_CACHE_PER_THREAD))
{
static __thread struct dwarf_rs_cache tls_cache __attribute__((tls_model("initial-exec")));
Debug (16, "using TLS cache\n");
cache = &tls_cache;
}
else
#else
if (likely (caching == UNW_CACHE_GLOBAL)) if (likely (caching == UNW_CACHE_GLOBAL))
#endif
{ {
Debug (16, "acquiring lock\n"); Debug (16, "acquiring lock\n");
lock_acquire (&cache->lock, *saved_maskp); lock_acquire (&cache->lock, *saved_maskp);
@ -615,6 +625,8 @@ get_rs_cache (unw_addr_space_t as, intrmask_t *saved_maskp)
if ((atomic_read (&as->cache_generation) != atomic_read (&cache->generation)) if ((atomic_read (&as->cache_generation) != atomic_read (&cache->generation))
|| !cache->hash) || !cache->hash)
{ {
/* cache_size is only set in the global_cache, copy it over before flushing */
cache->log_size = as->global_cache.log_size;
if (dwarf_flush_rs_cache (cache) < 0) if (dwarf_flush_rs_cache (cache) < 0)
return NULL; return NULL;
cache->generation = as->cache_generation; cache->generation = as->cache_generation;

View file

@ -179,7 +179,7 @@ HIDDEN void
hppa_local_addr_space_init (void) hppa_local_addr_space_init (void)
{ {
memset (&local_addr_space, 0, sizeof (local_addr_space)); memset (&local_addr_space, 0, sizeof (local_addr_space));
local_addr_space.caching_policy = UNW_CACHE_GLOBAL; local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY;
local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.put_unwind_info = put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;

View file

@ -361,7 +361,7 @@ ia64_local_addr_space_init (void)
#elif defined(__hpux) #elif defined(__hpux)
local_addr_space.abi = ABI_HPUX; local_addr_space.abi = ABI_HPUX;
#endif #endif
local_addr_space.caching_policy = UNW_CACHE_GLOBAL; local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY;
local_addr_space.acc.find_proc_info = tdep_find_proc_info; local_addr_space.acc.find_proc_info = tdep_find_proc_info;
local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.put_unwind_info = put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;

View file

@ -45,7 +45,7 @@ enum ia64_script_insn_opcode
IA64_INSN_MOVE_SCRATCH_NO_NAT /* like above, but clear NaT info */ IA64_INSN_MOVE_SCRATCH_NO_NAT /* like above, but clear NaT info */
}; };
#ifdef HAVE___THREAD #if defined(HAVE___THREAD) && HAVE___THREAD
static __thread struct ia64_script_cache ia64_per_thread_cache = static __thread struct ia64_script_cache ia64_per_thread_cache =
{ {
#ifdef HAVE_ATOMIC_OPS_H #ifdef HAVE_ATOMIC_OPS_H
@ -105,7 +105,7 @@ get_script_cache (unw_addr_space_t as, intrmask_t *saved_maskp)
if (!spin_trylock_irqsave (&cache->busy, *saved_maskp)) if (!spin_trylock_irqsave (&cache->busy, *saved_maskp))
return NULL; return NULL;
#else #else
# ifdef HAVE___THREAD # if defined(HAVE___THREAD) && HAVE___THREAD
if (as->caching_policy == UNW_CACHE_PER_THREAD) if (as->caching_policy == UNW_CACHE_PER_THREAD)
cache = &ia64_per_thread_cache; cache = &ia64_per_thread_cache;
# endif # endif

View file

@ -38,6 +38,12 @@ unw_set_cache_size (unw_addr_space_t as, size_t size, int flag)
if (flag != 0) if (flag != 0)
return -1; return -1;
/* Currently not supported for per-thread cache due to memory leak */
/* A pthread-key destructor would work, but is not signal safe */
#if defined(HAVE___THREAD) && HAVE___THREAD
return -1;
#endif
/* Round up to next power of two, slowly but portably */ /* Round up to next power of two, slowly but portably */
while(power < size) while(power < size)
{ {

View file

@ -31,7 +31,7 @@ unw_set_caching_policy (unw_addr_space_t as, unw_caching_policy_t policy)
if (!tdep_init_done) if (!tdep_init_done)
tdep_init (); tdep_init ();
#ifndef HAVE___THREAD #if !(defined(HAVE___THREAD) && HAVE___THREAD)
if (policy == UNW_CACHE_PER_THREAD) if (policy == UNW_CACHE_PER_THREAD)
policy = UNW_CACHE_GLOBAL; policy = UNW_CACHE_GLOBAL;
#endif #endif

View file

@ -195,7 +195,7 @@ mips_local_addr_space_init (void)
# error Unsupported ABI # error Unsupported ABI
#endif #endif
local_addr_space.addr_size = sizeof (void *); local_addr_space.addr_size = sizeof (void *);
local_addr_space.caching_policy = UNW_CACHE_GLOBAL; local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY;
local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.put_unwind_info = put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;

View file

@ -201,7 +201,7 @@ HIDDEN void
ppc32_local_addr_space_init (void) ppc32_local_addr_space_init (void)
{ {
memset (&local_addr_space, 0, sizeof (local_addr_space)); memset (&local_addr_space, 0, sizeof (local_addr_space));
local_addr_space.caching_policy = UNW_CACHE_GLOBAL; local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY;
local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.put_unwind_info = put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;

View file

@ -214,7 +214,7 @@ ppc64_local_addr_space_init (void)
#else #else
local_addr_space.abi = UNW_PPC64_ABI_ELFv1; local_addr_space.abi = UNW_PPC64_ABI_ELFv1;
#endif #endif
local_addr_space.caching_policy = UNW_CACHE_GLOBAL; local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY;
local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.put_unwind_info = put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;

View file

@ -171,7 +171,7 @@ HIDDEN void
sh_local_addr_space_init (void) sh_local_addr_space_init (void)
{ {
memset (&local_addr_space, 0, sizeof (local_addr_space)); memset (&local_addr_space, 0, sizeof (local_addr_space));
local_addr_space.caching_policy = UNW_CACHE_GLOBAL; local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY;
local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.put_unwind_info = put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;

View file

@ -152,7 +152,7 @@ tilegx_local_addr_space_init (void)
local_addr_space.abi = UNW_TILEGX_ABI_N64; local_addr_space.abi = UNW_TILEGX_ABI_N64;
local_addr_space.addr_size = sizeof (void *); local_addr_space.addr_size = sizeof (void *);
local_addr_space.caching_policy = UNW_CACHE_GLOBAL; local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY;
local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.put_unwind_info = put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;

View file

@ -228,7 +228,7 @@ HIDDEN void
x86_local_addr_space_init (void) x86_local_addr_space_init (void)
{ {
memset (&local_addr_space, 0, sizeof (local_addr_space)); memset (&local_addr_space, 0, sizeof (local_addr_space));
local_addr_space.caching_policy = UNW_CACHE_GLOBAL; local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY;
local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.put_unwind_info = put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;

View file

@ -273,7 +273,7 @@ HIDDEN void
x86_64_local_addr_space_init (void) x86_64_local_addr_space_init (void)
{ {
memset (&local_addr_space, 0, sizeof (local_addr_space)); memset (&local_addr_space, 0, sizeof (local_addr_space));
local_addr_space.caching_policy = UNW_CACHE_GLOBAL; local_addr_space.caching_policy = UNWI_DEFAULT_CACHING_POLICY;
local_addr_space.acc.find_proc_info = dwarf_find_proc_info; local_addr_space.acc.find_proc_info = dwarf_find_proc_info;
local_addr_space.acc.put_unwind_info = put_unwind_info; local_addr_space.acc.put_unwind_info = put_unwind_info;
local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr; local_addr_space.acc.get_dyn_info_list_addr = get_dyn_info_list_addr;

View file

@ -249,6 +249,8 @@ main (int argc, char **argv)
measure_init (); measure_init ();
doit ("default ");
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE);
doit ("no cache "); doit ("no cache ");

View file

@ -235,6 +235,8 @@ main (int argc, char **argv)
measure_init (); measure_init ();
doit ("default ");
unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE);
doit ("no cache "); doit ("no cache ");