diff options
author | Kostya Serebryany <kcc@google.com> | 2012-12-06 14:43:11 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@gcc.gnu.org> | 2012-12-06 14:43:11 +0000 |
commit | 695edbac5c1b02ac162a301d6886dc073b0361fb (patch) | |
tree | 1f745ce7339c78271d4e10927b85f87464a29e01 /libsanitizer/tsan | |
parent | c8211767c5f4e6bcce383122cddcbe812b871182 (diff) | |
download | gcc-695edbac5c1b02ac162a301d6886dc073b0361fb.tar.gz |
[libsanitizer] merge from upstream r169392
From-SVN: r194255
Diffstat (limited to 'libsanitizer/tsan')
-rw-r--r-- | libsanitizer/tsan/tsan_interceptors.cc | 37 | ||||
-rw-r--r-- | libsanitizer/tsan/tsan_interface_atomic.cc | 8 | ||||
-rw-r--r-- | libsanitizer/tsan/tsan_stat.cc | 1 | ||||
-rw-r--r-- | libsanitizer/tsan/tsan_stat.h | 1 |
4 files changed, 31 insertions, 16 deletions
diff --git a/libsanitizer/tsan/tsan_interceptors.cc b/libsanitizer/tsan/tsan_interceptors.cc index 0463fbd4f28..dea64150786 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 25f171ed07a..63860edcfbb 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 f8ecec1e207..7b913306673 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 51e4c4a377e..0dc1cd9a90d 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, |