From 42124e683da03a7a7463ad9e37d15fda575348af Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 2 Jun 2008 20:42:23 +0000 Subject: [PATCH] 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 --- docs/doxygen/mainpages/const_cpp.h | 4 +++ include/wx/atomic.h | 13 ++++---- interface/atomic.h | 15 +++++++-- tests/thread/atomic.cpp | 49 +++++++++++++++++++----------- 4 files changed, 53 insertions(+), 28 deletions(-) diff --git a/docs/doxygen/mainpages/const_cpp.h b/docs/doxygen/mainpages/const_cpp.h index c03215e0cb..86c85e2c27 100644 --- a/docs/doxygen/mainpages/const_cpp.h +++ b/docs/doxygen/mainpages/const_cpp.h @@ -188,6 +188,10 @@ the corresponding feature is available and not defined at all otherwise. Currently the following symbols exist: @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_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.} diff --git a/include/wx/atomic.h b/include/wx/atomic.h index 829e29bdd3..9b7efacd68 100644 --- a/include/wx/atomic.h +++ b/include/wx/atomic.h @@ -88,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 @@ -105,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 @@ -144,14 +141,16 @@ private: 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 diff --git a/interface/atomic.h b/interface/atomic.h index b2aba23510..3767cd7f0b 100644 --- a/interface/atomic.h +++ b/interface/atomic.h @@ -17,14 +17,23 @@ /** 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} */ void wxAtomicInc(wxAtomicInt& value); /** - This function decrements value in an atomic manner. Returns 0 if value is 0 - after decrementation or any non-zero value (not necessarily equal to the - value of the variable) otherwise. + 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. + + @see wxAtomicInc @header{wx/atomic.h} */ diff --git a/tests/thread/atomic.cpp b/tests/thread/atomic.cpp index 55bf3bdf2d..1170093e44 100644 --- a/tests/thread/atomic.cpp +++ b/tests/thread/atomic.cpp @@ -27,6 +27,18 @@ 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 // ---------------------------------------------------------------------------- @@ -86,16 +98,17 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AtomicTestCase, "AtomicTestCase" ); 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); wxAtomicDec(int2); } - CPPUNIT_ASSERT( int1 == 10000000 ); - CPPUNIT_ASSERT( int2 == -10000000 ); + CPPUNIT_ASSERT( int1 == ITERATIONS_NUM ); + CPPUNIT_ASSERT( int2 == -ITERATIONS_NUM ); } void AtomicTestCase::TestDecReturn() @@ -160,25 +173,25 @@ void *AtomicTestCase::MyThread::Entry() { 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: - wxAtomicInc(m_operateOn); - wxAtomicDec(m_operateOn); + case AtomicTestCase::IncAndDecMixed: + wxAtomicInc(m_operateOn); + wxAtomicDec(m_operateOn); - if (m_operateOn < 0) - ++negativeValuesSeen; - break; + if (m_operateOn < 0) + ++negativeValuesSeen; + break; - case AtomicTestCase::IncOnly: - wxAtomicInc(m_operateOn); - break; + case AtomicTestCase::IncOnly: + wxAtomicInc(m_operateOn); + break; - case AtomicTestCase::DecOnly: - wxAtomicDec(m_operateOn); - break; + case AtomicTestCase::DecOnly: + wxAtomicDec(m_operateOn); + break; } } -- 2.47.2