]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/fiber/test/test_mutex_dispatch.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / fiber / test / test_mutex_dispatch.cpp
CommitLineData
7c673cae
FG
1
2// Copyright Oliver Kowalke 2013.
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6//
7// This test is based on the tests of Boost.Thread
8
9#include <chrono>
10#include <cstdlib>
11#include <iostream>
12#include <map>
13#include <mutex>
14#include <stdexcept>
15#include <vector>
16
17#include <boost/test/unit_test.hpp>
18
19#include <boost/fiber/all.hpp>
20
21typedef std::chrono::nanoseconds ns;
22typedef std::chrono::milliseconds ms;
23
24int value1 = 0;
25int value2 = 0;
26
27template< typename M >
28void fn1( M & mtx) {
29 typedef M mutex_type;
30 typename std::unique_lock< mutex_type > lk( mtx);
31 ++value1;
32 for ( int i = 0; i < 3; ++i)
33 boost::this_fiber::yield();
34}
35
36template< typename M >
37void fn2( M & mtx) {
38 typedef M mutex_type;
39 ++value2;
40 typename std::unique_lock< mutex_type > lk( mtx);
41 ++value2;
42}
43
44void fn3( boost::fibers::timed_mutex & m) {
45 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
46 m.lock();
47 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
48 m.unlock();
49 ns d = t1 - t0 - ms(250);
b32b8144 50 BOOST_CHECK(d < ns(2500000)+ms(2000)); // within 2.5 ms
7c673cae
FG
51}
52
53void fn4( boost::fibers::timed_mutex & m) {
54 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
55 while ( ! m.try_lock() );
56 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
57 m.unlock();
58 ns d = t1 - t0 - ms(250);
59 BOOST_CHECK(d < ns(50000000)+ms(2000)); // within 50 ms
60}
61
62void fn5( boost::fibers::timed_mutex & m) {
63 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
64 BOOST_CHECK( m.try_lock_for(ms(300)+ms(2000)) == true);
65 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
66 m.unlock();
67 ns d = t1 - t0 - ms(250);
68 BOOST_CHECK(d < ns(5000000)+ms(2000)); // within 5 ms
69}
70
71void fn6( boost::fibers::timed_mutex & m) {
72 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
73 BOOST_CHECK(m.try_lock_for(ms(250)) == false);
74 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
75 ns d = t1 - t0 - ms(250);
b32b8144 76 BOOST_CHECK(d < ns(5000000)+ms(2000)); // within 5 ms
7c673cae
FG
77}
78
79void fn7( boost::fibers::timed_mutex & m) {
80 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
81 BOOST_CHECK(m.try_lock_until(std::chrono::steady_clock::now() + ms(300) + ms(1000)) == true);
82 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
83 m.unlock();
84 ns d = t1 - t0 - ms(250);
b32b8144 85 BOOST_CHECK(d < ns(5000000)+ms(2000)); // within 5ms
7c673cae
FG
86}
87
88void fn8( boost::fibers::timed_mutex & m) {
89 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
90 BOOST_CHECK(m.try_lock_until(std::chrono::steady_clock::now() + ms(250)) == false);
91 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
92 ns d = t1 - t0 - ms(250);
b32b8144 93 ns r = ns(5000000)+ms(2000); // within 6ms
7c673cae
FG
94 BOOST_CHECK(d < r); // within 6ms
95}
96
97void fn9( boost::fibers::recursive_timed_mutex & m) {
98 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
99 m.lock();
100 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
101 m.lock();
102 m.unlock();
103 m.unlock();
104 ns d = t1 - t0 - ms(250);
b32b8144 105 BOOST_CHECK(d < ms(2500)+ms(2000)); // within 2.5 ms
7c673cae
FG
106}
107
108void fn10( boost::fibers::recursive_timed_mutex & m) {
109 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
110 while (!m.try_lock()) ;
111 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
112 BOOST_CHECK(m.try_lock());
113 m.unlock();
114 m.unlock();
115 ns d = t1 - t0 - ms(250);
b32b8144 116 BOOST_CHECK(d < ms(50000)+ms(2000)); // within 50 ms
7c673cae
FG
117}
118
119void fn11( boost::fibers::recursive_timed_mutex & m) {
120 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
121 BOOST_CHECK(m.try_lock_for(ms(300)+ms(1000)) == true);
122 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
123 BOOST_CHECK(m.try_lock());
124 m.unlock();
125 m.unlock();
126 ns d = t1 - t0 - ms(250);
b32b8144 127 BOOST_CHECK(d < ns(5000000)+ms(2000)); // within 5 ms
7c673cae
FG
128}
129
130void fn12( boost::fibers::recursive_timed_mutex & m) {
131 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
132 BOOST_CHECK(m.try_lock_for(ms(250)) == false);
133 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
134 ns d = t1 - t0 - ms(250);
b32b8144 135 BOOST_CHECK(d < ms(5000)+ms(2000)); // within 5 ms
7c673cae
FG
136}
137
138void fn13( boost::fibers::recursive_timed_mutex & m) {
139 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
140 BOOST_CHECK(m.try_lock_until(std::chrono::steady_clock::now() + ms(300) + ms(1000)) == true);
141 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
142 m.unlock();
143 ns d = t1 - t0 - ms(250);
b32b8144 144 BOOST_CHECK(d < ns(5000000)+ms(2000)); // within 5 ms
7c673cae
FG
145}
146
147void fn14( boost::fibers::recursive_timed_mutex & m) {
148 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
149 BOOST_CHECK(m.try_lock_until(std::chrono::steady_clock::now() + ms(250)) == false);
150 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
151 ns d = t1 - t0 - ms(250);
b32b8144 152 BOOST_CHECK(d < ns(5000000)+ms(2000)); // within 5 ms
7c673cae
FG
153}
154
155void fn15( boost::fibers::recursive_mutex & m) {
156 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
157 m.lock();
158 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
159 m.lock();
160 m.unlock();
161 m.unlock();
162 ns d = t1 - t0 - ms(250);
b32b8144 163 BOOST_CHECK(d < ns(2500000)+ms(2000)); // within 2.5 ms
7c673cae
FG
164}
165
166void fn16( boost::fibers::recursive_mutex & m) {
167 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
168 while (!m.try_lock());
169 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
170 BOOST_CHECK(m.try_lock());
171 m.unlock();
172 m.unlock();
173 ns d = t1 - t0 - ms(250);
b32b8144 174 BOOST_CHECK(d < ns(50000000)+ms(2000)); // within 50 ms
7c673cae
FG
175}
176
177void fn17( boost::fibers::mutex & m) {
178 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
179 m.lock();
180 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
181 m.unlock();
182 ns d = t1 - t0 - ms(250);
b32b8144 183 BOOST_CHECK(d < ms(2500)+ms(2000)); // within 2.5 ms
7c673cae
FG
184}
185
186void fn18( boost::fibers::mutex & m) {
187 std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now();
188 while (!m.try_lock()) ;
189 std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
190 m.unlock();
191 ns d = t1 - t0 - ms(250);
b32b8144 192 BOOST_CHECK(d < ns(50000000)+ms(2000)); // within 50 ms
7c673cae
FG
193}
194
195template< typename M >
196struct test_lock {
197 typedef M mutex_type;
198 typedef typename std::unique_lock< M > lock_type;
199
200 void operator()() {
201 mutex_type mtx;
202
203 // Test the lock's constructors.
204 {
205 lock_type lk(mtx, std::defer_lock);
206 BOOST_CHECK(!lk);
207 }
208 lock_type lk(mtx);
209 BOOST_CHECK(lk ? true : false);
210
211 // Test the lock and unlock methods.
212 lk.unlock();
213 BOOST_CHECK(!lk);
214 lk.lock();
215 BOOST_CHECK(lk ? true : false);
216 }
217};
218
219template< typename M >
220struct test_exclusive {
221 typedef M mutex_type;
222 typedef typename std::unique_lock< M > lock_type;
223
224 void operator()() {
225 value1 = 0;
226 value2 = 0;
227 BOOST_CHECK_EQUAL( 0, value1);
228 BOOST_CHECK_EQUAL( 0, value2);
229
230 mutex_type mtx;
231 boost::fibers::fiber f1( boost::fibers::launch::dispatch, & fn1< mutex_type >, std::ref( mtx) );
232 boost::fibers::fiber f2( boost::fibers::launch::dispatch, & fn2< mutex_type >, std::ref( mtx) );
233 BOOST_ASSERT( f1.joinable() );
234 BOOST_ASSERT( f2.joinable() );
235
236 f1.join();
237 f2.join();
238 BOOST_CHECK_EQUAL( 1, value1);
239 BOOST_CHECK_EQUAL( 2, value2);
240 }
241};
242
243template< typename M >
244struct test_recursive_lock {
245 typedef M mutex_type;
246 typedef typename std::unique_lock< M > lock_type;
247
248 void operator()() {
249 mutex_type mx;
250 lock_type lock1(mx);
251 lock_type lock2(mx);
252 }
253};
254
255void do_test_mutex() {
256 test_lock< boost::fibers::mutex >()();
257 test_exclusive< boost::fibers::mutex >()();
258
259 {
260 boost::fibers::mutex mtx;
261 mtx.lock();
262 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn17, std::ref( mtx) );
263 boost::this_fiber::sleep_for( ms(250) );
264 mtx.unlock();
265 f.join();
266 }
267
268 {
269 boost::fibers::mutex mtx;
270 mtx.lock();
271 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn18, std::ref( mtx) );
272 boost::this_fiber::sleep_for( ms(250) );
273 mtx.unlock();
274 f.join();
275 }
276}
277
278void test_mutex() {
279 boost::fibers::fiber( boost::fibers::launch::dispatch, & do_test_mutex).join();
280}
281
282void do_test_recursive_mutex() {
283 test_lock< boost::fibers::recursive_mutex >()();
284 test_exclusive< boost::fibers::recursive_mutex >()();
285 test_recursive_lock< boost::fibers::recursive_mutex >()();
286
287 {
288 boost::fibers::recursive_mutex mtx;
289 mtx.lock();
290 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn15, std::ref( mtx) );
291 boost::this_fiber::sleep_for( ms(250) );
292 mtx.unlock();
293 f.join();
294 }
295
296 {
297 boost::fibers::recursive_mutex mtx;
298 mtx.lock();
299 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn16, std::ref( mtx) );
300 boost::this_fiber::sleep_for( ms(250) );
301 mtx.unlock();
302 f.join();
303 }
304}
305
306void test_recursive_mutex() {
307 boost::fibers::fiber( boost::fibers::launch::dispatch, do_test_recursive_mutex).join();
308}
309
310void do_test_timed_mutex() {
311 test_lock< boost::fibers::timed_mutex >()();
312 test_exclusive< boost::fibers::timed_mutex >()();
313
314 {
315 boost::fibers::timed_mutex timed_mtx;
316 timed_mtx.lock();
317 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn3, std::ref( timed_mtx) );
318 boost::this_fiber::sleep_for( ms(250) );
319 timed_mtx.unlock();
320 f.join();
321 }
322
323 {
324 boost::fibers::timed_mutex timed_mtx;
325 timed_mtx.lock();
326 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn4, std::ref( timed_mtx) );
327 boost::this_fiber::sleep_for( ms(250) );
328 timed_mtx.unlock();
329 f.join();
330 }
331
332 {
333 boost::fibers::timed_mutex timed_mtx;
334 timed_mtx.lock();
335 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn5, std::ref( timed_mtx) );
336 boost::this_fiber::sleep_for( ms(250) );
337 timed_mtx.unlock();
338 f.join();
339 }
340
341 {
342 boost::fibers::timed_mutex timed_mtx;
343 timed_mtx.lock();
344 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn6, std::ref( timed_mtx) );
345 boost::this_fiber::sleep_for( ms(300) );
346 timed_mtx.unlock();
347 f.join();
348 }
349
350 {
351 boost::fibers::timed_mutex timed_mtx;
352 timed_mtx.lock();
353 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn7, std::ref( timed_mtx) );
354 boost::this_fiber::sleep_for( ms(250) );
355 timed_mtx.unlock();
356 f.join();
357 }
358
359 {
360 boost::fibers::timed_mutex timed_mtx;
361 timed_mtx.lock();
362 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn8, std::ref( timed_mtx) );
363 boost::this_fiber::sleep_for( ms(300) + ms(1000) );
364 timed_mtx.unlock();
365 f.join();
366 }
367}
368
369void test_timed_mutex() {
370 boost::fibers::fiber( boost::fibers::launch::dispatch, & do_test_timed_mutex).join();
371}
372
373void do_test_recursive_timed_mutex() {
374 test_lock< boost::fibers::recursive_timed_mutex >()();
375 test_exclusive< boost::fibers::recursive_timed_mutex >()();
376 test_recursive_lock< boost::fibers::recursive_timed_mutex >()();
377
378 {
379 boost::fibers::recursive_timed_mutex timed_mtx;
380 timed_mtx.lock();
381 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn9, std::ref( timed_mtx) );
382 boost::this_fiber::sleep_for( ms(250) );
383 timed_mtx.unlock();
384 f.join();
385 }
386
387 {
388 boost::fibers::recursive_timed_mutex timed_mtx;
389 timed_mtx.lock();
390 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn10, std::ref( timed_mtx) );
391 boost::this_fiber::sleep_for( ms(250) );
392 timed_mtx.unlock();
393 f.join();
394 }
395
396 {
397 boost::fibers::recursive_timed_mutex timed_mtx;
398 timed_mtx.lock();
399 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn11, std::ref( timed_mtx) );
400 boost::this_fiber::sleep_for( ms(250) );
401 timed_mtx.unlock();
402 f.join();
403 }
404
405 {
406 boost::fibers::recursive_timed_mutex timed_mtx;
407 timed_mtx.lock();
408 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn12, std::ref( timed_mtx) );
409 boost::this_fiber::sleep_for( ms(400) );
410 timed_mtx.unlock();
411 f.join();
412 }
413
414 {
415 boost::fibers::recursive_timed_mutex timed_mtx;
416 timed_mtx.lock();
417 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn13, std::ref( timed_mtx) );
418 boost::this_fiber::sleep_for( ms(250) );
419 timed_mtx.unlock();
420 f.join();
421 }
422
423 {
424 boost::fibers::recursive_timed_mutex timed_mtx;
425 timed_mtx.lock();
426 boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn14, std::ref( timed_mtx) );
427 boost::this_fiber::sleep_for( ms(300) );
428 timed_mtx.unlock();
429 f.join();
430 }
431}
432
433void test_recursive_timed_mutex() {
434 boost::fibers::fiber( boost::fibers::launch::dispatch, & do_test_recursive_timed_mutex).join();
435}
436
437boost::unit_test::test_suite * init_unit_test_suite( int, char* []) {
438 boost::unit_test::test_suite * test =
439 BOOST_TEST_SUITE("Boost.Fiber: mutex test suite");
440
441 test->add( BOOST_TEST_CASE( & test_mutex) );
442 test->add( BOOST_TEST_CASE( & test_recursive_mutex) );
443 test->add( BOOST_TEST_CASE( & test_timed_mutex) );
444 test->add( BOOST_TEST_CASE( & test_recursive_timed_mutex) );
445
446 return test;
447}