Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/thread/test/test_condition.cpp @ 20

Last change on this file since 20 was 12, checked in by landauf, 18 years ago

added boost

File size: 5.6 KB
Line 
1// Copyright (C) 2001-2003
2// William E. Kempf
3//
4// Permission to use, copy, modify, distribute and sell this software
5// and its documentation for any purpose is hereby granted without fee,
6// provided that the above copyright notice appear in all copies and
7// that both that copyright notice and this permission notice appear
8// in supporting documentation.  William E. Kempf makes no representations
9// about the suitability of this software for any purpose.
10// It is provided "as is" without express or implied warranty.
11
12#include <boost/thread/detail/config.hpp>
13
14#include <boost/thread/condition.hpp>
15#include <boost/thread/thread.hpp>
16#include <boost/thread/xtime.hpp>
17
18#include <boost/test/unit_test.hpp>
19
20#include <libs/thread/test/util.inl>
21
22struct condition_test_data
23{
24    condition_test_data() : notified(0), awoken(0) { }
25
26    boost::mutex mutex;
27    boost::condition condition;
28    int notified;
29    int awoken;
30};
31
32void condition_test_thread(condition_test_data* data)
33{
34    boost::mutex::scoped_lock lock(data->mutex);
35    BOOST_CHECK(lock ? true : false);
36    while (!(data->notified > 0))
37        data->condition.wait(lock);
38    BOOST_CHECK(lock ? true : false);
39    data->awoken++;
40}
41
42struct cond_predicate
43{
44    cond_predicate(int& var, int val) : _var(var), _val(val) { }
45
46    bool operator()() { return _var == _val; }
47
48    int& _var;
49    int _val;
50};
51
52void condition_test_waits(condition_test_data* data)
53{
54    boost::mutex::scoped_lock lock(data->mutex);
55    BOOST_CHECK(lock ? true : false);
56
57    // Test wait.
58    while (data->notified != 1)
59        data->condition.wait(lock);
60    BOOST_CHECK(lock ? true : false);
61    BOOST_CHECK_EQUAL(data->notified, 1);
62    data->awoken++;
63    data->condition.notify_one();
64
65    // Test predicate wait.
66    data->condition.wait(lock, cond_predicate(data->notified, 2));
67    BOOST_CHECK(lock ? true : false);
68    BOOST_CHECK_EQUAL(data->notified, 2);
69    data->awoken++;
70    data->condition.notify_one();
71
72    // Test timed_wait.
73    boost::xtime xt = delay(10);
74    while (data->notified != 3)
75        data->condition.timed_wait(lock, xt);
76    BOOST_CHECK(lock ? true : false);
77    BOOST_CHECK_EQUAL(data->notified, 3);
78    data->awoken++;
79    data->condition.notify_one();
80
81    // Test predicate timed_wait.
82    xt = delay(10);
83    cond_predicate pred(data->notified, 4);
84    BOOST_CHECK(data->condition.timed_wait(lock, xt, pred));
85    BOOST_CHECK(lock ? true : false);
86    BOOST_CHECK(pred());
87    BOOST_CHECK_EQUAL(data->notified, 4);
88    data->awoken++;
89    data->condition.notify_one();
90}
91
92void do_test_condition_notify_one()
93{
94    condition_test_data data;
95
96    boost::thread thread(bind(&condition_test_thread, &data));
97
98    {
99        boost::mutex::scoped_lock lock(data.mutex);
100        BOOST_CHECK(lock ? true : false);
101        data.notified++;
102        data.condition.notify_one();
103    }
104
105    thread.join();
106    BOOST_CHECK_EQUAL(data.awoken, 1);
107}
108
109void test_condition_notify_one()
110{
111    timed_test(&do_test_condition_notify_one, 2, execution_monitor::use_mutex);
112}
113
114void do_test_condition_notify_all()
115{
116    const int NUMTHREADS = 5;
117    boost::thread_group threads;
118    condition_test_data data;
119
120    for (int i = 0; i < NUMTHREADS; ++i)
121        threads.create_thread(bind(&condition_test_thread, &data));
122
123    {
124        boost::mutex::scoped_lock lock(data.mutex);
125        BOOST_CHECK(lock ? true : false);
126        data.notified++;
127        data.condition.notify_all();
128    }
129
130    threads.join_all();
131    BOOST_CHECK_EQUAL(data.awoken, NUMTHREADS);
132}
133
134void test_condition_notify_all()
135{
136    // We should have already tested notify_one here, so
137    // a timed test with the default execution_monitor::use_condition
138    // should be OK, and gives the fastest performance
139    timed_test(&do_test_condition_notify_all, 3);
140}
141
142void do_test_condition_waits()
143{
144    condition_test_data data;
145
146    boost::thread thread(bind(&condition_test_waits, &data));
147
148    {
149        boost::mutex::scoped_lock lock(data.mutex);
150        BOOST_CHECK(lock ? true : false);
151
152        boost::thread::sleep(delay(1));
153        data.notified++;
154        data.condition.notify_one();
155        while (data.awoken != 1)
156            data.condition.wait(lock);
157        BOOST_CHECK(lock ? true : false);
158        BOOST_CHECK_EQUAL(data.awoken, 1);
159
160        boost::thread::sleep(delay(1));
161        data.notified++;
162        data.condition.notify_one();
163        while (data.awoken != 2)
164            data.condition.wait(lock);
165        BOOST_CHECK(lock ? true : false);
166        BOOST_CHECK_EQUAL(data.awoken, 2);
167
168        boost::thread::sleep(delay(1));
169        data.notified++;
170        data.condition.notify_one();
171        while (data.awoken != 3)
172            data.condition.wait(lock);
173        BOOST_CHECK(lock ? true : false);
174        BOOST_CHECK_EQUAL(data.awoken, 3);
175
176        boost::thread::sleep(delay(1));
177        data.notified++;
178        data.condition.notify_one();
179        while (data.awoken != 4)
180            data.condition.wait(lock);
181        BOOST_CHECK(lock ? true : false);
182        BOOST_CHECK_EQUAL(data.awoken, 4);
183    }
184
185    thread.join();
186    BOOST_CHECK_EQUAL(data.awoken, 4);
187}
188
189void test_condition_waits()
190{
191    // We should have already tested notify_one here, so
192    // a timed test with the default execution_monitor::use_condition
193    // should be OK, and gives the fastest performance
194    timed_test(&do_test_condition_waits, 12);
195}
196
197boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
198{
199    boost::unit_test_framework::test_suite* test =
200        BOOST_TEST_SUITE("Boost.Threads: condition test suite");
201
202    test->add(BOOST_TEST_CASE(&test_condition_notify_one));
203    test->add(BOOST_TEST_CASE(&test_condition_notify_all));
204    test->add(BOOST_TEST_CASE(&test_condition_waits));
205
206    return test;
207}
Note: See TracBrowser for help on using the repository browser.