[llvm-commits] [compiler-rt] r159443 - in /compiler-rt/trunk/lib: sanitizer_common/sanitizer_atomic.h sanitizer_common/sanitizer_atomic_clang.h sanitizer_common/sanitizer_atomic_msvc.h sanitizer_common/sanitizer_posix.cc sanitizer_common/sanitizer_win.cc tsan/unit_tests/tsan_mutex_test.cc

Dmitry Vyukov dvyukov at google.com
Fri Jun 29 11:00:38 PDT 2012


Author: dvyukov
Date: Fri Jun 29 13:00:38 2012
New Revision: 159443

URL: http://llvm.org/viewvc/llvm-project?rev=159443&view=rev
Log:
tsan/asan: first try on msvc atomics

Added:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic_clang.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic_msvc.h
Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
    compiler-rt/trunk/lib/tsan/unit_tests/tsan_mutex_test.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic.h?rev=159443&r1=159442&r2=159443&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic.h Fri Jun 29 13:00:38 2012
@@ -52,106 +52,14 @@
   volatile Type val_dont_use;
 };
 
-INLINE void atomic_signal_fence(memory_order) {
-  __asm__ __volatile__("" ::: "memory");
-}
-
-INLINE void atomic_thread_fence(memory_order) {
-  __sync_synchronize();
-}
+}  // namespace __sanitizer
 
