1 //===-- sanitizer_atomic_test.cc ------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
12 //===----------------------------------------------------------------------===//
13 #include "sanitizer_common/sanitizer_atomic.h"
14 #include "gtest/gtest.h"
16 namespace __sanitizer {
20 typename T::Type magic0;
22 typename T::Type magic1;
24 static ValAndMagic<T> *sink;
28 ValAndMagic<T> *ValAndMagic<T>::sink;
30 template<typename T, memory_order load_mo, memory_order store_mo>
31 void CheckStoreLoad() {
32 typedef typename T::Type Type;
34 // Prevent the compiler from scalarizing the struct.
35 ValAndMagic<T>::sink = &val;
36 // Ensure that surrounding memory is not overwritten.
37 val.magic0 = val.magic1 = (Type)-3;
38 for (u64 i = 0; i < 100; i++) {
39 // Generate a value that occupies all bytes of the variable.
44 val.a.val_dont_use = (Type)v;
45 EXPECT_EQ(atomic_load(&val.a, load_mo), (Type)v);
46 val.a.val_dont_use = (Type)-1;
47 atomic_store(&val.a, (Type)v, store_mo);
48 EXPECT_EQ(val.a.val_dont_use, (Type)v);
50 EXPECT_EQ(val.magic0, (Type)-3);
51 EXPECT_EQ(val.magic1, (Type)-3);
54 TEST(SanitizerCommon, AtomicStoreLoad) {
55 CheckStoreLoad<atomic_uint8_t, memory_order_relaxed, memory_order_relaxed>();
56 CheckStoreLoad<atomic_uint8_t, memory_order_consume, memory_order_relaxed>();
57 CheckStoreLoad<atomic_uint8_t, memory_order_acquire, memory_order_relaxed>();
58 CheckStoreLoad<atomic_uint8_t, memory_order_relaxed, memory_order_release>();
59 CheckStoreLoad<atomic_uint8_t, memory_order_seq_cst, memory_order_seq_cst>();
61 CheckStoreLoad<atomic_uint16_t, memory_order_relaxed, memory_order_relaxed>();
62 CheckStoreLoad<atomic_uint16_t, memory_order_consume, memory_order_relaxed>();
63 CheckStoreLoad<atomic_uint16_t, memory_order_acquire, memory_order_relaxed>();
64 CheckStoreLoad<atomic_uint16_t, memory_order_relaxed, memory_order_release>();
65 CheckStoreLoad<atomic_uint16_t, memory_order_seq_cst, memory_order_seq_cst>();
67 CheckStoreLoad<atomic_uint32_t, memory_order_relaxed, memory_order_relaxed>();
68 CheckStoreLoad<atomic_uint32_t, memory_order_consume, memory_order_relaxed>();
69 CheckStoreLoad<atomic_uint32_t, memory_order_acquire, memory_order_relaxed>();
70 CheckStoreLoad<atomic_uint32_t, memory_order_relaxed, memory_order_release>();
71 CheckStoreLoad<atomic_uint32_t, memory_order_seq_cst, memory_order_seq_cst>();
73 CheckStoreLoad<atomic_uint64_t, memory_order_relaxed, memory_order_relaxed>();
74 CheckStoreLoad<atomic_uint64_t, memory_order_consume, memory_order_relaxed>();
75 CheckStoreLoad<atomic_uint64_t, memory_order_acquire, memory_order_relaxed>();
76 CheckStoreLoad<atomic_uint64_t, memory_order_relaxed, memory_order_release>();
77 CheckStoreLoad<atomic_uint64_t, memory_order_seq_cst, memory_order_seq_cst>();
79 CheckStoreLoad<atomic_uintptr_t, memory_order_relaxed, memory_order_relaxed>
81 CheckStoreLoad<atomic_uintptr_t, memory_order_consume, memory_order_relaxed>
83 CheckStoreLoad<atomic_uintptr_t, memory_order_acquire, memory_order_relaxed>
85 CheckStoreLoad<atomic_uintptr_t, memory_order_relaxed, memory_order_release>
87 CheckStoreLoad<atomic_uintptr_t, memory_order_seq_cst, memory_order_seq_cst>
91 // Clang crashes while compiling this test for Android:
92 // http://llvm.org/bugs/show_bug.cgi?id=15587
93 #if !SANITIZER_ANDROID
95 void CheckAtomicCompareExchange() {
96 typedef typename T::Type Type;
101 EXPECT_TRUE(atomic_compare_exchange_strong((T*)&var, &old_val, new_val,
102 memory_order_relaxed));
103 EXPECT_FALSE(atomic_compare_exchange_strong((T*)&var, &old_val, new_val,
104 memory_order_relaxed));
105 EXPECT_EQ(new_val, old_val);
111 EXPECT_TRUE(atomic_compare_exchange_weak((T*)&var, &old_val, new_val,
112 memory_order_relaxed));
113 EXPECT_FALSE(atomic_compare_exchange_weak((T*)&var, &old_val, new_val,
114 memory_order_relaxed));
115 EXPECT_EQ(new_val, old_val);
119 TEST(SanitizerCommon, AtomicCompareExchangeTest) {
120 CheckAtomicCompareExchange<atomic_uint8_t>();
121 CheckAtomicCompareExchange<atomic_uint16_t>();
122 CheckAtomicCompareExchange<atomic_uint32_t>();
123 CheckAtomicCompareExchange<atomic_uint64_t>();
124 CheckAtomicCompareExchange<atomic_uintptr_t>();
126 #endif //!SANITIZER_ANDROID
128 } // namespace __sanitizer