214491dd94
MemoryBarrier() is used in the implementation, so it should be checked. This in effect disables the faster atomic ops on msvc 7.1 and older, even if only the MemoryBarrier() call is missing. But it ensures for the fist cut that it will build everywhere. If somebody cares for msvc 7.1 enough and has one for testing installed, he might provide the apropriate defines to guard that MemoryBarrier() call. I tested that msvc8 32/64bit still passes the configure tests and compiles. "
96 lines
2.4 KiB
CMake
96 lines
2.4 KiB
CMake
# Check for availability of atomic operations
|
|
# This module defines
|
|
# OPENTHREADS_HAVE_ATOMIC_OPS
|
|
|
|
INCLUDE(CheckCXXSourceRuns)
|
|
|
|
# Do step by step checking,
|
|
CHECK_CXX_SOURCE_RUNS("
|
|
#include <cstdlib>
|
|
|
|
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;
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
" _OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
|
|
|
|
CHECK_CXX_SOURCE_RUNS("
|
|
#include <stdlib.h>
|
|
|
|
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;
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
" _OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
|
|
|
|
CHECK_CXX_SOURCE_RUNS("
|
|
#include <atomic.h>
|
|
#include <cstdlib>
|
|
|
|
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;
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
" _OPENTHREADS_ATOMIC_USE_SUN)
|
|
|
|
CHECK_CXX_SOURCE_RUNS("
|
|
#include <windows.h>
|
|
#include <cstdlib>
|
|
|
|
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)
|
|
|
|
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)
|
|
SET(_OPENTHREADS_ATOMIC_USE_MUTEX)
|
|
ENDIF(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)
|