summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Watson <davejwatson@fb.com>2019-04-03 08:55:28 -0700
committerGitHub <noreply@github.com>2019-04-03 08:55:28 -0700
commitf2931b349c1d00f8539fc989d32f8ff270e4f7a0 (patch)
tree40b4327dbe27d197aeef262405b99394a568dd61
parent334047a04e59287463348a9e333947b5e59ddd91 (diff)
downloadlibunwind-f2931b349c1d00f8539fc989d32f8ff270e4f7a0.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);