X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/cde76cf2a96d43f62ecb7e18c51f73e871a6d4bd..931d6a47c32a5b4c283243cb553ce71ee2b535d5:/include/wx/atomic.h?ds=sidebyside diff --git a/include/wx/atomic.h b/include/wx/atomic.h index 9918f63ecc..1439d29484 100644 --- a/include/wx/atomic.h +++ b/include/wx/atomic.h @@ -3,7 +3,6 @@ // Purpose: functions to manipulate atomically integers and pointers // Author: Armel Asselin // Created: 12/13/2006 -// RCS-ID: $Id$ // Copyright: (c) Armel Asselin // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -25,46 +24,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(__WINDOWS__) + +// 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 +87,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,23 +104,21 @@ 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 { public: - wxAtomicInt() { } // non initialized for consistency with basic int type - wxAtomicInt(wxInt32 v) : m_value(v) { } + 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 wxInt32&() { return m_value; } + operator volatile wxInt32&() { return m_value; } - wxAtomicInt& operator=(wxInt32 v) { m_value = v; return *this; } + wxAtomicInt32& operator=(wxInt32 v) { m_value = v; return *this; } void Inc() { @@ -136,17 +137,19 @@ private: wxCriticalSection m_locker; }; -inline void wxAtomicInc(wxAtomicInt &value) { value.Inc(); } -inline wxInt32 wxAtomicDec(wxAtomicInt &value) { return value.Dec(); } +inline void wxAtomicInc(wxAtomicInt32 &value) { value.Inc(); } +inline wxInt32 wxAtomicDec(wxAtomicInt32 &value) { return value.Dec(); } + +#else // !wxNEEDS_GENERIC_ATOMIC_OPS -#else // !wxHAS_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