-INLINE void proc_yield(int cnt) {
-  __asm__ __volatile__("" ::: "memory");
-#if defined(__i386__) || defined(__x86_64__)
-  for (int i = 0; i < cnt; i++)
-    __asm__ __volatile__("pause");
+#if defined(__GNUC__)
+# include "sanitizer_atomic_clang.h"
+#elif defined(_MSC_VER)
+# include "sanitizer_atomic_msvc.h"
+#else
+# error "Unsupported compiler"
 #endif
-  __asm__ __volatile__("" ::: "memory");
-}
-
-template<typename T>
-INLINE typename T::Type atomic_load(
-    const volatile T *a, memory_order mo) {
-  DCHECK(mo & (memory_order_relaxed | memory_order_consume
-      | memory_order_acquire | memory_order_seq_cst));
-  DCHECK(!((uptr)a % sizeof(*a)));
-  typename T::Type v;
-  if (mo == memory_order_relaxed) {
-    v = a->val_dont_use;
-  } else {
-    atomic_signal_fence(memory_order_seq_cst);
-    v = a->val_dont_use;
-    atomic_signal_fence(memory_order_seq_cst);
-  }
-  return v;
-}
-
-template<typename T>
-INLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {
-  DCHECK(mo & (memory_order_relaxed | memory_order_release
-      | memory_order_seq_cst));
-  DCHECK(!((uptr)a % sizeof(*a)));
-  if (mo == memory_order_relaxed) {
-    a->val_dont_use = v;
-  } else {
-    atomic_signal_fence(memory_order_seq_cst);
-    a->val_dont_use = v;
-    atomic_signal_fence(memory_order_seq_cst);
-  }
-  if (mo == memory_order_seq_cst)
-    atomic_thread_fence(memory_order_seq_cst);
-}
-
-template<typename T>
-INLINE typename T::Type atomic_fetch_add(volatile T *a,
-    typename T::Type v, memory_order mo) {
-  (void)mo;
-  DCHECK(!((uptr)a % sizeof(*a)));
-  return __sync_fetch_and_add(&a->val_dont_use, v);
-}
-
-template<typename T>
-INLINE typename T::Type atomic_fetch_sub(volatile T *a,
-    typename T::Type v, memory_order mo) {
-  (void)mo;
-  DCHECK(!((uptr)a % sizeof(*a)));
-  return __sync_fetch_and_add(&a->val_dont_use, -v);
-}
-
-template<typename T>
-INLINE typename T::Type atomic_exchange(volatile T *a,
-    typename T::Type v, memory_order mo) {
-  DCHECK(!((uptr)a % sizeof(*a)));
-  if (mo & (memory_order_release | memory_order_acq_rel | memory_order_seq_cst))
-    __sync_synchronize();
-  v = __sync_lock_test_and_set(&a->val_dont_use, v);
-  if (mo == memory_order_seq_cst)
-    __sync_synchronize();
-  return v;
-}
-
-template<typename T>
-INLINE bool atomic_compare_exchange_strong(volatile T *a,
-                                           typename T::Type *cmp,
-                                           typename T::Type xchg,
-                                           memory_order mo) {
-  typedef typename T::Type Type;
-  Type cmpv = *cmp;
-  Type prev = __sync_val_compare_and_swap(&a->val_dont_use, cmpv, xchg);
-  if (prev == cmpv)
-    return true;
-  *cmp = prev;
-  return false;
-}
-
-template<typename T>
-INLINE bool atomic_compare_exchange_weak(volatile T *a,
-                                           typename T::Type *cmp,
-                                           typename T::Type xchg,
-                                           memory_order mo) {
-  return atomic_compare_exchange_strong(a, cmp, xchg, mo);
-}
-
-}  // namespace __sanitizer
 
 #endif  // SANITIZER_ATOMIC_H

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic_clang.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic_clang.h?rev=159443&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic_clang.h (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic_clang.h Fri Jun 29 13:00:38 2012
@@ -0,0 +1,122 @@
+//===-- sanitizer_atomic_clang.h --------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
+// Not intended for direct inclusion. Include sanitizer_atomic.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_ATOMIC_CLANG_H
+#define SANITIZER_ATOMIC_CLANG_H
+
+namespace __sanitizer {
+
+INLINE void atomic_signal_fence(memory_order) {
+  __asm__ __volatile__("" ::: "memory");
+}
+
+INLINE void atomic_thread_fence(memory_order) {
+  __sync_synchronize();
+}
+
+INLINE void proc_yield(int cnt) {
+  __asm__ __volatile__("" ::: "memory");
+#if defined(__i386__) || defined(__x86_64__)
+  for (int i = 0; i < cnt; i++)
+    __asm__ __volatile__("pause");
+#endif
+  __asm__ __volatile__("" ::: "memory");
+}
+
+template<typename T>
+INLINE typename T::Type atomic_load(
+    const volatile T *a, memory_order mo) {
+  DCHECK(mo & (memory_order_relaxed | memory_order_consume
+      | memory_order_acquire | memory_order_seq_cst));
+  DCHECK(!((uptr)a % sizeof(*a)));
+  typename T::Type v;
+  if (mo == memory_order_relaxed) {
+    v = a->val_dont_use;
+  } else {
+    atomic_signal_fence(memory_order_seq_cst);
+    v = a->val_dont_use;
+    atomic_signal_fence(memory_order_seq_cst);
+  }
+  return v;
+}
+
+template<typename T>
+INLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {
+  DCHECK(mo & (memory_order_relaxed | memory_order_release
+      | memory_order_seq_cst));
+  DCHECK(!((uptr)a % sizeof(*a)));
+  if (mo == memory_order_relaxed) {
+    a->val_dont_use = v;
+  } else {
+    atomic_signal_fence(memory_order_seq_cst);
+    a->val_dont_use = v;
+    atomic_signal_fence(memory_order_seq_cst);
+  }
+  if (mo == memory_order_seq_cst)
+    atomic_thread_fence(memory_order_seq_cst);
+}
+
+template<typename T>
+INLINE typename T::Type atomic_fetch_add(volatile T *a,
+    typename T::Type v, memory_order mo) {
+  (void)mo;
+  DCHECK(!((uptr)a % sizeof(*a)));
+  return __sync_fetch_and_add(&a->val_dont_use, v);
+}
+
+template<typename T>
+INLINE typename T::Type atomic_fetch_sub(volatile T *a,
+    typename T::Type v, memory_order mo) {
+  (void)mo;
+  DCHECK(!((uptr)a % sizeof(*a)));
+  return __sync_fetch_and_add(&a->val_dont_use, -v);
+}
+
+template<typename T>
+INLINE typename T::Type atomic_exchange(volatile T *a,
+    typename T::Type v, memory_order mo) {
+  DCHECK(!((uptr)a % sizeof(*a)));
+  if (mo & (memory_order_release | memory_order_acq_rel | memory_order_seq_cst))
+    __sync_synchronize();
+  v = __sync_lock_test_and_set(&a->val_dont_use, v);
+  if (mo == memory_order_seq_cst)
+    __sync_synchronize();
+  return v;
+}
+
+template<typename T>
+INLINE bool atomic_compare_exchange_strong(volatile T *a,
+                                           typename T::Type *cmp,
+                                           typename T::Type xchg,
+                                           memory_order mo) {
+  typedef typename T::Type Type;
+  Type cmpv = *cmp;
+  Type prev = __sync_val_compare_and_swap(&a->val_dont_use, cmpv, xchg);
+  if (prev == cmpv)
+    return true;
+  *cmp = prev;
+  return false;
+}
+
+template<typename T>
+INLINE bool atomic_compare_exchange_weak(volatile T *a,
+                                           typename T::Type *cmp,
+                                           typename T::Type xchg,
+                                           memory_order mo) {
+  return atomic_compare_exchange_strong(a, cmp, xchg, mo);
+}
+
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_ATOMIC_CLANG_H

Added: compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic_msvc.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic_msvc.h?rev=159443&view=auto
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic_msvc.h (added)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_atomic_msvc.h Fri Jun 29 13:00:38 2012
@@ -0,0 +1,104 @@
+//===-- sanitizer_atomic_msvc.h ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
+// Not intended for direct inclusion. Include sanitizer_atomic.h.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_ATOMIC_MSVC_H
+#define SANITIZER_ATOMIC_MSVC_H
+
+#include <intrin.h>
+
+namespace __sanitizer {
+
+INLINE void atomic_signal_fence(memory_order) {
+  _ReadWriteBarrier();
+}
+
+INLINE void atomic_thread_fence(memory_order) {
+  _mm_mfence();
+}
+
+INLINE void proc_yield(int cnt) {
+  for (int i = 0; i < cnt; i++)
+    _mm_pause();
+}
+
+template<typename T>
+INLINE typename T::Type atomic_load(
+    const volatile T *a, memory_order mo) {
+  DCHECK(mo & (memory_order_relaxed | memory_order_consume
+      | memory_order_acquire | memory_order_seq_cst));
+  DCHECK(!((uptr)a % sizeof(*a)));
+  typename T::Type v;
+  if (mo == memory_order_relaxed) {
+    v = a->val_dont_use;
+  } else {
+    atomic_signal_fence(memory_order_seq_cst);
+    v = a->val_dont_use;
+    atomic_signal_fence(memory_order_seq_cst);
+  }
+  return v;
+}
+
+template<typename T>
+INLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) {
+  DCHECK(mo & (memory_order_relaxed | memory_order_release
+      | memory_order_seq_cst));
+  DCHECK(!((uptr)a % sizeof(*a)));
+  if (mo == memory_order_relaxed) {
+    a->val_dont_use = v;
+  } else {
+    atomic_signal_fence(memory_order_seq_cst);
+    a->val_dont_use = v;
+    atomic_signal_fence(memory_order_seq_cst);
+  }
+  if (mo == memory_order_seq_cst)
+    atomic_thread_fence(memory_order_seq_cst);
+}
+
+INLINE u32 atomic_fetch_add(volatile atomic_uint32_t *a,
+    u32 v, memory_order mo) {
+  (void)mo;
+  DCHECK(!((uptr)a % sizeof(*a)));
+  return (u32)_InterlockedExchangeAdd(
+      (volatile long*)&a->val_dont_use, (long)v);  // NOLINT
+}
+
+INLINE u8 atomic_exchange(volatile atomic_uint8_t *a,
+    u8 v, memory_order mo) {
+  (void)mo;
+  DCHECK(!((uptr)a % sizeof(*a)));
+  __asm {
+    mov eax, a
+    mov cx, v
+    xchg [eax], cx  // NOLINT
+    mov v, cx
+  }
+  return v;
+}
+
+INLINE u16 atomic_exchange(volatile atomic_uint16_t *a,
+    u16 v, memory_order mo) {
+  (void)mo;
+  DCHECK(!((uptr)a % sizeof(*a)));
+  __asm {
+    mov eax, a
+    mov cl, v
+    xchg [eax], cl  // NOLINT
+    mov v, cl
+  }
+  return v;
+}
+
+}  // namespace __sanitizer
+
+#endif  // SANITIZER_ATOMIC_CLANG_H

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc?rev=159443&r1=159442&r2=159443&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc Fri Jun 29 13:00:38 2012
@@ -27,10 +27,6 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#ifdef ANDROID
-#include <sys/atomics.h>
-#endif
-
 namespace __sanitizer {
 
 // ------------- sanitizer_common.h
@@ -147,22 +143,6 @@
   return atexit(function);
 }
 
-int AtomicInc(int *a) {
-#ifdef ANDROID
-  return __atomic_inc(a) + 1;
-#else
-  return __sync_add_and_fetch(a, 1);
-#endif
-}
-
-u16 AtomicExchange(u16 *a, u16 new_val) {
-  return __sync_lock_test_and_set(a, new_val);
-}
-
-u8 AtomicExchange(u8 *a, u8 new_val) {
-  return __sync_lock_test_and_set(a, new_val);
-}
-
 }  // namespace __sanitizer
 
 #endif  // __linux__ || __APPLE_

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc?rev=159443&r1=159442&r2=159443&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_win.cc Fri Jun 29 13:00:38 2012
@@ -124,30 +124,6 @@
   return atexit(function);
 }
 
