feature request #3432362 (native AtomicCounter for GCC)

This commit is contained in:
Marian Krivos
2011-11-04 12:52:31 +00:00
parent 650d804f1d
commit 5084562770
2 changed files with 116 additions and 5 deletions

View File

@@ -42,11 +42,13 @@
#include "Poco/Foundation.h" #include "Poco/Foundation.h"
#if POCO_OS == POCO_OS_WINDOWS_NT #if POCO_OS == POCO_OS_WINDOWS_NT
#include "Poco/UnWindows.h" #include "Poco/UnWindows.h"
#elif POCO_OS == POCO_OS_MAC_OS_X #elif POCO_OS == POCO_OS_MAC_OS_X
#include <libkern/OSAtomic.h> #include <libkern/OSAtomic.h>
#elif (POCO_OS == POCO_OS_LINUX) && ((POCO_ARCH == POCO_ARCH_IA32) || (POCO_ARCH == POCO_ARCH_AMD64)) && defined(__GNUC__)
#define POCO_ARCH_GCC_INTEL_X32_64 1
#else #else
#include "Poco/Mutex.h" #include "Poco/Mutex.h"
#endif // POCO_OS #endif // POCO_OS
@@ -117,9 +119,11 @@ public:
private: private:
#if POCO_OS == POCO_OS_WINDOWS_NT #if POCO_OS == POCO_OS_WINDOWS_NT
typedef volatile LONG ImplType; typedef LONG ImplType;
#elif POCO_OS == POCO_OS_MAC_OS_X #elif POCO_OS == POCO_OS_MAC_OS_X
typedef int32_t ImplType; typedef int32_t ImplType;
#elif defined(POCO_ARCH_GCC_INTEL_X32_64)
typedef int ImplType;
#else // generic implementation based on FastMutex #else // generic implementation based on FastMutex
struct ImplType struct ImplType
{ {
@@ -128,7 +132,7 @@ private:
}; };
#endif // POCO_OS #endif // POCO_OS
ImplType _counter; volatile ImplType _counter;
}; };
@@ -233,6 +237,72 @@ inline bool AtomicCounter::operator ! () const
} }
#elif defined(POCO_ARCH_GCC_INTEL_X32_64)
//
// Generic Intel & GCC
//
//
// From boost atomic_count_gcc_x86
//
inline int poco_atomic_exchange_and_add( volatile int * pw, int dv )
{
int r;
__asm__ __volatile__
(
"lock\n\t"
"xadd %1, %0":
"+m"( *pw ), "=r"( r ): // outputs (%0, %1)
"1"( dv ): // inputs (%2 == %1)
"memory", "cc" // clobbers
);
return r;
}
inline AtomicCounter::operator AtomicCounter::ValueType () const
{
return _counter;
}
inline AtomicCounter::ValueType AtomicCounter::value() const
{
return _counter;
}
inline AtomicCounter::ValueType AtomicCounter::operator ++ () // prefix
{
return poco_atomic_exchange_and_add( &_counter, +1 ) + 1;
}
inline AtomicCounter::ValueType AtomicCounter::operator ++ (int) // postfix
{
return poco_atomic_exchange_and_add( &_counter, +1 );
}
inline AtomicCounter::ValueType AtomicCounter::operator -- () // prefix
{
return poco_atomic_exchange_and_add( &_counter, -1 ) - 1;
}
inline AtomicCounter::ValueType AtomicCounter::operator -- (int) // postfix
{
return poco_atomic_exchange_and_add( &_counter, -1 );
}
inline bool AtomicCounter::operator ! () const
{
return _counter == 0;
}
#else #else
// //
// Generic implementation based on FastMutex // Generic implementation based on FastMutex

View File

@@ -122,6 +122,47 @@ AtomicCounter& AtomicCounter::operator = (AtomicCounter::ValueType value)
} }
#elif defined(POCO_ARCH_GCC_INTEL_X32_64)
//
// GCC & Linux
//
AtomicCounter::AtomicCounter():
_counter(0)
{
}
AtomicCounter::AtomicCounter(AtomicCounter::ValueType initialValue):
_counter(initialValue)
{
}
AtomicCounter::AtomicCounter(const AtomicCounter& counter):
_counter(counter.value())
{
}
AtomicCounter::~AtomicCounter()
{
}
AtomicCounter& AtomicCounter::operator = (const AtomicCounter& counter)
{
_counter = counter.value();
return *this;
}
AtomicCounter& AtomicCounter::operator = (AtomicCounter::ValueType value)
{
_counter = value;
return *this;
}
#else #else
// //
// Generic implementation based on FastMutex // Generic implementation based on FastMutex