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)
7 // This test is based on the tests of Boost.Thread
17 #include <boost/atomic.hpp>
18 #include <boost/bind.hpp>
19 #include <boost/chrono.hpp>
20 #include <boost/cstdint.hpp>
21 #include <boost/function.hpp>
22 #include <boost/ref.hpp>
23 #include <boost/test/unit_test.hpp>
24 #include <boost/thread.hpp>
25 #include <boost/utility.hpp>
27 #include <boost/fiber/all.hpp>
29 typedef boost::chrono::milliseconds ms
;
31 boost::atomic
< int > value1
;
33 void wait_fn( boost::barrier
& b
,
34 boost::fibers::mutex
& mtx
,
35 boost::fibers::condition_variable
& cond
,
38 std::unique_lock
< boost::fibers::mutex
> lk( mtx
);
39 cond
.wait( lk
, [&flag
](){ return flag
; });
43 void notify_one_fn( boost::barrier
& b
,
44 boost::fibers::mutex
& mtx
,
45 boost::fibers::condition_variable
& cond
,
48 std::unique_lock
< boost::fibers::mutex
> lk( mtx
);
54 void notify_all_fn( boost::barrier
& b
,
55 boost::fibers::mutex
& mtx
,
56 boost::fibers::condition_variable
& cond
,
59 std::unique_lock
< boost::fibers::mutex
> lk( mtx
);
65 void fn1( boost::barrier
& b
,
66 boost::fibers::mutex
& mtx
,
67 boost::fibers::condition_variable
& cond
,
70 boost::fibers::launch::dispatch
,
75 std::ref( flag
) ).join();
78 void fn2( boost::barrier
& b
,
79 boost::fibers::mutex
& mtx
,
80 boost::fibers::condition_variable
& cond
,
83 boost::fibers::launch::dispatch
,
88 std::ref( flag
) ).join();
91 void fn3( boost::barrier
& b
,
92 boost::fibers::mutex
& mtx
,
93 boost::fibers::condition_variable
& cond
,
96 boost::fibers::launch::dispatch
,
101 std::ref( flag
) ).join();
104 void test_one_waiter_notify_one() {
105 for ( int i
= 0; i
< 10; ++i
) {
106 boost::barrier
b( 2);
110 boost::fibers::mutex mtx
;
111 boost::fibers::condition_variable cond
;
113 BOOST_CHECK( 0 == value1
);
115 boost::thread
t1(std::bind( fn1
, std::ref( b
), std::ref( mtx
), std::ref( cond
), std::ref( flag
) ) );
116 boost::thread
t2(std::bind( fn2
, std::ref( b
), std::ref( mtx
), std::ref( cond
), std::ref( flag
) ) );
121 BOOST_CHECK( 1 == value1
);
125 void test_two_waiter_notify_all() {
126 for ( int i
= 0; i
< 10; ++i
) {
127 boost::barrier
b( 3);
131 boost::fibers::mutex mtx
;
132 boost::fibers::condition_variable cond
;
134 BOOST_CHECK( 0 == value1
);
136 boost::thread
t1(std::bind( fn1
, std::ref( b
), std::ref( mtx
), std::ref( cond
), std::ref( flag
) ) );
137 boost::thread
t2(std::bind( fn1
, std::ref( b
), std::ref( mtx
), std::ref( cond
), std::ref( flag
) ) );
138 boost::thread
t3(std::bind( fn3
, std::ref( b
), std::ref( mtx
), std::ref( cond
), std::ref( flag
) ) );
144 BOOST_CHECK( 2 == value1
);
151 boost::unit_test::test_suite
* init_unit_test_suite( int, char* [])
153 boost::unit_test::test_suite
* test
=
154 BOOST_TEST_SUITE("Boost.Fiber: multithreaded condition_variable test suite");
156 #if ! defined(BOOST_FIBERS_NO_ATOMICS)
157 test
->add( BOOST_TEST_CASE( & test_one_waiter_notify_one
) );
158 test
->add( BOOST_TEST_CASE( & test_two_waiter_notify_all
) );
160 test
->add( BOOST_TEST_CASE( & test_dummy
) );