]> git.saurik.com Git - wxWidgets.git/blame - tests/thread/atomic.cpp
added wxUTF8StringBuffer for writing UTF8 data into wxString efficiently, similarly...
[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"
26WX_DEFINE_ARRAY_PTR(wxThread *, wxArrayThread);
27
28// ----------------------------------------------------------------------------
29// test class
30// ----------------------------------------------------------------------------
31
32class AtomicTestCase : public CppUnit::TestCase
33{
34public:
35 AtomicTestCase() { }
36
37private:
38
39 enum ETestType
40 {
41 IncAndDecMixed,
42 IncOnly,
43 DecOnly
44 };
45
46 class MyThread : public wxThread
47 {
48 public:
49 MyThread(wxAtomicInt &operateOn, ETestType testType) : wxThread(wxTHREAD_JOINABLE),
50 m_operateOn(operateOn), m_testType(testType) {}
51
52 // thread execution starts here
53 virtual void *Entry();
54
55 public:
56 wxAtomicInt &m_operateOn;
57 ETestType m_testType;
58 };
59
60 CPPUNIT_TEST_SUITE( AtomicTestCase );
61 CPPUNIT_TEST( TestNoThread );
62 CPPUNIT_TEST( TestTwoThreadsMix );
63 CPPUNIT_TEST( TestTenThreadsMix );
64 CPPUNIT_TEST( TestTwoThreadsSeparate );
65 CPPUNIT_TEST( TestTenThreadsSeparate );
66 CPPUNIT_TEST_SUITE_END();
67
68 void TestNoThread();
69 void TestTenThreadsMix() { TestWithThreads(10, IncAndDecMixed); }
70 void TestTwoThreadsMix() { TestWithThreads(2, IncAndDecMixed); }
71 void TestTenThreadsSeparate() { TestWithThreads(10, IncOnly); }
72 void TestTwoThreadsSeparate() { TestWithThreads(2, IncOnly); }
73 void TestWithThreads(int count, ETestType testtype);
74
75 DECLARE_NO_COPY_CLASS(AtomicTestCase)
76};
77
78// register in the unnamed registry so that these tests are run by default
79CPPUNIT_TEST_SUITE_REGISTRATION( AtomicTestCase );
80
81// also include in it's own registry so that these tests can be run alone
82CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AtomicTestCase, "AtomicTestCase" );
83
84void AtomicTestCase::TestNoThread()
85{
86 wxAtomicInt int1=0, int2=0;
87
88 for (wxInt32 i=0; i<10000000; ++i)
89 {
90 wxAtomicInc(int1);
91 wxAtomicDec(int2);
92 }
93
94 CPPUNIT_ASSERT( int1 == 10000000 );
95 CPPUNIT_ASSERT( int2 == -10000000 );
96}
97
98void AtomicTestCase::TestWithThreads(int count, ETestType testType)
99{
100 wxAtomicInt int1=0;
101
102 wxArrayThread threads;
103
104 int i;
105 for ( i = 0; i < count; ++i )
106 {
107 ETestType actualThreadType;
108 switch(testType)
109 {
110 default:
111 actualThreadType = testType;
112 break;
113 case IncOnly:
114 actualThreadType = (i&1)==0 ? IncOnly : DecOnly;
115 break;
116 }
117
118 MyThread *thread = new MyThread(int1, actualThreadType);
119
120 if ( thread->Create() != wxTHREAD_NO_ERROR )
121 {
122 wxLogError(wxT("Can't create thread!"));
123 }
124 else
125 threads.Add(thread);
126 }
127
128 for ( i = 0; i < count; ++i )
129 {
130 threads[i]->Run();
131 }
132
133
134 for ( i = 0; i < count; ++i )
135 {
136 // each thread should return 0, else it detected some problem
137 CPPUNIT_ASSERT (threads[i]->Wait() == (wxThread::ExitCode)0);
138 }
139
140 CPPUNIT_ASSERT( int1 == 0 );
141}
142
143// ----------------------------------------------------------------------------
144
145void *AtomicTestCase::MyThread::Entry()
146{
147 wxInt32 negativeValuesSeen = 0;
148
149 for (wxInt32 i=0; i<10000000; ++i)
150 {
151 switch (m_testType)
152 {
153 case AtomicTestCase::IncAndDecMixed:
154 wxAtomicInc(m_operateOn);
155 wxAtomicDec(m_operateOn);
156
157 if (m_operateOn < 0)
158 ++negativeValuesSeen;
159 break;
160
161 case AtomicTestCase::IncOnly:
162 wxAtomicInc(m_operateOn);
163 break;
164
165 case AtomicTestCase::DecOnly:
166 wxAtomicDec(m_operateOn);
167 break;
168 }
169 }
170
171 return (wxThread::ExitCode)negativeValuesSeen;
172}