]> git.saurik.com Git - wxWidgets.git/commitdiff
define wxHAS_ATOMIC_OPS only if native implementation is available; use fewer loop...
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 2 Jun 2008 20:42:23 +0000 (20:42 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 2 Jun 2008 20:42:23 +0000 (20:42 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@53954 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/doxygen/mainpages/const_cpp.h
include/wx/atomic.h
interface/atomic.h
tests/thread/atomic.cpp

index c03215e0cba7f9e7991ec12dd81832f9cdfc477b..86c85e2c27340b9bb7d987c37bc3e7f3435087e0 100644 (file)
@@ -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.}
index 829e29bdd34fff719534cad151c8bdec736eb3de..9b7efacd680d7cbe35fde5dcd50ddee4f55923e5 100644 (file)
@@ -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
index b2aba23510eab1e29590319553f53559835b899b..3767cd7f0ba5516cfa2b734a13774cbf92380268 100644 (file)
 /**
     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}
 */
index 55bf3bdf2d8f879c4640de42ae679f0ae9bf98c8..1170093e440001d6f62629e25e34d1f26fe2a79a 100644 (file)
 
 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;
         }
     }