Xerxes Ranby | 6215c62 | 2009-07-17 19:22:41 +0000 | [diff] [blame] | 1 | # atomic builtins are required for threading support. |
| 2 | |
| 3 | INCLUDE(CheckCXXSourceCompiles) |
Martell Malone | abd7f8c | 2017-12-02 07:17:01 +0000 | [diff] [blame] | 4 | INCLUDE(CheckLibraryExists) |
Oscar Fuentes | 87e9807 | 2009-12-05 23:19:33 +0000 | [diff] [blame] | 5 | |
James Y Knight | cc73f10 | 2015-06-16 14:00:01 +0000 | [diff] [blame] | 6 | # Sometimes linking against libatomic is required for atomic ops, if |
| 7 | # the platform doesn't support lock-free atomics. |
| 8 | |
| 9 | function(check_working_cxx_atomics varname) |
| 10 | set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) |
Don Hinton | e40169c | 2017-12-25 01:23:09 +0000 | [diff] [blame] | 11 | set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -std=c++11") |
James Y Knight | cc73f10 | 2015-06-16 14:00:01 +0000 | [diff] [blame] | 12 | CHECK_CXX_SOURCE_COMPILES(" |
| 13 | #include <atomic> |
| 14 | std::atomic<int> x; |
| 15 | int main() { |
| 16 | return x; |
| 17 | } |
| 18 | " ${varname}) |
| 19 | set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) |
| 20 | endfunction(check_working_cxx_atomics) |
| 21 | |
Sagar Thakur | 7c2609a | 2016-06-23 06:39:35 +0000 | [diff] [blame] | 22 | function(check_working_cxx_atomics64 varname) |
| 23 | set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) |
| 24 | set(CMAKE_REQUIRED_FLAGS "-std=c++11 ${CMAKE_REQUIRED_FLAGS}") |
| 25 | CHECK_CXX_SOURCE_COMPILES(" |
| 26 | #include <atomic> |
| 27 | #include <cstdint> |
| 28 | std::atomic<uint64_t> x (0); |
| 29 | int main() { |
| 30 | uint64_t i = x.load(std::memory_order_relaxed); |
| 31 | return 0; |
| 32 | } |
| 33 | " ${varname}) |
| 34 | set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) |
| 35 | endfunction(check_working_cxx_atomics64) |
| 36 | |
| 37 | |
James Y Knight | cc73f10 | 2015-06-16 14:00:01 +0000 | [diff] [blame] | 38 | # This isn't necessary on MSVC, so avoid command-line switch annoyance |
| 39 | # by only running on GCC-like hosts. |
| 40 | if (LLVM_COMPILER_IS_GCC_COMPATIBLE) |
| 41 | # First check if atomics work without the library. |
| 42 | check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB) |
| 43 | # If not, check if the library exists, and atomics work with it. |
| 44 | if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB) |
| 45 | check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC) |
| 46 | if( HAVE_LIBATOMIC ) |
| 47 | list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") |
| 48 | check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB) |
| 49 | if (NOT HAVE_CXX_ATOMICS_WITH_LIB) |
| 50 | message(FATAL_ERROR "Host compiler must support std::atomic!") |
| 51 | endif() |
| 52 | else() |
| 53 | message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.") |
| 54 | endif() |
Saleem Abdulrasool | fb5edaa | 2015-02-25 02:38:03 +0000 | [diff] [blame] | 55 | endif() |
Evgeniy Stepanov | 6354451 | 2014-09-12 11:08:59 +0000 | [diff] [blame] | 56 | endif() |
| 57 | |
Sagar Thakur | 7c2609a | 2016-06-23 06:39:35 +0000 | [diff] [blame] | 58 | # Check for 64 bit atomic operations. |
| 59 | if(MSVC) |
| 60 | set(HAVE_CXX_ATOMICS64_WITHOUT_LIB True) |
| 61 | else() |
| 62 | check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITHOUT_LIB) |
| 63 | endif() |
| 64 | |
| 65 | # If not, check if the library exists, and atomics work with it. |
| 66 | if(NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB) |
| 67 | check_library_exists(atomic __atomic_load_8 "" HAVE_CXX_LIBATOMICS64) |
| 68 | if(HAVE_CXX_LIBATOMICS64) |
| 69 | list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") |
| 70 | check_working_cxx_atomics64(HAVE_CXX_ATOMICS64_WITH_LIB) |
| 71 | if (NOT HAVE_CXX_ATOMICS64_WITH_LIB) |
| 72 | message(FATAL_ERROR "Host compiler must support std::atomic!") |
| 73 | endif() |
| 74 | else() |
| 75 | message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.") |
| 76 | endif() |
| 77 | endif() |
| 78 | |
James Y Knight | cc73f10 | 2015-06-16 14:00:01 +0000 | [diff] [blame] | 79 | ## TODO: This define is only used for the legacy atomic operations in |
| 80 | ## llvm's Atomic.h, which should be replaced. Other code simply |
| 81 | ## assumes C++11 <atomic> works. |
Oscar Fuentes | c595e6c | 2009-12-06 00:06:33 +0000 | [diff] [blame] | 82 | CHECK_CXX_SOURCE_COMPILES(" |
Oscar Fuentes | 87e9807 | 2009-12-05 23:19:33 +0000 | [diff] [blame] | 83 | #ifdef _MSC_VER |
| 84 | #include <windows.h> |
| 85 | #endif |
Xerxes Ranby | 6215c62 | 2009-07-17 19:22:41 +0000 | [diff] [blame] | 86 | int main() { |
Oscar Fuentes | 87e9807 | 2009-12-05 23:19:33 +0000 | [diff] [blame] | 87 | #ifdef _MSC_VER |
| 88 | volatile LONG val = 1; |
| 89 | MemoryBarrier(); |
| 90 | InterlockedCompareExchange(&val, 0, 1); |
| 91 | InterlockedIncrement(&val); |
| 92 | InterlockedDecrement(&val); |
| 93 | #else |
Xerxes Ranby | 6215c62 | 2009-07-17 19:22:41 +0000 | [diff] [blame] | 94 | volatile unsigned long val = 1; |
| 95 | __sync_synchronize(); |
| 96 | __sync_val_compare_and_swap(&val, 1, 0); |
| 97 | __sync_add_and_fetch(&val, 1); |
| 98 | __sync_sub_and_fetch(&val, 1); |
Oscar Fuentes | 87e9807 | 2009-12-05 23:19:33 +0000 | [diff] [blame] | 99 | #endif |
Xerxes Ranby | 6215c62 | 2009-07-17 19:22:41 +0000 | [diff] [blame] | 100 | return 0; |
| 101 | } |
Eric Christopher | 627445f | 2011-09-19 20:43:23 +0000 | [diff] [blame] | 102 | " LLVM_HAS_ATOMICS) |
Xerxes Ranby | 6215c62 | 2009-07-17 19:22:41 +0000 | [diff] [blame] | 103 | |
Eric Christopher | 627445f | 2011-09-19 20:43:23 +0000 | [diff] [blame] | 104 | if( NOT LLVM_HAS_ATOMICS ) |
Xerxes Ranby | 6215c62 | 2009-07-17 19:22:41 +0000 | [diff] [blame] | 105 | message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing") |
| 106 | endif() |