1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/thread/atomic.cpp
3 // Purpose: wxAtomic??? unit test
4 // Author: Armel Asselin
7 // Copyright: (c) 2006 Armel Asselin
8 ///////////////////////////////////////////////////////////////////////////////
10 // ----------------------------------------------------------------------------
12 // ----------------------------------------------------------------------------
23 #include "wx/atomic.h"
24 #include "wx/thread.h"
25 #include "wx/dynarray.h"
28 WX_DEFINE_ARRAY_PTR(wxThread
*, wxArrayThread
);
30 // ----------------------------------------------------------------------------
32 // ----------------------------------------------------------------------------
34 class AtomicTestCase
: public CppUnit::TestCase
47 class MyThread
: public wxThread
50 MyThread(wxAtomicInt
&operateOn
, ETestType testType
) : wxThread(wxTHREAD_JOINABLE
),
51 m_operateOn(operateOn
), m_testType(testType
) {}
53 // thread execution starts here
54 virtual void *Entry();
57 wxAtomicInt
&m_operateOn
;
61 CPPUNIT_TEST_SUITE( AtomicTestCase
);
62 CPPUNIT_TEST( TestNoThread
);
63 CPPUNIT_TEST( TestDecReturn
);
64 CPPUNIT_TEST( TestTwoThreadsMix
);
65 CPPUNIT_TEST( TestTenThreadsMix
);
66 CPPUNIT_TEST( TestTwoThreadsSeparate
);
67 CPPUNIT_TEST( TestTenThreadsSeparate
);
68 CPPUNIT_TEST_SUITE_END();
72 void TestTenThreadsMix() { TestWithThreads(10, IncAndDecMixed
); }
73 void TestTwoThreadsMix() { TestWithThreads(2, IncAndDecMixed
); }
74 void TestTenThreadsSeparate() { TestWithThreads(10, IncOnly
); }
75 void TestTwoThreadsSeparate() { TestWithThreads(2, IncOnly
); }
76 void TestWithThreads(int count
, ETestType testtype
);
78 DECLARE_NO_COPY_CLASS(AtomicTestCase
)
81 // register in the unnamed registry so that these tests are run by default
82 CPPUNIT_TEST_SUITE_REGISTRATION( AtomicTestCase
);
84 // also include in it's own registry so that these tests can be run alone
85 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AtomicTestCase
, "AtomicTestCase" );
87 void AtomicTestCase::TestNoThread()
89 wxAtomicInt int1
=0, int2
=0;
91 for (wxInt32 i
=0; i
<10000000; ++i
)
97 CPPUNIT_ASSERT( int1
== 10000000 );
98 CPPUNIT_ASSERT( int2
== -10000000 );
101 void AtomicTestCase::TestDecReturn()
106 CPPUNIT_ASSERT( i
== 2 );
108 CPPUNIT_ASSERT( wxAtomicDec(i
) > 0 );
109 CPPUNIT_ASSERT( wxAtomicDec(i
) == 0 );
112 void AtomicTestCase::TestWithThreads(int count
, ETestType testType
)
116 wxArrayThread threads
;
119 for ( i
= 0; i
< count
; ++i
)
121 ETestType actualThreadType
;
125 actualThreadType
= testType
;
128 actualThreadType
= (i
&1)==0 ? IncOnly
: DecOnly
;
132 MyThread
*thread
= new MyThread(int1
, actualThreadType
);
134 if ( thread
->Create() != wxTHREAD_NO_ERROR
)
136 wxLogError(wxT("Can't create thread!"));
142 for ( i
= 0; i
< count
; ++i
)
148 for ( i
= 0; i
< count
; ++i
)
150 // each thread should return 0, else it detected some problem
151 CPPUNIT_ASSERT (threads
[i
]->Wait() == (wxThread::ExitCode
)0);
154 CPPUNIT_ASSERT( int1
== 0 );
157 // ----------------------------------------------------------------------------
159 void *AtomicTestCase::MyThread::Entry()
161 wxInt32 negativeValuesSeen
= 0;
163 for (wxInt32 i
=0; i
<10000000; ++i
)
167 case AtomicTestCase::IncAndDecMixed
:
168 wxAtomicInc(m_operateOn
);
169 wxAtomicDec(m_operateOn
);
172 ++negativeValuesSeen
;
175 case AtomicTestCase::IncOnly
:
176 wxAtomicInc(m_operateOn
);
179 case AtomicTestCase::DecOnly
:
180 wxAtomicDec(m_operateOn
);
185 return (wxThread::ExitCode
)negativeValuesSeen
;