]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[libsanitizer] merge from upstream r169392
authorKostya Serebryany <kcc@google.com>
Thu, 6 Dec 2012 14:43:11 +0000 (14:43 +0000)
committerKostya Serebryany <kcc@gcc.gnu.org>
Thu, 6 Dec 2012 14:43:11 +0000 (14:43 +0000)
From-SVN: r194255

libsanitizer/ChangeLog
libsanitizer/MERGE
libsanitizer/asan/asan_interceptors.cc
libsanitizer/tsan/tsan_interceptors.cc
libsanitizer/tsan/tsan_interface_atomic.cc
libsanitizer/tsan/tsan_stat.cc
libsanitizer/tsan/tsan_stat.h

index 4b0adecc5e9373d60affff88b462902a18e32369..ff5188f26cfe570868a006fb238b26419af13d90 100644 (file)
@@ -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.
index 1512aa0380278d3e11ce55847b3c65a648800579..071edae3249b5c9c579aefda9e4bd58e0fca4239 100644 (file)
@@ -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.
index ebaf95c3834c7bc34618b626da83d53cc9be12b2..5b544c87fcb85adcae8f5ecfa31c14498545ff10 100644 (file)
@@ -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);
index 0463fbd4f2847daae277fd4e3ed124df34d75ac8..dea6415078636524e4f04dfddbb081a797eaf157 100644 (file)
@@ -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);
index 25f171ed07a5ab56d9e93413de0b541f4769af4f..63860edcfbb2419249bc4c3e4737e1995c9e4656 100644 (file)
@@ -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)>
index f8ecec1e2071da06e85ad423427fe57aac22a9d2..7b9133066739909b2aab54b5dcf0431525f001f0 100644 (file)
@@ -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                  ";
index 51e4c4a377e42e430670b83d5964b4c9ea6dfee0..0dc1cd9a90ddb674c05adce03c376ad80fdccf5c 100644 (file)
@@ -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,