X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/eb096b8eebb7497554c4fc8921a0c8ffef1fbddd..8d4ff849370781952d46cd78eb628a575ab3c688:/include/wx/atomic.h diff --git a/include/wx/atomic.h b/include/wx/atomic.h index c2cdc62345..9b7efacd68 100644 --- a/include/wx/atomic.h +++ b/include/wx/atomic.h @@ -25,46 +25,50 @@ #if wxUSE_THREADS -#if defined(__WXMSW__) +#if defined(HAVE_GCC_ATOMIC_BUILTINS) -// include standard Windows headers -#include "wx/msw/wrapwin.h" +// NB: we intentionally don't use Linux's asm/atomic.h header, because it's +// an internal kernel header that doesn't always work in userspace: +// http://bugs.mysql.com/bug.php?id=28456 +// http://golubenco.org/blog/atomic-operations/ inline void wxAtomicInc (wxUint32 &value) { - InterlockedIncrement ((LONG*)&value); + __sync_fetch_and_add(&value, 1); } inline wxUint32 wxAtomicDec (wxUint32 &value) { - return InterlockedDecrement ((LONG*)&value); + return __sync_sub_and_fetch(&value, 1); } -#elif defined(__WXMAC__) || defined(__DARWIN__) -#include "libkern/OSAtomic.h" +#elif defined(__WXMSW__) + +// include standard Windows headers +#include "wx/msw/wrapwin.h" + inline void wxAtomicInc (wxUint32 &value) { - OSAtomicIncrement32 ((int32_t*)&value); + InterlockedIncrement ((LONG*)&value); } inline wxUint32 wxAtomicDec (wxUint32 &value) { - return OSAtomicDecrement32 ((int32_t*)&value); + return InterlockedDecrement ((LONG*)&value); } -#elif defined(__LINUX__) - -#include +#elif defined(__WXMAC__) || defined(__DARWIN__) +#include "libkern/OSAtomic.h" inline void wxAtomicInc (wxUint32 &value) { - atomic_inc ((atomic_t*)&value); + OSAtomicIncrement32 ((int32_t*)&value); } inline wxUint32 wxAtomicDec (wxUint32 &value) { - return atomic_dec_and_test ((atomic_t*)&value) ? 0 : 1; + return OSAtomicDecrement32 ((int32_t*)&value); } #elif defined (__SOLARIS__) @@ -84,7 +88,7 @@ inline wxUint32 wxAtomicDec (wxUint32 &value) #else // unknown platform // it will result in inclusion if the generic implementation code a bit later in this page -#define wxHAS_GENERIC_ATOMIC_OPS 1 +#define wxNEEDS_GENERIC_ATOMIC_OPS #endif // unknown platform @@ -101,11 +105,8 @@ inline wxUint32 wxAtomicDec (wxUint32 &value) { return --value; } // behaviour // ---------------------------------------------------------------------------- -#if !defined(wxHAS_GENERIC_ATOMIC_OPS) -#define wxHAS_GENERIC_ATOMIC_OPS 0 -#endif +#ifdef wxNEEDS_GENERIC_ATOMIC_OPS -#if wxHAS_GENERIC_ATOMIC_OPS #include "wx/thread.h" // for wxCriticalSection class wxAtomicInt32 @@ -113,6 +114,7 @@ class wxAtomicInt32 public: wxAtomicInt32() { } // non initialized for consistency with basic int type wxAtomicInt32(wxInt32 v) : m_value(v) { } + wxAtomicInt32(const wxAtomicInt32& a) : m_value(a.m_value) {} operator wxInt32() const { return m_value; } operator volatile wxInt32&() { return m_value; } @@ -134,21 +136,21 @@ public: private: volatile wxInt32 m_value; wxCriticalSection m_locker; - - DECLARE_NO_COPY_CLASS(wxAtomicInt32) }; inline void wxAtomicInc(wxAtomicInt32 &value) { value.Inc(); } inline wxInt32 wxAtomicDec(wxAtomicInt32 &value) { return value.Dec(); } -#else // !wxHAS_GENERIC_ATOMIC_OPS +#else // !wxNEEDS_GENERIC_ATOMIC_OPS + +#define wxHAS_ATOMIC_OPS inline void wxAtomicInc(wxInt32 &value) { wxAtomicInc((wxUint32&)value); } inline wxInt32 wxAtomicDec(wxInt32 &value) { return wxAtomicDec((wxUint32&)value); } typedef wxInt32 wxAtomicInt32; -#endif // wxHAS_GENERIC_ATOMIC_OPS +#endif // wxNEEDS_GENERIC_ATOMIC_OPS // all the native implementations use 32 bits currently // for a 64 bits implementation we could use (a future) wxAtomicInt64 as