tsan: fix windows build (1)


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@162996 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/sanitizer_common/sanitizer_atomic_msvc.h b/lib/sanitizer_common/sanitizer_atomic_msvc.h
index 2a15b59..b21275b 100644
--- a/lib/sanitizer_common/sanitizer_atomic_msvc.h
+++ b/lib/sanitizer_common/sanitizer_atomic_msvc.h
@@ -24,6 +24,10 @@
 extern "C" long _InterlockedExchangeAdd(  // NOLINT
     long volatile * Addend, long Value);  // NOLINT
 #pragma intrinsic(_InterlockedExchangeAdd)
+extern "C" void *_InterlockedCompareExchangePointer(
+    void *volatile *Destination,
+    void *Exchange, void *Comparand);
+#pragma intrinsic(_InterlockedCompareExchangePointer)
 
 namespace __sanitizer {
 
@@ -107,6 +111,27 @@
   return v;
 }
 
+INLINE bool atomic_compare_exchange_strong(volatile uptr *a,
+                                           uptr *cmp,
+                                           uptr xchg,
+                                           memory_order mo) {
+  uptr cmpv = *cmp;
+  uptr prev = (uptr)_InterlockedCompareExchangePointer(
+      (void*volatile*)&a->val_dont_use, (void*)xchg, (void*)cmpv);
+  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