aboutsummaryrefslogtreecommitdiff
path: root/libsanitizer/tsan
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2012-12-06 14:43:11 +0000
committerKostya Serebryany <kcc@gcc.gnu.org>2012-12-06 14:43:11 +0000
commit695edbac5c1b02ac162a301d6886dc073b0361fb (patch)
tree1f745ce7339c78271d4e10927b85f87464a29e01 /libsanitizer/tsan
parentc8211767c5f4e6bcce383122cddcbe812b871182 (diff)
downloadgcc-695edbac5c1b02ac162a301d6886dc073b0361fb.zip
gcc-695edbac5c1b02ac162a301d6886dc073b0361fb.tar.gz
gcc-695edbac5c1b02ac162a301d6886dc073b0361fb.tar.bz2
[libsanitizer] merge from upstream r169392
From-SVN: r194255
Diffstat (limited to 'libsanitizer/tsan')
-rw-r--r--libsanitizer/tsan/tsan_interceptors.cc37
-rw-r--r--libsanitizer/tsan/tsan_interface_atomic.cc8
-rw-r--r--libsanitizer/tsan/tsan_stat.cc1
-rw-r--r--libsanitizer/tsan/tsan_stat.h1
4 files changed, 31 insertions, 16 deletions
diff --git a/libsanitizer/tsan/tsan_interceptors.cc b/libsanitizer/tsan/tsan_interceptors.cc
index 0463fbd4..dea6415 100644
--- a/libsanitizer/tsan/tsan_interceptors.cc
+++ b/libsanitizer/tsan/tsan_interceptors.cc
@@ -617,21 +617,31 @@ TSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) {
}
// Used in thread-safe function static initialization.
-TSAN_INTERCEPTOR(int, __cxa_guard_acquire, char *m) {
- SCOPED_TSAN_INTERCEPTOR(__cxa_guard_acquire, m);
- int res = REAL(__cxa_guard_acquire)(m);
- if (res) {
- // This thread does the init.
- } else {
- Acquire(thr, pc, (uptr)m);
+extern "C" int INTERFACE_ATTRIBUTE __cxa_guard_acquire(atomic_uint32_t *g) {
+ SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire, g);
+ for (;;) {
+ u32 cmp = atomic_load(g, memory_order_acquire);
+ if (cmp == 0) {
+ if (atomic_compare_exchange_strong(g, &cmp, 1<<16, memory_order_relaxed))
+ return 1;
+ } else if (cmp == 1) {
+ Acquire(thr, pc, (uptr)g);
+ return 0;
+ } else {
+ internal_sched_yield();
+ }
}
- return res;
}
-TSAN_INTERCEPTOR(void, __cxa_guard_release, char *m) {
- SCOPED_TSAN_INTERCEPTOR(__cxa_guard_release, m);
- Release(thr, pc, (uptr)m);
- REAL(__cxa_guard_release)(m);
+extern "C" void INTERFACE_ATTRIBUTE __cxa_guard_release(atomic_uint32_t *g) {
+ SCOPED_INTERCEPTOR_RAW(__cxa_guard_release, g);
+ Release(thr, pc, (uptr)g);
+ atomic_store(g, 1, memory_order_release);
+}
+
+extern "C" void INTERFACE_ATTRIBUTE __cxa_guard_abort(atomic_uint32_t *g) {
+ SCOPED_INTERCEPTOR_RAW(__cxa_guard_abort, g);
+ atomic_store(g, 0, memory_order_relaxed);
}
static void thread_finalize(void *v) {
@@ -1508,9 +1518,6 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(strncpy);
TSAN_INTERCEPT(strstr);
- TSAN_INTERCEPT(__cxa_guard_acquire);
- TSAN_INTERCEPT(__cxa_guard_release);
-
TSAN_INTERCEPT(pthread_create);
TSAN_INTERCEPT(pthread_join);
TSAN_INTERCEPT(pthread_detach);
diff --git a/libsanitizer/tsan/tsan_interface_atomic.cc b/libsanitizer/tsan/tsan_interface_atomic.cc
index 25f171e..63860ed 100644
--- a/libsanitizer/tsan/tsan_interface_atomic.cc
+++ b/libsanitizer/tsan/tsan_interface_atomic.cc
@@ -113,7 +113,10 @@ static morder ConvertOrder(morder mo) {
}
template<typename T> T func_xchg(volatile T *v, T op) {
- return __sync_lock_test_and_set(v, op);
+ T res = __sync_lock_test_and_set(v, op);
+ // __sync_lock_test_and_set does not contain full barrier.
+ __sync_synchronize();
+ return res;
}
template<typename T> T func_add(volatile T *v, T op) {
@@ -253,6 +256,9 @@ static void AtomicStore(ThreadState *thr, uptr pc, volatile T *a, T v,
thr->clock.ReleaseStore(&s->clock);
*a = v;
s->mtx.Unlock();
+ // Trainling memory barrier to provide sequential consistency
+ // for Dekker-like store-load synchronization.
+ __sync_synchronize();
}
template<typename T, T (*F)(volatile T *v, T op)>
diff --git a/libsanitizer/tsan/tsan_stat.cc b/libsanitizer/tsan/tsan_stat.cc
index f8ecec1..7b91330 100644
--- a/libsanitizer/tsan/tsan_stat.cc
+++ b/libsanitizer/tsan/tsan_stat.cc
@@ -136,6 +136,7 @@ void StatOutput(u64 *stat) {
name[StatInt_atexit] = " atexit ";
name[StatInt___cxa_guard_acquire] = " __cxa_guard_acquire ";
name[StatInt___cxa_guard_release] = " __cxa_guard_release ";
+ name[StatInt___cxa_guard_abort] = " __cxa_guard_abort ";
name[StatInt_pthread_create] = " pthread_create ";
name[StatInt_pthread_join] = " pthread_join ";
name[StatInt_pthread_detach] = " pthread_detach ";
diff --git a/libsanitizer/tsan/tsan_stat.h b/libsanitizer/tsan/tsan_stat.h
index 51e4c4a..0dc1cd9 100644
--- a/libsanitizer/tsan/tsan_stat.h
+++ b/libsanitizer/tsan/tsan_stat.h
@@ -133,6 +133,7 @@ enum StatType {
StatInt_atexit,
StatInt___cxa_guard_acquire,
StatInt___cxa_guard_release,
+ StatInt___cxa_guard_abort,
StatInt_pthread_create,
StatInt_pthread_join,
StatInt_pthread_detach,