2008-06-18 01:43:59 +08:00
|
|
|
/* -*-c++-*- OpenThreads library, Copyright (C) 2008 The Open Thread Group
|
|
|
|
*
|
2009-11-20 00:53:29 +08:00
|
|
|
* This library is open source and may be redistributed and/or modified under
|
|
|
|
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
2008-06-18 01:43:59 +08:00
|
|
|
* (at your option) any later version. The full license is in LICENSE file
|
|
|
|
* included with this distribution, and on the openscenegraph.org website.
|
2009-11-20 00:53:29 +08:00
|
|
|
*
|
2008-06-18 01:43:59 +08:00
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2009-11-20 00:53:29 +08:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2008-06-18 01:43:59 +08:00
|
|
|
* OpenSceneGraph Public License for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _OPENTHREADS_ATOMIC_
|
|
|
|
#define _OPENTHREADS_ATOMIC_
|
|
|
|
|
|
|
|
#include <OpenThreads/Config>
|
2008-06-26 18:27:16 +08:00
|
|
|
#include <OpenThreads/Exports>
|
2008-06-18 01:43:59 +08:00
|
|
|
|
2010-01-08 01:20:55 +08:00
|
|
|
#if defined(_OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)
|
|
|
|
# include <libkern/OSAtomic.h>
|
|
|
|
# define _OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES
|
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS) && defined(__i386__)
|
|
|
|
# define _OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES
|
2008-06-26 18:27:16 +08:00
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED)
|
2010-01-08 01:20:55 +08:00
|
|
|
# define _OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES
|
2008-06-18 01:43:59 +08:00
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
|
|
|
|
# include <atomic.h>
|
2009-01-08 19:15:14 +08:00
|
|
|
# include "Mutex"
|
|
|
|
# include "ScopedLock"
|
2008-06-18 01:43:59 +08:00
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
|
|
|
|
# include "Mutex"
|
|
|
|
# include "ScopedLock"
|
|
|
|
#endif
|
|
|
|
|
2008-06-26 18:27:16 +08:00
|
|
|
#if defined(_OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES)
|
|
|
|
#define _OPENTHREADS_ATOMIC_INLINE
|
|
|
|
#else
|
|
|
|
#define _OPENTHREADS_ATOMIC_INLINE inline
|
|
|
|
#endif
|
|
|
|
|
2008-06-18 01:43:59 +08:00
|
|
|
namespace OpenThreads {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @class Atomic
|
|
|
|
* @brief This class provides an atomic increment and decrement operation.
|
|
|
|
*/
|
2008-06-26 18:27:16 +08:00
|
|
|
class OPENTHREAD_EXPORT_DIRECTIVE Atomic {
|
2008-06-18 01:43:59 +08:00
|
|
|
public:
|
|
|
|
Atomic(unsigned value = 0) : _value(value)
|
|
|
|
{ }
|
2008-06-26 18:27:16 +08:00
|
|
|
_OPENTHREADS_ATOMIC_INLINE unsigned operator++();
|
|
|
|
_OPENTHREADS_ATOMIC_INLINE unsigned operator--();
|
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
|
|
|
_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);
|
2008-06-26 18:27:16 +08:00
|
|
|
_OPENTHREADS_ATOMIC_INLINE operator unsigned() const;
|
2008-06-18 01:43:59 +08:00
|
|
|
private:
|
2008-06-19 21:28:33 +08:00
|
|
|
|
2008-06-18 01:43:59 +08:00
|
|
|
Atomic(const Atomic&);
|
|
|
|
Atomic& operator=(const Atomic&);
|
2009-11-20 00:53:29 +08:00
|
|
|
|
2008-06-18 01:43:59 +08:00
|
|
|
#if defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
|
|
|
|
mutable Mutex _mutex;
|
|
|
|
#endif
|
|
|
|
#if defined(_OPENTHREADS_ATOMIC_USE_WIN32_INTERLOCKED)
|
2008-06-23 22:51:34 +08:00
|
|
|
volatile long _value;
|
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
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_BSD_ATOMIC)
|
|
|
|
volatile int32_t _value;
|
2008-06-18 01:43:59 +08:00
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
|
|
|
|
volatile uint_t _value;
|
2009-01-08 19:15:14 +08:00
|
|
|
mutable Mutex _mutex; // needed for xor
|
2008-06-18 01:43:59 +08:00
|
|
|
#else
|
|
|
|
volatile unsigned _value;
|
|
|
|
#endif
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @class AtomicPtr
|
|
|
|
* @brief This class provides an atomic pointer assignment using cas operations.
|
|
|
|
*/
|
2008-06-26 18:27:16 +08:00
|
|
|
class OPENTHREAD_EXPORT_DIRECTIVE AtomicPtr {
|
2008-06-18 01:43:59 +08:00
|
|
|
public:
|
2008-06-26 18:27:16 +08:00
|
|
|
AtomicPtr(void* ptr = 0) : _ptr(ptr)
|
2008-06-18 01:43:59 +08:00
|
|
|
{ }
|
|
|
|
~AtomicPtr()
|
|
|
|
{ _ptr = 0; }
|
|
|
|
|
|
|
|
// assigns a new pointer
|
2008-06-26 18:27:16 +08:00
|
|
|
_OPENTHREADS_ATOMIC_INLINE bool assign(void* ptrNew, const void* const ptrOld);
|
|
|
|
_OPENTHREADS_ATOMIC_INLINE void* get() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
AtomicPtr(const AtomicPtr&);
|
|
|
|
AtomicPtr& operator=(const AtomicPtr&);
|
|
|
|
|
|
|
|
#if defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
|
|
|
|
mutable Mutex _mutex;
|
|
|
|
#endif
|
|
|
|
void* volatile _ptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
#if !defined(_OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES)
|
|
|
|
|
|
|
|
_OPENTHREADS_ATOMIC_INLINE unsigned
|
|
|
|
Atomic::operator++()
|
|
|
|
{
|
2008-06-18 01:43:59 +08:00
|
|
|
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
|
2008-06-26 18:27:16 +08:00
|
|
|
return __sync_add_and_fetch(&_value, 1);
|
2008-06-18 01:43:59 +08:00
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
|
2008-06-26 18:27:16 +08:00
|
|
|
return __add_and_fetch(&_value, 1);
|
2008-06-18 01:43:59 +08:00
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
|
2008-06-26 18:27:16 +08:00
|
|
|
return atomic_inc_uint_nv(&_value);
|
2008-06-18 01:43:59 +08:00
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
|
2008-06-26 18:27:16 +08:00
|
|
|
ScopedLock<Mutex> lock(_mutex);
|
|
|
|
return ++_value;
|
2008-06-18 01:43:59 +08:00
|
|
|
#else
|
2008-06-26 18:27:16 +08:00
|
|
|
return ++_value;
|
2008-06-18 01:43:59 +08:00
|
|
|
#endif
|
2008-06-26 18:27:16 +08:00
|
|
|
}
|
2008-06-18 01:43:59 +08:00
|
|
|
|
2008-06-26 18:27:16 +08:00
|
|
|
_OPENTHREADS_ATOMIC_INLINE unsigned
|
|
|
|
Atomic::operator--()
|
|
|
|
{
|
2008-06-18 01:43:59 +08:00
|
|
|
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
|
2008-06-26 18:27:16 +08:00
|
|
|
return __sync_sub_and_fetch(&_value, 1);
|
2008-06-18 01:43:59 +08:00
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
|
2008-06-26 18:27:16 +08:00
|
|
|
return __sub_and_fetch(&_value, 1);
|
2008-06-18 01:43:59 +08:00
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
|
2008-06-26 18:27:16 +08:00
|
|
|
return atomic_dec_uint_nv(&_value);
|
2008-06-18 01:43:59 +08:00
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
|
2008-06-26 18:27:16 +08:00
|
|
|
ScopedLock<Mutex> lock(_mutex);
|
|
|
|
return --_value;
|
2008-06-18 01:43:59 +08:00
|
|
|
#else
|
2008-06-26 18:27:16 +08:00
|
|
|
return --_value;
|
2008-06-18 01:43:59 +08:00
|
|
|
#endif
|
2008-06-26 18:27:16 +08:00
|
|
|
}
|
2008-06-18 01:43:59 +08:00
|
|
|
|
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
|
|
|
_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);
|
2009-11-20 00:53:29 +08:00
|
|
|
_value |= value;
|
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
|
|
|
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)
|
2009-01-08 19:15:14 +08:00
|
|
|
ScopedLock<Mutex> lock(_mutex);
|
|
|
|
_value ^= value;
|
|
|
|
return _value;
|
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
|
|
|
#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
|
|
|
|
}
|
|
|
|
|
2008-06-26 18:27:16 +08:00
|
|
|
_OPENTHREADS_ATOMIC_INLINE
|
|
|
|
Atomic::operator unsigned() const
|
|
|
|
{
|
|
|
|
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
|
|
|
|
__sync_synchronize();
|
|
|
|
return _value;
|
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
|
|
|
|
__synchronize();
|
|
|
|
return _value;
|
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
|
|
|
|
membar_consumer(); // Hmm, do we need???
|
|
|
|
return _value;
|
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
|
|
|
|
ScopedLock<Mutex> lock(_mutex);
|
|
|
|
return _value;
|
|
|
|
#else
|
|
|
|
return _value;
|
|
|
|
#endif
|
|
|
|
}
|
2008-06-18 01:43:59 +08:00
|
|
|
|
2008-06-26 18:27:16 +08:00
|
|
|
_OPENTHREADS_ATOMIC_INLINE bool
|
|
|
|
AtomicPtr::assign(void* ptrNew, const void* const ptrOld)
|
|
|
|
{
|
|
|
|
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
|
2012-09-06 18:52:28 +08:00
|
|
|
return __sync_bool_compare_and_swap(&_ptr, (void *)ptrOld, ptrNew);
|
2008-06-26 18:27:16 +08:00
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
|
|
|
|
return __compare_and_swap((unsigned long*)&_ptr, (unsigned long)ptrOld, (unsigned long)ptrNew);
|
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
|
2009-01-08 19:16:56 +08:00
|
|
|
return ptrOld == atomic_cas_ptr(&_ptr, const_cast<void*>(ptrOld), ptrNew);
|
2008-06-26 18:27:16 +08:00
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
|
|
|
|
ScopedLock<Mutex> lock(_mutex);
|
|
|
|
if (_ptr != ptrOld)
|
|
|
|
return false;
|
|
|
|
_ptr = ptrNew;
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
if (_ptr != ptrOld)
|
|
|
|
return false;
|
|
|
|
_ptr = ptrNew;
|
|
|
|
return true;
|
2008-06-18 01:43:59 +08:00
|
|
|
#endif
|
2008-06-26 18:27:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
_OPENTHREADS_ATOMIC_INLINE void*
|
|
|
|
AtomicPtr::get() const
|
|
|
|
{
|
|
|
|
#if defined(_OPENTHREADS_ATOMIC_USE_GCC_BUILTINS)
|
|
|
|
__sync_synchronize();
|
|
|
|
return _ptr;
|
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_MIPOSPRO_BUILTINS)
|
|
|
|
__synchronize();
|
|
|
|
return _ptr;
|
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_SUN)
|
|
|
|
membar_consumer(); // Hmm, do we need???
|
|
|
|
return _ptr;
|
|
|
|
#elif defined(_OPENTHREADS_ATOMIC_USE_MUTEX)
|
|
|
|
ScopedLock<Mutex> lock(_mutex);
|
|
|
|
return _ptr;
|
|
|
|
#else
|
|
|
|
return _ptr;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // !defined(_OPENTHREADS_ATOMIC_USE_LIBRARY_ROUTINES)
|
2008-06-18 01:43:59 +08:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // _OPENTHREADS_ATOMIC_
|