diff options
author | kcc <kcc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-06 14:43:11 +0000 |
---|---|---|
committer | kcc <kcc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-06 14:43:11 +0000 |
commit | 1a8a3492ad2746da195565a50147c57b45e79cd0 (patch) | |
tree | 1f745ce7339c78271d4e10927b85f87464a29e01 /libsanitizer | |
parent | a0db5e0bd8f1348278937fe0ec60dec4db27a952 (diff) | |
download | gcc-1a8a3492ad2746da195565a50147c57b45e79cd0.tar.gz |
[libsanitizer] merge from upstream r169392
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194255 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libsanitizer')
-rw-r--r-- | libsanitizer/ChangeLog | 4 | ||||
-rw-r--r-- | libsanitizer/MERGE | 2 | ||||
-rw-r--r-- | libsanitizer/asan/asan_interceptors.cc | 2 | ||||
-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 |
7 files changed, 36 insertions, 19 deletions
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog index 4b0adecc5e9..ff5188f26cf 100644 --- a/libsanitizer/ChangeLog +++ b/libsanitizer/ChangeLog @@ -1,3 +1,7 @@ +2012-12-06 Kostya Serebryany <kcc@google.com> + + * All files: Merge from upstream r169392. + 2012-12-05 Kostya Serebryany <kcc@google.com> * All files: Merge from upstream r169371. diff --git a/libsanitizer/MERGE b/libsanitizer/MERGE index 1512aa03802..071edae3249 100644 --- a/libsanitizer/MERGE +++ b/libsanitizer/MERGE @@ -1,4 +1,4 @@ -169371 +169392 The first line of this file holds the svn revision number of the last merge done from the master library sources. diff --git a/libsanitizer/asan/asan_interceptors.cc b/libsanitizer/asan/asan_interceptors.cc index ebaf95c3834..5b544c87fcb 100644 --- a/libsanitizer/asan/asan_interceptors.cc +++ b/libsanitizer/asan/asan_interceptors.cc @@ -177,8 +177,6 @@ INTERCEPTOR(void, siglongjmp, void *env, int val) { #if ASAN_INTERCEPT___CXA_THROW INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { - Printf("__asan's __cxa_throw %p; REAL(__cxa_throw) %p PLAIN %p\n", - __interceptor___cxa_throw, REAL(__cxa_throw), __cxa_throw); CHECK(REAL(__cxa_throw)); __asan_handle_no_return(); REAL(__cxa_throw)(a, b, c); 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, |