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.}
#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
// 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
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
/**
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}
*/
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
// ----------------------------------------------------------------------------
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()
{
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;
}
}