2008-06-18 01:43:59 +08:00
|
|
|
# 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("
|
2008-06-26 18:27:16 +08:00
|
|
|
#include <stdlib.h>
|
2008-06-18 01:43:59 +08:00
|
|
|
|
|
|
|
int main(int, const char**)
|
|
|
|
{
|
|
|
|
unsigned value = 0;
|
|
|
|
void* ptr = &value;
|
|
|
|
__add_and_fetch(&value, 1);
|
|
|
|
__synchronize(value);
|
|
|
|
__sub_and_fetch(&value, 1);
|
2008-06-26 18:27:16 +08:00
|
|
|
if (!__compare_and_swap(&value, 0, 1))
|
2008-06-18 01:43:59 +08:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
2008-06-26 18:27:16 +08:00
|
|
|
if (!__compare_and_swap((unsigned long*)&ptr, (unsigned long)ptr, (unsigned long)ptr))
|
2008-06-18 01:43:59 +08:00
|
|
|
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>
|
2008-10-29 19:51:47 +08:00
|
|
|
#include <intrin.h>
|
2008-06-18 01:43:59 +08:00
|
|
|
#include <cstdlib>
|
|
|
|
|
2008-10-29 19:51:47 +08:00
|
|
|
#pragma intrinsic(_InterlockedAnd)
|
|
|
|
#pragma intrinsic(_InterlockedOr)
|
|
|
|
#pragma intrinsic(_InterlockedXor)
|
|
|
|
|
2008-06-18 01:43:59 +08:00
|
|
|
int main(int, const char**)
|
|
|
|
{
|
2008-06-23 22:51:34 +08:00
|
|
|
volatile long value = 0;
|
|
|
|
long data = 0;
|
|
|
|
long* volatile ptr = &data;
|
2008-06-18 01:43:59 +08:00
|
|
|
|
|
|
|
InterlockedIncrement(&value);
|
2008-06-28 00:47:43 +08:00
|
|
|
MemoryBarrier();
|
2008-06-18 01:43:59 +08:00
|
|
|
InterlockedDecrement(&value);
|
|
|
|
|
|
|
|
if (0 != InterlockedCompareExchange(&value, 1, 0))
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
2008-06-23 22:51:34 +08:00
|
|
|
if (ptr != InterlockedCompareExchangePointer((PVOID volatile*)&ptr, (PVOID)ptr, (PVOID)ptr))
|
2008-06-18 01:43:59 +08:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
" _OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED)
|
|
|
|
|
From Blasius Czink, "Among other things I added support for atomic operations on BSD-like systems and additional methods (for "and", "or", "xor").
"
and a later post the same osg-submissions thread:
"it's been a while since I have made the changes but I think it was due to problems with static builds of OpenThreads on windows. I was using
OpenThreads in a communication/synchronisation library (without
OpenSceneGraph). It seems I forgot to post a small change in the CMakeLists file of OpenThreads. If a user turns DYNAMIC_OPENTHREADS to OFF (static build) OT_LIBRARY_STATIC will be defined in the Config.
Without these changes a windows user will always end up with a "__declspec(dllexport)" or "__declspec(dllimport)" which is a problem for static builds."
And another post from Blasius on this topic:
"I tested with VS2005 and VS2008. For 32 bit everything works as expected. For x64 and VS2008 I could successfully do the cmake-configure and then the compilation but I had occasional crashes of cmTryCompileExec.exe (during the cmake-configure phase) which seems to be a cmake bug. With VS2005 and 64bit cmake does not set _OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED although the interlocked functionality should be there. If I place the source snippet from the CHECK_CXX_SOURCE_RUNS macro to a separate sourcefile I can compile and run the resulting executable successfully. Forcing OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED (on VS2005/x64) reveals a bug in "intrin.h" which seems to be fixed in VS2008 but not in VS2005.
In case anyone is interested the lines:
__MACHINEI(unsigned char _interlockedbittestandset(long *a, long b))
__MACHINEI(unsigned char _interlockedbittestandreset(long *a, long b))
__MACHINEX64(unsigned char _interlockedbittestandset64(__int64 *a, __int64 b))
__MACHINEX64(unsigned char _interlockedbittestandreset64(__int64 *a, __int64 b))
should be changed to:
__MACHINEI(unsigned char _interlockedbittestandset(long volatile *a, long b))
__MACHINEI(unsigned char _interlockedbittestandreset(long volatile *a, long b))
__MACHINEX64(unsigned char _interlockedbittestandset64(__int64 volatile *a, __int64 b))
__MACHINEX64(unsigned char _interlockedbittestandreset64(__int64 volatile *a, __int64 b))
The worst thing that can happen is that interlocked funtionality is not detected during cmake-configure and the mutex fallback is used.
Which reminds me another small glitch in the Atomic header so I attached a corrected version.
Why is the OT_LIBRARY_STATIC added to the config file? It is not needed anywhere.
OT_LIBRARY_STATIC is needed if you are doing static-builds on Windows. See my previous post on that.
"
2008-10-27 18:42:58 +08:00
|
|
|
CHECK_CXX_SOURCE_RUNS("
|
|
|
|
#include <libkern/OSAtomic.h>
|
|
|
|
|
|
|
|
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)
|
2008-07-01 17:40:06 +08:00
|
|
|
SET(_OPENTHREADS_ATOMIC_USE_MUTEX 1)
|
From Blasius Czink, "Among other things I added support for atomic operations on BSD-like systems and additional methods (for "and", "or", "xor").
"
and a later post the same osg-submissions thread:
"it's been a while since I have made the changes but I think it was due to problems with static builds of OpenThreads on windows. I was using
OpenThreads in a communication/synchronisation library (without
OpenSceneGraph). It seems I forgot to post a small change in the CMakeLists file of OpenThreads. If a user turns DYNAMIC_OPENTHREADS to OFF (static build) OT_LIBRARY_STATIC will be defined in the Config.
Without these changes a windows user will always end up with a "__declspec(dllexport)" or "__declspec(dllimport)" which is a problem for static builds."
And another post from Blasius on this topic:
"I tested with VS2005 and VS2008. For 32 bit everything works as expected. For x64 and VS2008 I could successfully do the cmake-configure and then the compilation but I had occasional crashes of cmTryCompileExec.exe (during the cmake-configure phase) which seems to be a cmake bug. With VS2005 and 64bit cmake does not set _OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED although the interlocked functionality should be there. If I place the source snippet from the CHECK_CXX_SOURCE_RUNS macro to a separate sourcefile I can compile and run the resulting executable successfully. Forcing OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED (on VS2005/x64) reveals a bug in "intrin.h" which seems to be fixed in VS2008 but not in VS2005.
In case anyone is interested the lines:
__MACHINEI(unsigned char _interlockedbittestandset(long *a, long b))
__MACHINEI(unsigned char _interlockedbittestandreset(long *a, long b))
__MACHINEX64(unsigned char _interlockedbittestandset64(__int64 *a, __int64 b))
__MACHINEX64(unsigned char _interlockedbittestandreset64(__int64 *a, __int64 b))
should be changed to:
__MACHINEI(unsigned char _interlockedbittestandset(long volatile *a, long b))
__MACHINEI(unsigned char _interlockedbittestandreset(long volatile *a, long b))
__MACHINEX64(unsigned char _interlockedbittestandset64(__int64 volatile *a, __int64 b))
__MACHINEX64(unsigned char _interlockedbittestandreset64(__int64 volatile *a, __int64 b))
The worst thing that can happen is that interlocked funtionality is not detected during cmake-configure and the mutex fallback is used.
Which reminds me another small glitch in the Atomic header so I attached a corrected version.
Why is the OT_LIBRARY_STATIC added to the config file? It is not needed anywhere.
OT_LIBRARY_STATIC is needed if you are doing static-builds on Windows. See my previous post on that.
"
2008-10-27 18:42:58 +08:00
|
|
|
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 AND NOT _OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)
|