summaryrefslogtreecommitdiff
path: root/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2013-11-04 21:33:31 +0000
committerKostya Serebryany <kcc@gcc.gnu.org>2013-11-04 21:33:31 +0000
commitef1b3fda32c08e9bd6977b96e1e619aae3e3726a (patch)
tree7cfc103c9b6b4ce7ca19d39f91509a1b68819a63 /libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h
parentfd5564d3c71195714c28ba150de7e9b90bf9c83d (diff)
libsanitizer merge from upstream r191666
This may break gcc-asan on Mac, will follow up separately. From-SVN: r204368
Diffstat (limited to 'libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h')
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h27
1 files changed, 24 insertions, 3 deletions
diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h b/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h
index 919e24f3b11..dac7c19199b 100644
--- a/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h
+++ b/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h
@@ -132,6 +132,27 @@ INLINE u16 atomic_exchange(volatile atomic_uint16_t *a,
return v;
}
+INLINE bool atomic_compare_exchange_strong(volatile atomic_uint8_t *a,
+ u8 *cmp,
+ u8 xchgv,
+ memory_order mo) {
+ (void)mo;
+ DCHECK(!((uptr)a % sizeof(*a)));
+ u8 cmpv = *cmp;
+ u8 prev;
+ __asm {
+ mov al, cmpv
+ mov ecx, a
+ mov dl, xchgv
+ lock cmpxchg [ecx], dl
+ mov prev, al
+ }
+ if (prev == cmpv)
+ return true;
+ *cmp = prev;
+ return false;
+}
+
INLINE bool atomic_compare_exchange_strong(volatile atomic_uintptr_t *a,
uptr *cmp,
uptr xchg,
@@ -147,9 +168,9 @@ INLINE bool atomic_compare_exchange_strong(volatile atomic_uintptr_t *a,
template<typename T>
INLINE bool atomic_compare_exchange_weak(volatile T *a,
- typename T::Type *cmp,
- typename T::Type xchg,
- memory_order mo) {
+ typename T::Type *cmp,
+ typename T::Type xchg,
+ memory_order mo) {
return atomic_compare_exchange_strong(a, cmp, xchg, mo);
}