]>
Commit | Line | Data |
---|---|---|
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 <cstdlib> | |
10 | #include <iostream> | |
11 | #include <map> | |
12 | #include <stdexcept> | |
13 | #include <vector> | |
14 | ||
15 | #include <boost/chrono.hpp> | |
16 | #include <boost/test/unit_test.hpp> | |
17 | #include <boost/thread/barrier.hpp> | |
18 | #include <boost/thread/thread.hpp> | |
19 | ||
20 | #include <boost/fiber/all.hpp> | |
21 | ||
22 | typedef boost::chrono::nanoseconds ns; | |
23 | typedef boost::chrono::milliseconds ms; | |
24 | ||
25 | int value1 = 0; | |
26 | int value2 = 0; | |
27 | ||
28 | template< typename Mtx > | |
29 | void g( boost::barrier & b, Mtx & m) { | |
30 | b.wait(); | |
31 | m.lock(); | |
32 | value1 = 3; | |
33 | m.unlock(); | |
34 | } | |
35 | ||
36 | template< typename Mtx > | |
37 | void f( boost::barrier & b, Mtx & m) { | |
38 | b.wait(); | |
39 | m.lock(); | |
40 | value2 = 7; | |
41 | m.unlock(); | |
42 | } | |
43 | ||
44 | template< typename Mtx > | |
45 | void fn1( boost::barrier & b, Mtx & m) { | |
46 | boost::fibers::fiber( boost::fibers::launch::dispatch, g< Mtx >, std::ref( b), std::ref( m) ).join(); | |
47 | } | |
48 | ||
49 | template< typename Mtx > | |
50 | void fn2( boost::barrier & b, Mtx & m) { | |
51 | boost::fibers::fiber( boost::fibers::launch::dispatch, f< Mtx >, std::ref( b), std::ref( m) ).join(); | |
52 | } | |
53 | ||
54 | void test_mutex() { | |
55 | for ( int i = 0; i < 10; ++i) { | |
56 | boost::fibers::mutex mtx; | |
57 | mtx.lock(); | |
58 | boost::barrier b( 3); | |
59 | boost::thread t1( fn1< boost::fibers::mutex >, std::ref( b), std::ref( mtx) ); | |
60 | boost::thread t2( fn2< boost::fibers::mutex >, std::ref( b), std::ref( mtx) ); | |
61 | b.wait(); | |
62 | boost::this_thread::sleep_for( ms( 250) ); | |
63 | mtx.unlock(); | |
64 | t1.join(); | |
65 | t2.join(); | |
66 | BOOST_CHECK( 3 == value1); | |
67 | BOOST_CHECK( 7 == value2); | |
68 | } | |
69 | } | |
70 | ||
71 | void test_recursive_mutex() { | |
72 | for ( int i = 0; i < 10; ++i) { | |
73 | boost::fibers::recursive_mutex mtx; | |
74 | mtx.lock(); | |
75 | boost::barrier b( 3); | |
76 | boost::thread t1( fn1< boost::fibers::recursive_mutex >, std::ref( b), std::ref( mtx) ); | |
77 | boost::thread t2( fn2< boost::fibers::recursive_mutex >, std::ref( b), std::ref( mtx) ); | |
78 | b.wait(); | |
79 | boost::this_thread::sleep_for( ms( 250) ); | |
80 | mtx.unlock(); | |
81 | t1.join(); | |
82 | t2.join(); | |
83 | BOOST_CHECK( 3 == value1); | |
84 | BOOST_CHECK( 7 == value2); | |
85 | } | |
86 | } | |
87 | ||
88 | void test_timed_mutex() { | |
89 | for ( int i = 0; i < 10; ++i) { | |
90 | boost::fibers::timed_mutex mtx; | |
91 | mtx.lock(); | |
92 | boost::barrier b( 3); | |
93 | boost::thread t1( fn1< boost::fibers::timed_mutex >, std::ref( b), std::ref( mtx) ); | |
94 | boost::thread t2( fn2< boost::fibers::timed_mutex >, std::ref( b), std::ref( mtx) ); | |
95 | b.wait(); | |
96 | boost::this_thread::sleep_for( ms( 250) ); | |
97 | mtx.unlock(); | |
98 | t1.join(); | |
99 | t2.join(); | |
100 | BOOST_CHECK( 3 == value1); | |
101 | BOOST_CHECK( 7 == value2); | |
102 | } | |
103 | } | |
104 | ||
105 | void test_recursive_timed_mutex() { | |
106 | for ( int i = 0; i < 10; ++i) { | |
107 | boost::fibers::recursive_timed_mutex mtx; | |
108 | mtx.lock(); | |
109 | boost::barrier b( 3); | |
110 | boost::thread t1( fn1< boost::fibers::recursive_timed_mutex >, std::ref( b), std::ref( mtx) ); | |
111 | boost::thread t2( fn2< boost::fibers::recursive_timed_mutex >, std::ref( b), std::ref( mtx) ); | |
112 | b.wait(); | |
113 | boost::this_thread::sleep_for( ms( 250) ); | |
114 | mtx.unlock(); | |
115 | t1.join(); | |
116 | t2.join(); | |
117 | BOOST_CHECK( 3 == value1); | |
118 | BOOST_CHECK( 7 == value2); | |
119 | } | |
120 | } | |
121 | ||
122 | void test_dummy() { | |
123 | } | |
124 | ||
125 | boost::unit_test::test_suite * init_unit_test_suite( int, char* []) { | |
126 | boost::unit_test::test_suite * test = | |
127 | BOOST_TEST_SUITE("Boost.Fiber: multithreaded mutex test suite"); | |
128 | ||
129 | #if ! defined(BOOST_FIBERS_NO_ATOMICS) | |
130 | test->add( BOOST_TEST_CASE( & test_mutex) ); | |
131 | test->add( BOOST_TEST_CASE( & test_recursive_mutex) ); | |
132 | test->add( BOOST_TEST_CASE( & test_timed_mutex) ); | |
133 | test->add( BOOST_TEST_CASE( & test_recursive_timed_mutex) ); | |
134 | #else | |
135 | test->add( BOOST_TEST_CASE( & test_dummy) ); | |
136 | #endif | |
137 | ||
138 | return test; | |
139 | } |