diff --git a/CMakeModules/CheckAtomicOps.cmake b/CMakeModules/CheckAtomicOps.cmake index 3815d7568..e37532f32 100644 --- a/CMakeModules/CheckAtomicOps.cmake +++ b/CMakeModules/CheckAtomicOps.cmake @@ -2,121 +2,136 @@ # This module defines # OPENTHREADS_HAVE_ATOMIC_OPS -INCLUDE(CheckCXXSourceRuns) +OPTION(OPENTHREADS_ATOMIC_USE_MUTEX "Set to ON to force OpenThreads to use a mutex for Atmoic." OFF) -# Do step by step checking, -CHECK_CXX_SOURCE_RUNS(" -#include +IF (OPENTHREADS_ATOMIC_USE_MUTEX) -int main() -{ - unsigned value = 0; - void* ptr = &value; - __sync_add_and_fetch(&value, 1); - __sync_synchronize(); - __sync_sub_and_fetch(&value, 1); - if (!__sync_bool_compare_and_swap(&value, 0, 1)) - return EXIT_FAILURE; - - if (!__sync_bool_compare_and_swap(&ptr, ptr, ptr)) - return EXIT_FAILURE; + SET(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS 0) + SET(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS 0) + SET(_OPENTHREADS_ATOMIC_USE_SUN 0) + SET(_OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED 0) + SET(_OPENTHREADS_ATOMIC_USE_BSD_ATOMIC 0) - return EXIT_SUCCESS; -} -" _OPENTHREADS_ATOMIC_USE_GCC_BUILTINS) + SET(_OPENTHREADS_ATOMIC_USE_MUTEX 1) -CHECK_CXX_SOURCE_RUNS(" -#include +ELSE() -int main(int, const char**) -{ - unsigned value = 0; - void* ptr = &value; - __add_and_fetch(&value, 1); - __synchronize(value); - __sub_and_fetch(&value, 1); - if (!__compare_and_swap(&value, 0, 1)) - return EXIT_FAILURE; - - if (!__compare_and_swap((unsigned long*)&ptr, (unsigned long)ptr, (unsigned long)ptr)) - return EXIT_FAILURE; + INCLUDE(CheckCXXSourceRuns) - return EXIT_SUCCESS; -} -" _OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS) + # Do step by step checking, + CHECK_CXX_SOURCE_RUNS(" + #include -CHECK_CXX_SOURCE_RUNS(" -#include -#include + int main() + { + unsigned value = 0; + void* ptr = &value; + __sync_add_and_fetch(&value, 1); + __sync_synchronize(); + __sync_sub_and_fetch(&value, 1); + if (!__sync_bool_compare_and_swap(&value, 0, 1)) + return EXIT_FAILURE; -int main(int, const char**) -{ - uint_t value = 0; - void* ptr = &value; - atomic_inc_uint_nv(&value); - membar_consumer(); - atomic_dec_uint_nv(&value); - if (0 != atomic_cas_uint(&value, 0, 1)) - return EXIT_FAILURE; - - if (ptr != atomic_cas_ptr(&ptr, ptr, ptr)) - return EXIT_FAILURE; + if (!__sync_bool_compare_and_swap(&ptr, ptr, ptr)) + return EXIT_FAILURE; - return EXIT_SUCCESS; -} -" _OPENTHREADS_ATOMIC_USE_SUN) + return EXIT_SUCCESS; + } + " _OPENTHREADS_ATOMIC_USE_GCC_BUILTINS) -CHECK_CXX_SOURCE_RUNS(" -#include -#include -#include + CHECK_CXX_SOURCE_RUNS(" + #include -#pragma intrinsic(_InterlockedAnd) -#pragma intrinsic(_InterlockedOr) -#pragma intrinsic(_InterlockedXor) + int main(int, const char**) + { + unsigned value = 0; + void* ptr = &value; + __add_and_fetch(&value, 1); + __synchronize(value); + __sub_and_fetch(&value, 1); + if (!__compare_and_swap(&value, 0, 1)) + return EXIT_FAILURE; -int main(int, const char**) -{ - volatile long value = 0; - long data = 0; - long* volatile ptr = &data; + if (!__compare_and_swap((unsigned long*)&ptr, (unsigned long)ptr, (unsigned long)ptr)) + return EXIT_FAILURE; - InterlockedIncrement(&value); - MemoryBarrier(); - InterlockedDecrement(&value); + return EXIT_SUCCESS; + } + " _OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS) - if (0 != InterlockedCompareExchange(&value, 1, 0)) - return EXIT_FAILURE; + CHECK_CXX_SOURCE_RUNS(" + #include + #include - if (ptr != InterlockedCompareExchangePointer((PVOID volatile*)&ptr, (PVOID)ptr, (PVOID)ptr)) - return EXIT_FAILURE; + int main(int, const char**) + { + uint_t value = 0; + void* ptr = &value; + atomic_inc_uint_nv(&value); + membar_consumer(); + atomic_dec_uint_nv(&value); + if (0 != atomic_cas_uint(&value, 0, 1)) + return EXIT_FAILURE; - return EXIT_SUCCESS; -} -" _OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED) + if (ptr != atomic_cas_ptr(&ptr, ptr, ptr)) + return EXIT_FAILURE; -CHECK_CXX_SOURCE_RUNS(" -#include + return EXIT_SUCCESS; + } + " _OPENTHREADS_ATOMIC_USE_SUN) -int main() -{ - volatile int32_t value = 0; - long data = 0; - long * volatile ptr = &data; - - OSAtomicIncrement32(&value); - OSMemoryBarrier(); - OSAtomicDecrement32(&value); - OSAtomicCompareAndSwapInt(value, 1, &value); - OSAtomicCompareAndSwapPtr(ptr, ptr, (void * volatile *)&ptr); -} -" _OPENTHREADS_ATOMIC_USE_BSD_ATOMIC) + CHECK_CXX_SOURCE_RUNS(" + #include + #include + #include + #pragma intrinsic(_InterlockedAnd) + #pragma intrinsic(_InterlockedOr) + #pragma intrinsic(_InterlockedXor) + + int main(int, const char**) + { + volatile long value = 0; + long data = 0; + long* volatile ptr = &data; + + InterlockedIncrement(&value); + MemoryBarrier(); + InterlockedDecrement(&value); + + if (0 != InterlockedCompareExchange(&value, 1, 0)) + return EXIT_FAILURE; + + if (ptr != InterlockedCompareExchangePointer((PVOID volatile*)&ptr, (PVOID)ptr, (PVOID)ptr)) + return EXIT_FAILURE; + + return EXIT_SUCCESS; + } + " _OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED) + + CHECK_CXX_SOURCE_RUNS(" + #include + + int main() + { + volatile int32_t value = 0; + long data = 0; + long * volatile ptr = &data; + + OSAtomicIncrement32(&value); + OSMemoryBarrier(); + OSAtomicDecrement32(&value); + OSAtomicCompareAndSwapInt(value, 1, &value); + OSAtomicCompareAndSwapPtr(ptr, ptr, (void * volatile *)&ptr); + } + " _OPENTHREADS_ATOMIC_USE_BSD_ATOMIC) + + IF(NOT _OPENTHREADS_ATOMIC_USE_GCC_BUILTINS AND + NOT _OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS AND + NOT _OPENTHREADS_ATOMIC_USE_SUN AND + NOT _OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED AND + NOT _OPENTHREADS_ATOMIC_USE_BSD_ATOMIC) + SET(_OPENTHREADS_ATOMIC_USE_MUTEX 1) + ENDIF() -IF(NOT _OPENTHREADS_ATOMIC_USE_GCC_BUILTINS AND - NOT _OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS AND - NOT _OPENTHREADS_ATOMIC_USE_SUN AND - NOT _OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED AND - NOT _OPENTHREADS_ATOMIC_USE_BSD_ATOMIC) - SET(_OPENTHREADS_ATOMIC_USE_MUTEX 1) ENDIF()