define wxHAS_ATOMIC_OPS only if native implementation is available; use fewer loop iterations in the test if it isn't as otherwise the test takes way too long to run
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@53954 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -188,6 +188,10 @@ the corresponding feature is available and not defined at all otherwise.
|
|||||||
Currently the following symbols exist:
|
Currently the following symbols exist:
|
||||||
|
|
||||||
@beginDefList
|
@beginDefList
|
||||||
|
@itemdef{wxHAS_ATOMIC_OPS, Defined if wxAtomicInc() and wxAtomicDec() functions
|
||||||
|
have an efficient (CPU-specific) implementation. Notice that the functions
|
||||||
|
themselves are always available but can be prohibitively slow to use when
|
||||||
|
implemented in a generic way, using a critical section.}
|
||||||
@itemdef{wxHAS_LARGE_FILES, Defined if wxFile supports files more than 4GB in size.}
|
@itemdef{wxHAS_LARGE_FILES, Defined if wxFile supports files more than 4GB in size.}
|
||||||
@itemdef{wxHAS_LARGE_FFILES, Defined if wxFFile supports files more than 4GB in size.}
|
@itemdef{wxHAS_LARGE_FFILES, Defined if wxFFile supports files more than 4GB in size.}
|
||||||
@itemdef{wxHAS_POWER_EVENTS, Defined if wxPowerEvent are ever generated on the current platform.}
|
@itemdef{wxHAS_POWER_EVENTS, Defined if wxPowerEvent are ever generated on the current platform.}
|
||||||
|
@@ -88,7 +88,7 @@ inline wxUint32 wxAtomicDec (wxUint32 &value)
|
|||||||
#else // unknown platform
|
#else // unknown platform
|
||||||
|
|
||||||
// it will result in inclusion if the generic implementation code a bit later in this page
|
// 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
|
#endif // unknown platform
|
||||||
|
|
||||||
@@ -105,11 +105,8 @@ inline wxUint32 wxAtomicDec (wxUint32 &value) { return --value; }
|
|||||||
// behaviour
|
// behaviour
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if !defined(wxHAS_GENERIC_ATOMIC_OPS)
|
#ifdef wxNEEDS_GENERIC_ATOMIC_OPS
|
||||||
#define wxHAS_GENERIC_ATOMIC_OPS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if wxHAS_GENERIC_ATOMIC_OPS
|
|
||||||
#include "wx/thread.h" // for wxCriticalSection
|
#include "wx/thread.h" // for wxCriticalSection
|
||||||
|
|
||||||
class wxAtomicInt32
|
class wxAtomicInt32
|
||||||
@@ -144,14 +141,16 @@ private:
|
|||||||
inline void wxAtomicInc(wxAtomicInt32 &value) { value.Inc(); }
|
inline void wxAtomicInc(wxAtomicInt32 &value) { value.Inc(); }
|
||||||
inline wxInt32 wxAtomicDec(wxAtomicInt32 &value) { return value.Dec(); }
|
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 void wxAtomicInc(wxInt32 &value) { wxAtomicInc((wxUint32&)value); }
|
||||||
inline wxInt32 wxAtomicDec(wxInt32 &value) { return wxAtomicDec((wxUint32&)value); }
|
inline wxInt32 wxAtomicDec(wxInt32 &value) { return wxAtomicDec((wxUint32&)value); }
|
||||||
|
|
||||||
typedef wxInt32 wxAtomicInt32;
|
typedef wxInt32 wxAtomicInt32;
|
||||||
|
|
||||||
#endif // wxHAS_GENERIC_ATOMIC_OPS
|
#endif // wxNEEDS_GENERIC_ATOMIC_OPS
|
||||||
|
|
||||||
// all the native implementations use 32 bits currently
|
// all the native implementations use 32 bits currently
|
||||||
// for a 64 bits implementation we could use (a future) wxAtomicInt64 as
|
// for a 64 bits implementation we could use (a future) wxAtomicInt64 as
|
||||||
|
@@ -17,14 +17,23 @@
|
|||||||
/**
|
/**
|
||||||
This function increments @a value in an atomic manner.
|
This function increments @a value in an atomic manner.
|
||||||
|
|
||||||
|
Whenever possible wxWidgets provides an efficient, CPU-specific,
|
||||||
|
implementation of this function. If such implementation is available, the
|
||||||
|
symbol wxHAS_ATOMIC_OPS is defined. Otherwise this function still exists
|
||||||
|
but is implemented in a generic way using a critical section which can be
|
||||||
|
prohibitively expensive for use in performance-sensitive code.
|
||||||
|
|
||||||
@header{wx/atomic.h}
|
@header{wx/atomic.h}
|
||||||
*/
|
*/
|
||||||
void wxAtomicInc(wxAtomicInt& value);
|
void wxAtomicInc(wxAtomicInt& value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This function decrements value in an atomic manner. Returns 0 if value is 0
|
This function decrements value in an atomic manner.
|
||||||
after decrementation or any non-zero value (not necessarily equal to the
|
|
||||||
value of the variable) otherwise.
|
Returns 0 if value is 0 after decrement or any non-zero value (not
|
||||||
|
necessarily equal to the value of the variable) otherwise.
|
||||||
|
|
||||||
|
@see wxAtomicInc
|
||||||
|
|
||||||
@header{wx/atomic.h}
|
@header{wx/atomic.h}
|
||||||
*/
|
*/
|
||||||
|
@@ -27,6 +27,18 @@
|
|||||||
|
|
||||||
WX_DEFINE_ARRAY_PTR(wxThread *, wxArrayThread);
|
WX_DEFINE_ARRAY_PTR(wxThread *, wxArrayThread);
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// constants
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// number of times to run the loops: the code takes too long to run if we use
|
||||||
|
// the bigger value with generic atomic operations implementation
|
||||||
|
#ifdef wxHAS_ATOMIC_OPS
|
||||||
|
static const wxInt32 ITERATIONS_NUM = 10000000;
|
||||||
|
#else
|
||||||
|
static const wxInt32 ITERATIONS_NUM = 1000;
|
||||||
|
#endif
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// test class
|
// test class
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -86,16 +98,17 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AtomicTestCase, "AtomicTestCase" );
|
|||||||
|
|
||||||
void AtomicTestCase::TestNoThread()
|
void AtomicTestCase::TestNoThread()
|
||||||
{
|
{
|
||||||
wxAtomicInt int1=0, int2=0;
|
wxAtomicInt int1 = 0,
|
||||||
|
int2 = 0;
|
||||||
|
|
||||||
for (wxInt32 i=0; i<10000000; ++i)
|
for ( wxInt32 i = 0; i < ITERATIONS_NUM; ++i )
|
||||||
{
|
{
|
||||||
wxAtomicInc(int1);
|
wxAtomicInc(int1);
|
||||||
wxAtomicDec(int2);
|
wxAtomicDec(int2);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPPUNIT_ASSERT( int1 == 10000000 );
|
CPPUNIT_ASSERT( int1 == ITERATIONS_NUM );
|
||||||
CPPUNIT_ASSERT( int2 == -10000000 );
|
CPPUNIT_ASSERT( int2 == -ITERATIONS_NUM );
|
||||||
}
|
}
|
||||||
|
|
||||||
void AtomicTestCase::TestDecReturn()
|
void AtomicTestCase::TestDecReturn()
|
||||||
@@ -160,25 +173,25 @@ void *AtomicTestCase::MyThread::Entry()
|
|||||||
{
|
{
|
||||||
wxInt32 negativeValuesSeen = 0;
|
wxInt32 negativeValuesSeen = 0;
|
||||||
|
|
||||||
for (wxInt32 i=0; i<10000000; ++i)
|
for ( wxInt32 i = 0; i < ITERATIONS_NUM; ++i )
|
||||||
{
|
{
|
||||||
switch (m_testType)
|
switch ( m_testType )
|
||||||
{
|
{
|
||||||
case AtomicTestCase::IncAndDecMixed:
|
case AtomicTestCase::IncAndDecMixed:
|
||||||
wxAtomicInc(m_operateOn);
|
wxAtomicInc(m_operateOn);
|
||||||
wxAtomicDec(m_operateOn);
|
wxAtomicDec(m_operateOn);
|
||||||
|
|
||||||
if (m_operateOn < 0)
|
if (m_operateOn < 0)
|
||||||
++negativeValuesSeen;
|
++negativeValuesSeen;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AtomicTestCase::IncOnly:
|
case AtomicTestCase::IncOnly:
|
||||||
wxAtomicInc(m_operateOn);
|
wxAtomicInc(m_operateOn);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AtomicTestCase::DecOnly:
|
case AtomicTestCase::DecOnly:
|
||||||
wxAtomicDec(m_operateOn);
|
wxAtomicDec(m_operateOn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user