1 // (C) Copyright 2006-7 Anthony Williams
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
6 #define BOOST_THREAD_VERSION 2
7 #define BOOST_THREAD_PROVIDES_INTERRUPTIONS
8 #define BOOST_TEST_MODULE Boost.Threads: shared_mutex test suite
10 #include <boost/test/unit_test.hpp>
11 #include <boost/thread/thread.hpp>
12 #include <boost/thread/xtime.hpp>
14 #include "./shared_mutex_locking_thread.hpp"
17 #define CHECK_LOCKED_VALUE_EQUAL(mutex_name,value,expected_value) \
19 boost::unique_lock<boost::mutex> lock(mutex_name); \
20 BOOST_CHECK_EQUAL(value,expected_value); \
23 BOOST_AUTO_TEST_CASE(test_multiple_readers
)
25 std::cout
<< __LINE__
<< std::endl
;
26 unsigned const number_of_threads
=10;
28 boost::thread_group pool
;
30 boost::shared_mutex rw_mutex
;
31 unsigned unblocked_count
=0;
32 unsigned simultaneous_running_count
=0;
33 unsigned max_simultaneous_running
=0;
34 boost::mutex unblocked_count_mutex
;
35 boost::condition_variable unblocked_condition
;
36 boost::mutex finish_mutex
;
37 boost::unique_lock
<boost::mutex
> finish_lock(finish_mutex
);
41 for(unsigned i
=0;i
<number_of_threads
;++i
)
43 pool
.create_thread(locking_thread
<boost::shared_lock
<boost::shared_mutex
> >(rw_mutex
,unblocked_count
,unblocked_count_mutex
,unblocked_condition
,
44 finish_mutex
,simultaneous_running_count
,max_simultaneous_running
));
48 boost::unique_lock
<boost::mutex
> lk(unblocked_count_mutex
);
49 while(unblocked_count
<number_of_threads
)
51 unblocked_condition
.wait(lk
);
55 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,unblocked_count
,number_of_threads
);
68 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,max_simultaneous_running
,number_of_threads
);
71 BOOST_AUTO_TEST_CASE(test_only_one_writer_permitted
)
73 std::cout
<< __LINE__
<< std::endl
;
74 unsigned const number_of_threads
=10;
76 boost::thread_group pool
;
78 boost::shared_mutex rw_mutex
;
79 unsigned unblocked_count
=0;
80 unsigned simultaneous_running_count
=0;
81 unsigned max_simultaneous_running
=0;
82 boost::mutex unblocked_count_mutex
;
83 boost::condition_variable unblocked_condition
;
84 boost::mutex finish_mutex
;
85 boost::unique_lock
<boost::mutex
> finish_lock(finish_mutex
);
89 for(unsigned i
=0;i
<number_of_threads
;++i
)
91 pool
.create_thread(locking_thread
<boost::unique_lock
<boost::shared_mutex
> >(rw_mutex
,unblocked_count
,unblocked_count_mutex
,unblocked_condition
,
92 finish_mutex
,simultaneous_running_count
,max_simultaneous_running
));
95 boost::thread::sleep(delay(2));
97 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,unblocked_count
,1U);
105 pool
.interrupt_all();
110 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,unblocked_count
,number_of_threads
);
111 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,max_simultaneous_running
,1u);
114 BOOST_AUTO_TEST_CASE(test_reader_blocks_writer
)
116 std::cout
<< __LINE__
<< std::endl
;
117 boost::thread_group pool
;
119 boost::shared_mutex rw_mutex
;
120 unsigned unblocked_count
=0;
121 unsigned simultaneous_running_count
=0;
122 unsigned max_simultaneous_running
=0;
123 boost::mutex unblocked_count_mutex
;
124 boost::condition_variable unblocked_condition
;
125 boost::mutex finish_mutex
;
126 boost::unique_lock
<boost::mutex
> finish_lock(finish_mutex
);
131 pool
.create_thread(locking_thread
<boost::shared_lock
<boost::shared_mutex
> >(rw_mutex
,unblocked_count
,unblocked_count_mutex
,unblocked_condition
,
132 finish_mutex
,simultaneous_running_count
,max_simultaneous_running
));
134 boost::unique_lock
<boost::mutex
> lk(unblocked_count_mutex
);
135 while(unblocked_count
<1)
137 unblocked_condition
.wait(lk
);
140 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,unblocked_count
,1U);
141 pool
.create_thread(locking_thread
<boost::unique_lock
<boost::shared_mutex
> >(rw_mutex
,unblocked_count
,unblocked_count_mutex
,unblocked_condition
,
142 finish_mutex
,simultaneous_running_count
,max_simultaneous_running
));
143 boost::thread::sleep(delay(1));
144 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,unblocked_count
,1U);
146 finish_lock
.unlock();
152 pool
.interrupt_all();
157 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,unblocked_count
,2U);
158 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,max_simultaneous_running
,1u);
161 BOOST_AUTO_TEST_CASE(test_unlocking_writer_unblocks_all_readers
)
163 std::cout
<< __LINE__
<< std::endl
;
164 boost::thread_group pool
;
166 boost::shared_mutex rw_mutex
;
167 boost::unique_lock
<boost::shared_mutex
> write_lock(rw_mutex
);
168 unsigned unblocked_count
=0;
169 unsigned simultaneous_running_count
=0;
170 unsigned max_simultaneous_running
=0;
171 boost::mutex unblocked_count_mutex
;
172 boost::condition_variable unblocked_condition
;
173 boost::mutex finish_mutex
;
174 boost::unique_lock
<boost::mutex
> finish_lock(finish_mutex
);
176 unsigned const reader_count
=10;
180 for(unsigned i
=0;i
<reader_count
;++i
)
182 pool
.create_thread(locking_thread
<boost::shared_lock
<boost::shared_mutex
> >(rw_mutex
,unblocked_count
,unblocked_count_mutex
,unblocked_condition
,
183 finish_mutex
,simultaneous_running_count
,max_simultaneous_running
));
185 boost::thread::sleep(delay(1));
186 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,unblocked_count
,0U);
191 boost::unique_lock
<boost::mutex
> lk(unblocked_count_mutex
);
192 while(unblocked_count
<reader_count
)
194 unblocked_condition
.wait(lk
);
198 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,unblocked_count
,reader_count
);
200 finish_lock
.unlock();
205 pool
.interrupt_all();
210 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,max_simultaneous_running
,reader_count
);
213 BOOST_AUTO_TEST_CASE(test_unlocking_last_reader_only_unblocks_one_writer
)
215 std::cout
<< __LINE__
<< std::endl
;
216 boost::thread_group pool
;
218 boost::shared_mutex rw_mutex
;
219 unsigned unblocked_count
=0;
220 unsigned simultaneous_running_readers
=0;
221 unsigned max_simultaneous_readers
=0;
222 unsigned simultaneous_running_writers
=0;
223 unsigned max_simultaneous_writers
=0;
224 boost::mutex unblocked_count_mutex
;
225 boost::condition_variable unblocked_condition
;
226 boost::mutex finish_reading_mutex
;
227 boost::unique_lock
<boost::mutex
> finish_reading_lock(finish_reading_mutex
);
228 boost::mutex finish_writing_mutex
;
229 boost::unique_lock
<boost::mutex
> finish_writing_lock(finish_writing_mutex
);
231 unsigned const reader_count
=10;
232 unsigned const writer_count
=10;
236 for(unsigned i
=0;i
<reader_count
;++i
)
238 pool
.create_thread(locking_thread
<boost::shared_lock
<boost::shared_mutex
> >(rw_mutex
,unblocked_count
,unblocked_count_mutex
,unblocked_condition
,
239 finish_reading_mutex
,simultaneous_running_readers
,max_simultaneous_readers
));
241 boost::thread::sleep(delay(1));
242 for(unsigned i
=0;i
<writer_count
;++i
)
244 pool
.create_thread(locking_thread
<boost::unique_lock
<boost::shared_mutex
> >(rw_mutex
,unblocked_count
,unblocked_count_mutex
,unblocked_condition
,
245 finish_writing_mutex
,simultaneous_running_writers
,max_simultaneous_writers
));
248 boost::unique_lock
<boost::mutex
> lk(unblocked_count_mutex
);
249 while(unblocked_count
<reader_count
)
251 unblocked_condition
.wait(lk
);
254 boost::thread::sleep(delay(1));
255 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,unblocked_count
,reader_count
);
257 finish_reading_lock
.unlock();
260 boost::unique_lock
<boost::mutex
> lk(unblocked_count_mutex
);
261 while(unblocked_count
<(reader_count
+1))
263 unblocked_condition
.wait(lk
);
266 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,unblocked_count
,reader_count
+1);
268 finish_writing_lock
.unlock();
273 pool
.interrupt_all();
278 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,unblocked_count
,reader_count
+writer_count
);
279 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,max_simultaneous_readers
,reader_count
);
280 CHECK_LOCKED_VALUE_EQUAL(unblocked_count_mutex
,max_simultaneous_writers
,1u);