implementation of the atomic increment and decrement into a implementation file. This way inlining and compiler optimization can no longer happen for these implementations, but it fixes compilation on win32 msvc targets. I expect that this is still faster than with with mutexes. Also the i386 gcc target gets atomic operations with this patch. By using an implementation file we can guarantee that we have the right compiler flags available."
95 lines
2.4 KiB
CMake
95 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);
|
|
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)
|