[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