• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 >
g(boost::barrier & b,Mtx & m)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 >
f(boost::barrier & b,Mtx & m)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 >
fn1(boost::barrier & b,Mtx & m)45 void fn1( boost::barrier & b, Mtx & m) {
46     boost::fibers::fiber( boost::fibers::launch::post, g< Mtx >, std::ref( b), std::ref( m) ).join();
47 }
48 
49 template< typename Mtx >
fn2(boost::barrier & b,Mtx & m)50 void fn2( boost::barrier & b, Mtx & m) {
51     boost::fibers::fiber( boost::fibers::launch::post, f< Mtx >, std::ref( b), std::ref( m) ).join();
52 }
53 
test_mutex()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 
test_recursive_mutex()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 
test_timed_mutex()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 
test_recursive_timed_mutex()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 
test_dummy()122 void test_dummy() {
123 }
124 
init_unit_test_suite(int,char * [])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 }
140