summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Watson <davejwatson@fb.com>2019-04-03 08:55:28 -0700
committerDave Watson <davejwatson@fb.com>2019-04-03 09:04:22 -0700
commit4ac3bbd869357c4e61ae849d3b0a5c6861f92471 (patch)
tree4e64b1b888c2aa5c1a09ecb8e8194c18cdf6f5ca
parent5ea02ede42b336fe6e9a5bfe5565d49d622d3914 (diff)
downloadlibunwind-4ac3bbd869357c4e61ae849d3b0a5c6861f92471.tar.gz
Tsan (#109)
x86_64: tsan clean
-rw-r--r--include/libunwind_i.h5
-rw-r--r--src/x86_64/Gglobal.c17
-rw-r--r--src/x86_64/Ginit_local.c2
-rw-r--r--src/x86_64/Ginit_remote.c2
4 files changed, 17 insertions, 9 deletions
diff --git a/include/libunwind_i.h b/include/libunwind_i.h
index 36cf7a14..e0f45401 100644
--- a/include/libunwind_i.h
+++ b/include/libunwind_i.h
@@ -140,6 +140,7 @@ cmpxchg_ptr (void *addr, void *old, void *new)
}
# define fetch_and_add1(_ptr) AO_fetch_and_add1(_ptr)
# define fetch_and_add(_ptr, value) AO_fetch_and_add(_ptr, value)
+# define atomic_read(ptr) (AO_load(ptr))
/* GCC 3.2.0 on HP-UX crashes on cmpxchg_ptr() */
# if !(defined(__hpux) && __GNUC__ == 3 && __GNUC_MINOR__ == 2)
# define HAVE_CMPXCHG
@@ -164,10 +165,14 @@ cmpxchg_ptr (void *addr, void *old, void *new)
}
# define fetch_and_add1(_ptr) __sync_fetch_and_add(_ptr, 1)
# define fetch_and_add(_ptr, value) __sync_fetch_and_add(_ptr, value)
+# define atomic_read(ptr) (__atomic_load_n(ptr,__ATOMIC_RELAXED))
# define HAVE_CMPXCHG
# define HAVE_FETCH_AND_ADD
#endif
+
+#ifndef atomic_read
#define atomic_read(ptr) (*(ptr))
+#endif
#define UNWI_OBJ(fn) UNW_PASTE(UNW_PREFIX,UNW_PASTE(I,fn))
#define UNWI_ARCH_OBJ(fn) UNW_PASTE(UNW_PASTE(UNW_PASTE(_UI,UNW_TARGET),_), fn)
diff --git a/src/x86_64/Gglobal.c b/src/x86_64/Gglobal.c
index 8d1fbb4b..d0560582 100644
--- a/src/x86_64/Gglobal.c
+++ b/src/x86_64/Gglobal.c
@@ -30,7 +30,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
#include "dwarf_i.h"
HIDDEN define_lock (x86_64_lock);
-HIDDEN int tdep_init_done;
+HIDDEN sig_atomic_t tdep_init_done;
/* See comments for svr4_dbx_register_map[] in gcc/config/i386/i386.c. */
@@ -77,15 +77,17 @@ HIDDEN void
tdep_init (void)
{
intrmask_t saved_mask;
+ intrmask_t full_mask;
+ sigfillset (&full_mask);
- sigfillset (&unwi_full_mask);
-
- lock_acquire (&x86_64_lock, saved_mask);
+ SIGPROCMASK (SIG_SETMASK, &full_mask, &saved_mask);
+ mutex_lock (&x86_64_lock);
{
- if (tdep_init_done)
+ if (atomic_read(&tdep_init_done))
/* another thread else beat us to it... */
goto out;
+ sigfillset (&unwi_full_mask);
mi_init ();
dwarf_init ();
@@ -95,8 +97,9 @@ tdep_init (void)
#ifndef UNW_REMOTE_ONLY
x86_64_local_addr_space_init ();
#endif
- tdep_init_done = 1; /* signal that we're initialized... */
+ fetch_and_add1(&tdep_init_done); /* signal that we're initialized... */
}
out:
- lock_release (&x86_64_lock, saved_mask);
+ mutex_unlock(&x86_64_lock);
+ SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);
}
diff --git a/src/x86_64/Ginit_local.c b/src/x86_64/Ginit_local.c
index 5eaead0f..12a9e3e4 100644
--- a/src/x86_64/Ginit_local.c
+++ b/src/x86_64/Ginit_local.c
@@ -43,7 +43,7 @@ unw_init_local_common (unw_cursor_t *cursor, ucontext_t *uc, unsigned use_prev_i
{
struct cursor *c = (struct cursor *) cursor;
- if (unlikely (!tdep_init_done))
+ if (unlikely (!atomic_read(&tdep_init_done)))
tdep_init ();
Debug (1, "(cursor=%p)\n", c);
diff --git a/src/x86_64/Ginit_remote.c b/src/x86_64/Ginit_remote.c
index efd61d64..f411b233 100644
--- a/src/x86_64/Ginit_remote.c
+++ b/src/x86_64/Ginit_remote.c
@@ -36,7 +36,7 @@ unw_init_remote (unw_cursor_t *cursor, unw_addr_space_t as, void *as_arg)
#else /* !UNW_LOCAL_ONLY */
struct cursor *c = (struct cursor *) cursor;
- if (!tdep_init_done)
+ if (!atomic_read(&tdep_init_done))
tdep_init ();
Debug (1, "(cursor=%p)\n", c);