Home | History | Annotate | Download | only in modules
      1 # atomic builtins are required for threading support.
      2 
      3 INCLUDE(CheckCXXSourceCompiles)
      4 
      5 # Sometimes linking against libatomic is required for atomic ops, if
      6 # the platform doesn't support lock-free atomics.
      7 
      8 function(check_working_cxx_atomics varname)
      9   set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
     10   set(CMAKE_REQUIRED_FLAGS "-std=c++11")
     11   CHECK_CXX_SOURCE_COMPILES("
     12 #include <atomic>
     13 std::atomic<int> x;
     14 int main() {
     15   return x;
     16 }
     17 " ${varname})
     18   set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
     19 endfunction(check_working_cxx_atomics)
     20 
     21 # This isn't necessary on MSVC, so avoid command-line switch annoyance
     22 # by only running on GCC-like hosts.
     23 if (LLVM_COMPILER_IS_GCC_COMPATIBLE)
     24   # First check if atomics work without the library.
     25   check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITHOUT_LIB)
     26   # If not, check if the library exists, and atomics work with it.
     27   if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
     28     check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC)
     29     if( HAVE_LIBATOMIC )
     30       list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
     31       check_working_cxx_atomics(HAVE_CXX_ATOMICS_WITH_LIB)
     32       if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
     33 	message(FATAL_ERROR "Host compiler must support std::atomic!")
     34       endif()
     35     else()
     36       message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
     37     endif()
     38   endif()
     39 endif()
     40 
     41 ## TODO: This define is only used for the legacy atomic operations in
     42 ## llvm's Atomic.h, which should be replaced.  Other code simply
     43 ## assumes C++11 <atomic> works.
     44 CHECK_CXX_SOURCE_COMPILES("
     45 #ifdef _MSC_VER
     46 #include <Intrin.h> /* Workaround for PR19898. */
     47 #include <windows.h>
     48 #endif
     49 int main() {
     50 #ifdef _MSC_VER
     51         volatile LONG val = 1;
     52         MemoryBarrier();
     53         InterlockedCompareExchange(&val, 0, 1);
     54         InterlockedIncrement(&val);
     55         InterlockedDecrement(&val);
     56 #else
     57         volatile unsigned long val = 1;
     58         __sync_synchronize();
     59         __sync_val_compare_and_swap(&val, 1, 0);
     60         __sync_add_and_fetch(&val, 1);
     61         __sync_sub_and_fetch(&val, 1);
     62 #endif
     63         return 0;
     64       }
     65 " LLVM_HAS_ATOMICS)
     66 
     67 if( NOT LLVM_HAS_ATOMICS )
     68   message(STATUS "Warning: LLVM will be built thread-unsafe because atomic builtins are missing")
     69 endif()
     70