Return the new value from wxAtomicInc() too
This is easy to do and can be useful when using an atomic initialization counter. The only platform where not returning the new value might be more efficient than returning it is Solaris which is not really relevant any more and on all the other platforms the functions we were already using provided this value already (or almost, in case of using gcc builtins, when we just have to use a different one).
This commit is contained in:
parent
e82290f0da
commit
cf66ce5f94
@ -6,16 +6,13 @@ AC_DEFUN([WX_ATOMIC_BUILTINS],
|
||||
[
|
||||
AC_REQUIRE([AC_PROG_CC])
|
||||
if test -n "$GCC"; then
|
||||
AC_MSG_CHECKING([for __sync_fetch_and_add and __sync_sub_and_fetch builtins])
|
||||
AC_MSG_CHECKING([for __sync_xxx_and_fetch builtins])
|
||||
AC_CACHE_VAL(wx_cv_cc_gcc_atomic_builtins, [
|
||||
AC_TRY_LINK(
|
||||
[],
|
||||
[
|
||||
unsigned int value=0;
|
||||
/* wxAtomicInc doesn't use return value here */
|
||||
__sync_fetch_and_add(&value, 2);
|
||||
__sync_sub_and_fetch(&value, 1);
|
||||
/* but wxAtomicDec does, so mimic that: */
|
||||
volatile unsigned int r1 = __sync_add_and_fetch(&value, 2);
|
||||
volatile unsigned int r2 = __sync_sub_and_fetch(&value, 1);
|
||||
],
|
||||
wx_cv_cc_gcc_atomic_builtins=yes,
|
||||
|
9
configure
vendored
9
configure
vendored
@ -25145,8 +25145,8 @@ fi
|
||||
|
||||
|
||||
if test -n "$GCC"; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __sync_fetch_and_add and __sync_sub_and_fetch builtins" >&5
|
||||
$as_echo_n "checking for __sync_fetch_and_add and __sync_sub_and_fetch builtins... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __sync_xxx_and_fetch builtins" >&5
|
||||
$as_echo_n "checking for __sync_xxx_and_fetch builtins... " >&6; }
|
||||
if ${wx_cv_cc_gcc_atomic_builtins+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
@ -25159,10 +25159,7 @@ main ()
|
||||
{
|
||||
|
||||
unsigned int value=0;
|
||||
/* wxAtomicInc doesn't use return value here */
|
||||
__sync_fetch_and_add(&value, 2);
|
||||
__sync_sub_and_fetch(&value, 1);
|
||||
/* but wxAtomicDec does, so mimic that: */
|
||||
volatile unsigned int r1 = __sync_add_and_fetch(&value, 2);
|
||||
volatile unsigned int r2 = __sync_sub_and_fetch(&value, 1);
|
||||
|
||||
;
|
||||
|
@ -17,10 +17,7 @@
|
||||
// get the value of wxUSE_THREADS configuration flag
|
||||
#include "wx/defs.h"
|
||||
|
||||
// constraints on the various functions:
|
||||
// - wxAtomicDec must return a zero value if the value is zero once
|
||||
// decremented else it must return any non-zero value (the true value is OK
|
||||
// but not necessary).
|
||||
// these functions return the new value, after the operation
|
||||
|
||||
#if wxUSE_THREADS
|
||||
|
||||
@ -31,9 +28,9 @@
|
||||
// http://bugs.mysql.com/bug.php?id=28456
|
||||
// http://golubenco.org/blog/atomic-operations/
|
||||
|
||||
inline void wxAtomicInc (wxUint32 &value)
|
||||
inline wxUint32 wxAtomicInc (wxUint32 &value)
|
||||
{
|
||||
__sync_fetch_and_add(&value, 1);
|
||||
return __sync_add_and_fetch(&value, 1);
|
||||
}
|
||||
|
||||
inline wxUint32 wxAtomicDec (wxUint32 &value)
|
||||
@ -47,9 +44,9 @@ inline wxUint32 wxAtomicDec (wxUint32 &value)
|
||||
// include standard Windows headers
|
||||
#include "wx/msw/wrapwin.h"
|
||||
|
||||
inline void wxAtomicInc (wxUint32 &value)
|
||||
inline wxUint32 wxAtomicInc (wxUint32 &value)
|
||||
{
|
||||
InterlockedIncrement ((LONG*)&value);
|
||||
return InterlockedIncrement ((LONG*)&value);
|
||||
}
|
||||
|
||||
inline wxUint32 wxAtomicDec (wxUint32 &value)
|
||||
@ -60,9 +57,9 @@ inline wxUint32 wxAtomicDec (wxUint32 &value)
|
||||
#elif defined(__DARWIN__)
|
||||
|
||||
#include "libkern/OSAtomic.h"
|
||||
inline void wxAtomicInc (wxUint32 &value)
|
||||
inline wxUint32 wxAtomicInc (wxUint32 &value)
|
||||
{
|
||||
OSAtomicIncrement32 ((int32_t*)&value);
|
||||
return OSAtomicIncrement32 ((int32_t*)&value);
|
||||
}
|
||||
|
||||
inline wxUint32 wxAtomicDec (wxUint32 &value)
|
||||
@ -76,7 +73,7 @@ inline wxUint32 wxAtomicDec (wxUint32 &value)
|
||||
|
||||
inline void wxAtomicInc (wxUint32 &value)
|
||||
{
|
||||
atomic_add_32 ((uint32_t*)&value, 1);
|
||||
return atomic_add_32_nv ((uint32_t*)&value, 1);
|
||||
}
|
||||
|
||||
inline wxUint32 wxAtomicDec (wxUint32 &value)
|
||||
@ -94,7 +91,7 @@ inline wxUint32 wxAtomicDec (wxUint32 &value)
|
||||
#else // else of wxUSE_THREADS
|
||||
// if no threads are used we can safely use simple ++/--
|
||||
|
||||
inline void wxAtomicInc (wxUint32 &value) { ++value; }
|
||||
inline wxUint32 wxAtomicInc (wxUint32 &value) { return ++value; }
|
||||
inline wxUint32 wxAtomicDec (wxUint32 &value) { return --value; }
|
||||
|
||||
#endif // !wxUSE_THREADS
|
||||
@ -120,10 +117,10 @@ public:
|
||||
|
||||
wxAtomicInt32& operator=(wxInt32 v) { m_value = v; return *this; }
|
||||
|
||||
void Inc()
|
||||
wxInt32 Inc()
|
||||
{
|
||||
wxCriticalSectionLocker lock(m_locker);
|
||||
++m_value;
|
||||
return ++m_value;
|
||||
}
|
||||
|
||||
wxInt32 Dec()
|
||||
@ -137,14 +134,14 @@ private:
|
||||
wxCriticalSection m_locker;
|
||||
};
|
||||
|
||||
inline void wxAtomicInc(wxAtomicInt32 &value) { value.Inc(); }
|
||||
inline wxInt32 wxAtomicInc(wxAtomicInt32 &value) { return value.Inc(); }
|
||||
inline wxInt32 wxAtomicDec(wxAtomicInt32 &value) { return value.Dec(); }
|
||||
|
||||
#else // !wxNEEDS_GENERIC_ATOMIC_OPS
|
||||
|
||||
#define wxHAS_ATOMIC_OPS
|
||||
|
||||
inline void wxAtomicInc(wxInt32 &value) { wxAtomicInc((wxUint32&)value); }
|
||||
inline wxInt32 wxAtomicInc(wxInt32 &value) { return wxAtomicInc((wxUint32&)value); }
|
||||
inline wxInt32 wxAtomicDec(wxInt32 &value) { return wxAtomicDec((wxUint32&)value); }
|
||||
|
||||
typedef wxInt32 wxAtomicInt32;
|
||||
|
@ -22,15 +22,18 @@
|
||||
but is implemented in a generic way using a critical section which can be
|
||||
prohibitively expensive for use in performance-sensitive code.
|
||||
|
||||
Returns the new value after the increment (the return value is only
|
||||
available since wxWidgets 3.1.7, this function doesn't return anything in
|
||||
previous versions of the library).
|
||||
|
||||
@header{wx/atomic.h}
|
||||
*/
|
||||
void wxAtomicInc(wxAtomicInt& value);
|
||||
wxInt32 wxAtomicInc(wxAtomicInt& value);
|
||||
|
||||
/**
|
||||
This function decrements value in an atomic manner.
|
||||
|
||||
Returns 0 if value is 0 after decrement or any non-zero value (not
|
||||
necessarily equal to the value of the variable) otherwise.
|
||||
Returns the new value after decrementing it.
|
||||
|
||||
@see wxAtomicInc
|
||||
|
||||
|
@ -77,15 +77,14 @@ TEST_CASE("Atomic::NoThread", "[atomic]")
|
||||
CHECK( int2 == -ITERATIONS_NUM );
|
||||
}
|
||||
|
||||
TEST_CASE("Atomic::DecReturn", "[atomic]")
|
||||
TEST_CASE("Atomic::ReturnValue", "[atomic]")
|
||||
{
|
||||
wxAtomicInt i(0);
|
||||
wxAtomicInc(i);
|
||||
wxAtomicInc(i);
|
||||
CHECK( i == 2 );
|
||||
REQUIRE( wxAtomicInc(i) == 1 );
|
||||
REQUIRE( wxAtomicInc(i) == 2 );
|
||||
|
||||
CHECK( wxAtomicDec(i) > 0 );
|
||||
CHECK( wxAtomicDec(i) == 0 );
|
||||
REQUIRE( wxAtomicDec(i) == 1 );
|
||||
REQUIRE( wxAtomicDec(i) == 0 );
|
||||
}
|
||||
|
||||
TEST_CASE("Atomic::WithThreads", "[atomic]")
|
||||
|
Loading…
Reference in New Issue
Block a user