Home | History | Annotate | Download | only in tests
      1 //===-- sanitizer_atomic_test.cc ------------------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file is a part of ThreadSanitizer/AddressSanitizer runtime.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 #include "sanitizer_common/sanitizer_atomic.h"
     14 #include "gtest/gtest.h"
     15 
     16 namespace __sanitizer {
     17 
     18 template<typename T>
     19 struct ValAndMagic {
     20   typename T::Type magic0;
     21   T a;
     22   typename T::Type magic1;
     23 
     24   static ValAndMagic<T> *sink;
     25 };
     26 
     27 template<typename T>
     28 ValAndMagic<T> *ValAndMagic<T>::sink;
     29 
     30 template<typename T, memory_order load_mo, memory_order store_mo>
     31 void CheckStoreLoad() {
     32   typedef typename T::Type Type;
     33   ValAndMagic<T> val;
     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.
     40     u64 v = i;
     41     v |= v << 8;
     42     v |= v << 16;
     43     v |= v << 32;
     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);
     49   }
     50   EXPECT_EQ(val.magic0, (Type)-3);
     51   EXPECT_EQ(val.magic1, (Type)-3);
     52 }
     53 
     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>();
     60 
     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>();
     66 
     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>();
     72 
     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>();
     78 
     79   CheckStoreLoad<atomic_uintptr_t, memory_order_relaxed, memory_order_relaxed>
     80       ();
     81   CheckStoreLoad<atomic_uintptr_t, memory_order_consume, memory_order_relaxed>
     82       ();
     83   CheckStoreLoad<atomic_uintptr_t, memory_order_acquire, memory_order_relaxed>
     84       ();
     85   CheckStoreLoad<atomic_uintptr_t, memory_order_relaxed, memory_order_release>
     86       ();
     87   CheckStoreLoad<atomic_uintptr_t, memory_order_seq_cst, memory_order_seq_cst>
     88       ();
     89 }
     90 
     91 // Clang crashes while compiling this test for Android:
     92 // http://llvm.org/bugs/show_bug.cgi?id=15587
     93 #if !SANITIZER_ANDROID
     94 template<typename T>
     95 void CheckAtomicCompareExchange() {
     96   typedef typename T::Type Type;
     97   {
     98     Type old_val = 42;
     99     Type new_val = 24;
    100     Type var = old_val;
    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);
    106   }
    107   {
    108     Type old_val = 42;
    109     Type new_val = 24;
    110     Type var = 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);
    116   }
    117 }
    118 
    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>();
    125 }
    126 #endif  //!SANITIZER_ANDROID
    127 
    128 }  // namespace __sanitizer
    129