-int AtomicInc(int *a) {
-  return InterlockedExchangeAdd((LONG*)a, 1) + 1;
-}
-
-u16 AtomicExchange(u16 *a, u16 new_val) {
-  // InterlockedExchange16 seems unavailable on some MSVS installations.
-  // Everybody stand back, I pretend to know inline assembly!
-  // FIXME: I assume VC is smart enough to save/restore eax/ecx?
-  __asm {
-    mov eax, a
-    mov cx, new_val
-    xchg [eax], cx  ; NOLINT
-    mov new_val, cx
-  }
-  return new_val;
-}
-
-u8 AtomicExchange(u8 *a, u8 new_val) {
-  // FIXME: can we do this with a proper xchg intrinsic?
-  u8 t = *a;
-  *a = new_val;
-  return t;
-}
-
 // ------------------ sanitizer_libc.h
 void *internal_mmap(void *addr, uptr length, int prot, int flags,
                     int fd, u64 offset) {

Modified: compiler-rt/trunk/lib/tsan/unit_tests/tsan_mutex_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/unit_tests/tsan_mutex_test.cc?rev=159443&r1=159442&r2=159443&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/unit_tests/tsan_mutex_test.cc (original)
+++ compiler-rt/trunk/lib/tsan/unit_tests/tsan_mutex_test.cc Fri Jun 29 13:00:38 2012
@@ -22,7 +22,7 @@
 template<typename MutexType>
 class TestData {
  public:
-  TestData(MutexType *mtx)
+  explicit TestData(MutexType *mtx)
     : mtx_(mtx) {
     for (int i = 0; i < kSize; i++)
       data_[i] = 0;





More information about the llvm-commits mailing list