diff options
author | Milian Wolff <mail@milianw.de> | 2018-05-04 21:55:52 +0200 |
---|---|---|
committer | Milian Wolff <mail@milianw.de> | 2018-05-07 21:38:19 +0200 |
commit | cd8c5d70d4358aee3dc9fee53e9870d0501cc6db (patch) | |
tree | 75c29c70501c52b61d4aaddf8009d4676a15dae0 /src/x86_64 | |
parent | 3d473e183da99d9965112e45ab43f4d06c01ccab (diff) | |
download | libunwind-cd8c5d70d4358aee3dc9fee53e9870d0501cc6db.tar.gz |
Optionally use a thread-local cache for valid memory
When libunwind is compiled with per-thread-caches, then also
make the cache of valid memory addresses thread-local.
Diffstat (limited to 'src/x86_64')
-rw-r--r-- | src/x86_64/Ginit.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c index 21d8c496..669e9edb 100644 --- a/src/x86_64/Ginit.c +++ b/src/x86_64/Ginit.c @@ -174,8 +174,45 @@ tdep_init_mem_validate (void) } /* Cache of already validated addresses */ -#if HAVE_ATOMIC_OPS_H +#if defined(HAVE___THREAD) && HAVE___THREAD #define NLGA 4 +// thread-local variant +static __thread unw_word_t last_good_addr[NLGA]; +static __thread int lga_victim; + +static int +is_cached_valid_mem(unw_word_t addr) +{ + int i; + for (i = 0; i < NLGA; i++) + { + if (addr == &last_good_addr[i]) + return 1; + } + return 0; +} + +static void +cache_valid_mem(unw_word_t addr) +{ + int i, victim; + victim = lga_victim; + for (i = 0; i < NLGA; i++) { + if (last_good_addr[victim] == 0) { + last_good_addr[victim] = addr; + return; + } + victim = (victim + 1) % NLGA; + } + + /* All slots full. Evict the victim. */ + last_good_addr[victim] = addr; + victim = (victim + 1) % NLGA; + lga_victim = victim; +} + +#elif HAVE_ATOMIC_OPS_H +// global, thread safe variant static AO_T last_good_addr[NLGA]; static AO_T lga_victim; @@ -209,6 +246,7 @@ cache_valid_mem(unw_word_t addr) AO_store(&lga_victim, victim); } #else +// disabled, no cache static int is_cached_valid_mem(unw_word_t addr UNUSED) { |