]> git.saurik.com Git - wxWidgets.git/blame - tests/thread/atomic.cpp
Giving up on combining @e and @c
[wxWidgets.git] / tests / thread / atomic.cpp
CommitLineData
cde76cf2
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: tests/thread/atomic.cpp
3// Purpose: wxAtomic??? unit test
4// Author: Armel Asselin
5// Created: 2006-12-14
6// RCS-ID: $Id$
7// Copyright: (c) 2006 Armel Asselin
8///////////////////////////////////////////////////////////////////////////////
9
10// ----------------------------------------------------------------------------
11// headers
12// ----------------------------------------------------------------------------
13
14#include "testprec.h"
15
16#ifdef __BORLANDC__
17 #pragma hdrstop
18#endif
19
20#ifndef WX_PRECOMP
21#endif // WX_PRECOMP
22
23#include "wx/atomic.h"
24#include "wx/thread.h"
25#include "wx/dynarray.h"
cb979a71
VS
26#include "wx/log.h"
27
cde76cf2
VZ
28WX_DEFINE_ARRAY_PTR(wxThread *, wxArrayThread);
29
30// ----------------------------------------------------------------------------
31// test class
32// ----------------------------------------------------------------------------
33
34class AtomicTestCase : public CppUnit::TestCase
35{
36public:
37 AtomicTestCase() { }
38
cde76cf2
VZ
39 enum ETestType
40 {
41 IncAndDecMixed,
42 IncOnly,
43 DecOnly
44 };
45
5098c258 46private:
cde76cf2
VZ
47 class MyThread : public wxThread
48 {
49 public:
50 MyThread(wxAtomicInt &operateOn, ETestType testType) : wxThread(wxTHREAD_JOINABLE),
51 m_operateOn(operateOn), m_testType(testType) {}
52
53 // thread execution starts here
54 virtual void *Entry();
55
56 public:
57 wxAtomicInt &m_operateOn;
58 ETestType m_testType;
59 };
60
61 CPPUNIT_TEST_SUITE( AtomicTestCase );
62 CPPUNIT_TEST( TestNoThread );
630dad8c 63 CPPUNIT_TEST( TestDecReturn );
cde76cf2
VZ
64 CPPUNIT_TEST( TestTwoThreadsMix );
65 CPPUNIT_TEST( TestTenThreadsMix );
66 CPPUNIT_TEST( TestTwoThreadsSeparate );
67 CPPUNIT_TEST( TestTenThreadsSeparate );
68 CPPUNIT_TEST_SUITE_END();
69
70 void TestNoThread();
630dad8c 71 void TestDecReturn();
cde76cf2
VZ
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);
77
78 DECLARE_NO_COPY_CLASS(AtomicTestCase)
79};
80
81// register in the unnamed registry so that these tests are run by default
82CPPUNIT_TEST_SUITE_REGISTRATION( AtomicTestCase );
83
84// also include in it's own registry so that these tests can be run alone
85CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AtomicTestCase, "AtomicTestCase" );
86
87void AtomicTestCase::TestNoThread()
88{
89 wxAtomicInt int1=0, int2=0;
90
91 for (wxInt32 i=0; i<10000000; ++i)
92 {
93 wxAtomicInc(int1);
94 wxAtomicDec(int2);
95 }
96
97 CPPUNIT_ASSERT( int1 == 10000000 );
98 CPPUNIT_ASSERT( int2 == -10000000 );
99}
100
630dad8c
VS
101void AtomicTestCase::TestDecReturn()
102{
103 wxAtomicInt i(0);
104 wxAtomicInc(i);
105 wxAtomicInc(i);
106 CPPUNIT_ASSERT( i == 2 );
107
108 CPPUNIT_ASSERT( wxAtomicDec(i) > 0 );
109 CPPUNIT_ASSERT( wxAtomicDec(i) == 0 );
110}
111
cde76cf2
VZ
112void AtomicTestCase::TestWithThreads(int count, ETestType testType)
113{
114 wxAtomicInt int1=0;
115
116 wxArrayThread threads;
117
118 int i;
119 for ( i = 0; i < count; ++i )
120 {
121 ETestType actualThreadType;
122 switch(testType)
123 {
124 default:
125 actualThreadType = testType;
126 break;
127 case IncOnly:
128 actualThreadType = (i&1)==0 ? IncOnly : DecOnly;
129 break;
130 }
131
132 MyThread *thread = new MyThread(int1, actualThreadType);
133
134 if ( thread->Create() != wxTHREAD_NO_ERROR )
135 {
136 wxLogError(wxT("Can't create thread!"));
137 }
138 else
139 threads.Add(thread);
140 }
141
142 for ( i = 0; i < count; ++i )
143 {
144 threads[i]->Run();
145 }
146
147
148 for ( i = 0; i < count; ++i )
149 {
150 // each thread should return 0, else it detected some problem
151 CPPUNIT_ASSERT (threads[i]->Wait() == (wxThread::ExitCode)0);
152 }
153
154 CPPUNIT_ASSERT( int1 == 0 );
155}
156
157// ----------------------------------------------------------------------------
158
159void *AtomicTestCase::MyThread::Entry()
160{
161 wxInt32 negativeValuesSeen = 0;
162
163 for (wxInt32 i=0; i<10000000; ++i)
164 {
165 switch (m_testType)
166 {
167 case AtomicTestCase::IncAndDecMixed:
168 wxAtomicInc(m_operateOn);
169 wxAtomicDec(m_operateOn);
170
171 if (m_operateOn < 0)
172 ++negativeValuesSeen;
173 break;
174
175 case AtomicTestCase::IncOnly:
176 wxAtomicInc(m_operateOn);
177 break;
178
179 case AtomicTestCase::DecOnly:
180 wxAtomicDec(m_operateOn);
181 break;
182 }
183 }
184
185 return (wxThread::ExitCode)negativeValuesSeen;
186}