libunwind/Optionally-use-a-thread-local-cache-for-valid-memory.patch
2019-09-30 10:58:37 -04:00

74 lines
1.7 KiB
Diff

From cd8c5d70d4358aee3dc9fee53e9870d0501cc6db Mon Sep 17 00:00:00 2001
From: Milian Wolff <mail@milianw.de>
Date: Fri, 4 May 2018 21:55:52 +0200
Subject: [PATCH 23/50] 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.
---
src/x86_64/Ginit.c | 40 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/src/x86_64/Ginit.c b/src/x86_64/Ginit.c
index 21d8c49..669e9ed 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)
{
--
1.8.3.1