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.
"
This commit is contained in:
Robert Osfield
2008-10-27 10:42:58 +00:00
parent b1c858d8f8
commit d703c58936
8 changed files with 212 additions and 27 deletions

View File

@@ -23,6 +23,9 @@
#define _OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
# include <atomic.h>
#elif defined(_OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)
# include <libkern/OSAtomic.h>
# define _OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
# include "Mutex"
# include "ScopedLock"
@@ -46,6 +49,10 @@ class OPENTHREAD_EXPORT_DIRECTIVE Atomic {
{ }
_OPENTHREADS_ATOMIC_INLINE unsigned operator++();
_OPENTHREADS_ATOMIC_INLINE unsigned operator--();
_OPENTHREADS_ATOMIC_INLINE unsigned AND(unsigned value);
_OPENTHREADS_ATOMIC_INLINE unsigned OR(unsigned value);
_OPENTHREADS_ATOMIC_INLINE unsigned XOR(unsigned value);
_OPENTHREADS_ATOMIC_INLINE unsigned exchange(unsigned value = 0);
_OPENTHREADS_ATOMIC_INLINE operator unsigned() const;
private:
@@ -57,6 +64,8 @@ class OPENTHREAD_EXPORT_DIRECTIVE Atomic {
#endif
#if defined(_OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED)
volatile long _value;
#elif defined(_OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)
volatile int32_t _value;
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
volatile uint_t _value;
#else
@@ -125,6 +134,84 @@ Atomic::operator--()
#endif
}
_OPENTHREADS_ATOMIC_INLINE unsigned
Atomic::AND(unsigned value)
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
return __sync_fetch_and_and(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
return __and_and_fetch(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
return atomic_and_uint_nv(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
ScopedLock<Mutex> lock(_mutex);
_value &= value;
return _value;
#else
_value &= value;
return _value;
#endif
}
_OPENTHREADS_ATOMIC_INLINE unsigned
Atomic::OR(unsigned value)
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
return __sync_fetch_and_or(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
return __or_and_fetch(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
return atomic_or_uint_nv(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
ScopedLock<Mutex> lock(_mutex);
_value |= value;
return _value;
#else
_value |= value;
return _value;
#endif
}
_OPENTHREADS_ATOMIC_INLINE unsigned
Atomic::XOR(unsigned value)
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
return __sync_fetch_and_xor(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
return __xor_and_fetch(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
return atomic_xor_uint_nv(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
ScopedLock<Mutex> lock(_mutex);
_value ^= value;
return _value;
#else
_value ^= value;
return _value;
#endif
}
_OPENTHREADS_ATOMIC_INLINE unsigned
Atomic::exchange(unsigned value)
{
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
return __sync_lock_test_and_set(&_value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
return __compare_and_swap(&_value, _value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
return atomic_cas_uint(&_value, _value, value);
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
ScopedLock<Mutex> lock(_mutex);
unsigned oldval = _value;
_value = value;
return oldval;
#else
unsigned oldval = _value;
_value = value;
return oldval;
#endif
}
_OPENTHREADS_ATOMIC_INLINE
Atomic::operator unsigned() const
{

View File

@@ -14,6 +14,7 @@
#ifndef _OPENTHREAD_EXPORTS_H_
#define _OPENTHREAD_EXPORTS_H_
#include <OpenThreads/Config>
#ifndef WIN32
#define OPENTHREAD_EXPORT_DIRECTIVE