JF Bastien | 08511cd | 2016-03-25 15:48:21 +0000 | [diff] [blame] | 1 | //===----------------------------------------------------------------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is dual licensed under the MIT and the University of Illinois Open |
| 6 | // Source Licenses. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // UNSUPPORTED: libcpp-has-no-threads, c++98, c++03, c++11, c++14 |
| 11 | |
| 12 | // <atomic> |
| 13 | |
| 14 | // static constexpr bool is_always_lock_free; |
| 15 | |
| 16 | #include <atomic> |
| 17 | #include <cassert> |
| 18 | |
| 19 | #if !defined(__cpp_lib_atomic_is_always_lock_free) |
| 20 | # error Feature test macro missing. |
| 21 | #endif |
| 22 | |
| 23 | template <typename T> void checkAlwaysLockFree() { |
| 24 | if (std::atomic<T>::is_always_lock_free) |
| 25 | assert(std::atomic<T>().is_lock_free()); |
| 26 | } |
| 27 | |
| 28 | int main() |
| 29 | { |
| 30 | // structs and unions can't be defined in the template invocation. |
| 31 | // Work around this with a typedef. |
| 32 | #define CHECK_ALWAYS_LOCK_FREE(T) \ |
| 33 | do { \ |
| 34 | typedef T type; \ |
| 35 | checkAlwaysLockFree<type>(); \ |
| 36 | } while (0) |
| 37 | |
| 38 | CHECK_ALWAYS_LOCK_FREE(bool); |
| 39 | CHECK_ALWAYS_LOCK_FREE(char); |
| 40 | CHECK_ALWAYS_LOCK_FREE(signed char); |
| 41 | CHECK_ALWAYS_LOCK_FREE(unsigned char); |
| 42 | CHECK_ALWAYS_LOCK_FREE(char16_t); |
| 43 | CHECK_ALWAYS_LOCK_FREE(char32_t); |
| 44 | CHECK_ALWAYS_LOCK_FREE(wchar_t); |
| 45 | CHECK_ALWAYS_LOCK_FREE(short); |
| 46 | CHECK_ALWAYS_LOCK_FREE(unsigned short); |
| 47 | CHECK_ALWAYS_LOCK_FREE(int); |
| 48 | CHECK_ALWAYS_LOCK_FREE(unsigned int); |
| 49 | CHECK_ALWAYS_LOCK_FREE(long); |
| 50 | CHECK_ALWAYS_LOCK_FREE(unsigned long); |
| 51 | CHECK_ALWAYS_LOCK_FREE(long long); |
| 52 | CHECK_ALWAYS_LOCK_FREE(unsigned long long); |
| 53 | CHECK_ALWAYS_LOCK_FREE(std::nullptr_t); |
| 54 | CHECK_ALWAYS_LOCK_FREE(void*); |
| 55 | CHECK_ALWAYS_LOCK_FREE(float); |
| 56 | CHECK_ALWAYS_LOCK_FREE(double); |
| 57 | CHECK_ALWAYS_LOCK_FREE(long double); |
| 58 | CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(1 * sizeof(int))))); |
| 59 | CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(2 * sizeof(int))))); |
| 60 | CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(4 * sizeof(int))))); |
| 61 | CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(16 * sizeof(int))))); |
| 62 | CHECK_ALWAYS_LOCK_FREE(int __attribute__((vector_size(32 * sizeof(int))))); |
| 63 | CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(1 * sizeof(float))))); |
| 64 | CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(2 * sizeof(float))))); |
| 65 | CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(4 * sizeof(float))))); |
| 66 | CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(16 * sizeof(float))))); |
| 67 | CHECK_ALWAYS_LOCK_FREE(float __attribute__((vector_size(32 * sizeof(float))))); |
| 68 | CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(1 * sizeof(double))))); |
| 69 | CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(2 * sizeof(double))))); |
| 70 | CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(4 * sizeof(double))))); |
| 71 | CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(16 * sizeof(double))))); |
| 72 | CHECK_ALWAYS_LOCK_FREE(double __attribute__((vector_size(32 * sizeof(double))))); |
| 73 | CHECK_ALWAYS_LOCK_FREE(struct{}); |
| 74 | CHECK_ALWAYS_LOCK_FREE(struct{ int i; }); |
| 75 | CHECK_ALWAYS_LOCK_FREE(struct{ int i[2]; }); |
| 76 | CHECK_ALWAYS_LOCK_FREE(struct{ long long int i[2]; }); |
| 77 | CHECK_ALWAYS_LOCK_FREE(struct{ long long int i[4]; }); |
| 78 | CHECK_ALWAYS_LOCK_FREE(struct{ long long int i[8]; }); |
| 79 | CHECK_ALWAYS_LOCK_FREE(struct{ long long int i[16]; }); |
| 80 | CHECK_ALWAYS_LOCK_FREE(struct{ char c; /* padding */ long long int i; }); |
| 81 | CHECK_ALWAYS_LOCK_FREE(union{ int i; float f; }); |
| 82 | |
| 83 | // C macro and static constexpr must be consistent. |
| 84 | static_assert(std::atomic<bool>::is_always_lock_free == (2 == ATOMIC_BOOL_LOCK_FREE)); |
| 85 | static_assert(std::atomic<char>::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE)); |
| 86 | static_assert(std::atomic<signed char>::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE)); |
| 87 | static_assert(std::atomic<unsigned char>::is_always_lock_free == (2 == ATOMIC_CHAR_LOCK_FREE)); |
| 88 | static_assert(std::atomic<char16_t>::is_always_lock_free == (2 == ATOMIC_CHAR16_T_LOCK_FREE)); |
| 89 | static_assert(std::atomic<char32_t>::is_always_lock_free == (2 == ATOMIC_CHAR32_T_LOCK_FREE)); |
| 90 | static_assert(std::atomic<wchar_t>::is_always_lock_free == (2 == ATOMIC_WCHAR_T_LOCK_FREE)); |
| 91 | static_assert(std::atomic<short>::is_always_lock_free == (2 == ATOMIC_SHORT_LOCK_FREE)); |
| 92 | static_assert(std::atomic<unsigned short>::is_always_lock_free == (2 == ATOMIC_SHORT_LOCK_FREE)); |
| 93 | static_assert(std::atomic<int>::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE)); |
| 94 | static_assert(std::atomic<unsigned int>::is_always_lock_free == (2 == ATOMIC_INT_LOCK_FREE)); |
| 95 | static_assert(std::atomic<long>::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE)); |
| 96 | static_assert(std::atomic<unsigned long>::is_always_lock_free == (2 == ATOMIC_LONG_LOCK_FREE)); |
| 97 | static_assert(std::atomic<long long>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE)); |
| 98 | static_assert(std::atomic<unsigned long long>::is_always_lock_free == (2 == ATOMIC_LLONG_LOCK_FREE)); |
| 99 | static_assert(std::atomic<void*>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE)); |
| 100 | static_assert(std::atomic<std::nullptr_t>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE)); |
| 101 | } |