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