From 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 20:24:20 +0200 Subject: Adding upstream version 14.2.21. Signed-off-by: Daniel Baumann --- src/boost/libs/fiber/test/test_mutex_dispatch.cpp | 447 ++++++++++++++++++++++ 1 file changed, 447 insertions(+) create mode 100644 src/boost/libs/fiber/test/test_mutex_dispatch.cpp (limited to 'src/boost/libs/fiber/test/test_mutex_dispatch.cpp') diff --git a/src/boost/libs/fiber/test/test_mutex_dispatch.cpp b/src/boost/libs/fiber/test/test_mutex_dispatch.cpp new file mode 100644 index 00000000..dec8ed4d --- /dev/null +++ b/src/boost/libs/fiber/test/test_mutex_dispatch.cpp @@ -0,0 +1,447 @@ + +// 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 +#include +#include +#include +#include +#include +#include + +#include + +#include + +typedef std::chrono::nanoseconds ns; +typedef std::chrono::milliseconds ms; + +int value1 = 0; +int value2 = 0; + +template< typename M > +void fn1( M & mtx) { + typedef M mutex_type; + typename std::unique_lock< mutex_type > lk( mtx); + ++value1; + for ( int i = 0; i < 3; ++i) + boost::this_fiber::yield(); +} + +template< typename M > +void fn2( M & mtx) { + typedef M mutex_type; + ++value2; + typename std::unique_lock< mutex_type > lk( mtx); + ++value2; +} + +void fn3( boost::fibers::timed_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + m.lock(); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ns(2500000)+ms(2000)); // within 2.5 ms +} + +void fn4( boost::fibers::timed_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + while ( ! m.try_lock() ); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ns(50000000)+ms(2000)); // within 50 ms +} + +void fn5( boost::fibers::timed_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + BOOST_CHECK( m.try_lock_for(ms(300)+ms(2000)) == true); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ns(5000000)+ms(2000)); // within 5 ms +} + +void fn6( boost::fibers::timed_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + BOOST_CHECK(m.try_lock_for(ms(250)) == false); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ns(5000000)+ms(2000)); // within 5 ms +} + +void fn7( boost::fibers::timed_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + BOOST_CHECK(m.try_lock_until(std::chrono::steady_clock::now() + ms(300) + ms(1000)) == true); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ns(5000000)+ms(2000)); // within 5ms +} + +void fn8( boost::fibers::timed_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + BOOST_CHECK(m.try_lock_until(std::chrono::steady_clock::now() + ms(250)) == false); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + ns d = t1 - t0 - ms(250); + ns r = ns(5000000)+ms(2000); // within 6ms + BOOST_CHECK(d < r); // within 6ms +} + +void fn9( boost::fibers::recursive_timed_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + m.lock(); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + m.lock(); + m.unlock(); + m.unlock(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ms(2500)+ms(2000)); // within 2.5 ms +} + +void fn10( boost::fibers::recursive_timed_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + while (!m.try_lock()) ; + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + BOOST_CHECK(m.try_lock()); + m.unlock(); + m.unlock(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ms(50000)+ms(2000)); // within 50 ms +} + +void fn11( boost::fibers::recursive_timed_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + BOOST_CHECK(m.try_lock_for(ms(300)+ms(1000)) == true); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + BOOST_CHECK(m.try_lock()); + m.unlock(); + m.unlock(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ns(5000000)+ms(2000)); // within 5 ms +} + +void fn12( boost::fibers::recursive_timed_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + BOOST_CHECK(m.try_lock_for(ms(250)) == false); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ms(5000)+ms(2000)); // within 5 ms +} + +void fn13( boost::fibers::recursive_timed_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + BOOST_CHECK(m.try_lock_until(std::chrono::steady_clock::now() + ms(300) + ms(1000)) == true); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ns(5000000)+ms(2000)); // within 5 ms +} + +void fn14( boost::fibers::recursive_timed_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + BOOST_CHECK(m.try_lock_until(std::chrono::steady_clock::now() + ms(250)) == false); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ns(5000000)+ms(2000)); // within 5 ms +} + +void fn15( boost::fibers::recursive_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + m.lock(); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + m.lock(); + m.unlock(); + m.unlock(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ns(2500000)+ms(2000)); // within 2.5 ms +} + +void fn16( boost::fibers::recursive_mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + while (!m.try_lock()); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + BOOST_CHECK(m.try_lock()); + m.unlock(); + m.unlock(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ns(50000000)+ms(2000)); // within 50 ms +} + +void fn17( boost::fibers::mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + m.lock(); + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ms(2500)+ms(2000)); // within 2.5 ms +} + +void fn18( boost::fibers::mutex & m) { + std::chrono::steady_clock::time_point t0 = std::chrono::steady_clock::now(); + while (!m.try_lock()) ; + std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now(); + m.unlock(); + ns d = t1 - t0 - ms(250); + BOOST_CHECK(d < ns(50000000)+ms(2000)); // within 50 ms +} + +template< typename M > +struct test_lock { + typedef M mutex_type; + typedef typename std::unique_lock< M > lock_type; + + void operator()() { + mutex_type mtx; + + // Test the lock's constructors. + { + lock_type lk(mtx, std::defer_lock); + BOOST_CHECK(!lk); + } + lock_type lk(mtx); + BOOST_CHECK(lk ? true : false); + + // Test the lock and unlock methods. + lk.unlock(); + BOOST_CHECK(!lk); + lk.lock(); + BOOST_CHECK(lk ? true : false); + } +}; + +template< typename M > +struct test_exclusive { + typedef M mutex_type; + typedef typename std::unique_lock< M > lock_type; + + void operator()() { + value1 = 0; + value2 = 0; + BOOST_CHECK_EQUAL( 0, value1); + BOOST_CHECK_EQUAL( 0, value2); + + mutex_type mtx; + boost::fibers::fiber f1( boost::fibers::launch::dispatch, & fn1< mutex_type >, std::ref( mtx) ); + boost::fibers::fiber f2( boost::fibers::launch::dispatch, & fn2< mutex_type >, std::ref( mtx) ); + BOOST_ASSERT( f1.joinable() ); + BOOST_ASSERT( f2.joinable() ); + + f1.join(); + f2.join(); + BOOST_CHECK_EQUAL( 1, value1); + BOOST_CHECK_EQUAL( 2, value2); + } +}; + +template< typename M > +struct test_recursive_lock { + typedef M mutex_type; + typedef typename std::unique_lock< M > lock_type; + + void operator()() { + mutex_type mx; + lock_type lock1(mx); + lock_type lock2(mx); + } +}; + +void do_test_mutex() { + test_lock< boost::fibers::mutex >()(); + test_exclusive< boost::fibers::mutex >()(); + + { + boost::fibers::mutex mtx; + mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn17, std::ref( mtx) ); + boost::this_fiber::sleep_for( ms(250) ); + mtx.unlock(); + f.join(); + } + + { + boost::fibers::mutex mtx; + mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn18, std::ref( mtx) ); + boost::this_fiber::sleep_for( ms(250) ); + mtx.unlock(); + f.join(); + } +} + +void test_mutex() { + boost::fibers::fiber( boost::fibers::launch::dispatch, & do_test_mutex).join(); +} + +void do_test_recursive_mutex() { + test_lock< boost::fibers::recursive_mutex >()(); + test_exclusive< boost::fibers::recursive_mutex >()(); + test_recursive_lock< boost::fibers::recursive_mutex >()(); + + { + boost::fibers::recursive_mutex mtx; + mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn15, std::ref( mtx) ); + boost::this_fiber::sleep_for( ms(250) ); + mtx.unlock(); + f.join(); + } + + { + boost::fibers::recursive_mutex mtx; + mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn16, std::ref( mtx) ); + boost::this_fiber::sleep_for( ms(250) ); + mtx.unlock(); + f.join(); + } +} + +void test_recursive_mutex() { + boost::fibers::fiber( boost::fibers::launch::dispatch, do_test_recursive_mutex).join(); +} + +void do_test_timed_mutex() { + test_lock< boost::fibers::timed_mutex >()(); + test_exclusive< boost::fibers::timed_mutex >()(); + + { + boost::fibers::timed_mutex timed_mtx; + timed_mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn3, std::ref( timed_mtx) ); + boost::this_fiber::sleep_for( ms(250) ); + timed_mtx.unlock(); + f.join(); + } + + { + boost::fibers::timed_mutex timed_mtx; + timed_mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn4, std::ref( timed_mtx) ); + boost::this_fiber::sleep_for( ms(250) ); + timed_mtx.unlock(); + f.join(); + } + + { + boost::fibers::timed_mutex timed_mtx; + timed_mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn5, std::ref( timed_mtx) ); + boost::this_fiber::sleep_for( ms(250) ); + timed_mtx.unlock(); + f.join(); + } + + { + boost::fibers::timed_mutex timed_mtx; + timed_mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn6, std::ref( timed_mtx) ); + boost::this_fiber::sleep_for( ms(300) ); + timed_mtx.unlock(); + f.join(); + } + + { + boost::fibers::timed_mutex timed_mtx; + timed_mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn7, std::ref( timed_mtx) ); + boost::this_fiber::sleep_for( ms(250) ); + timed_mtx.unlock(); + f.join(); + } + + { + boost::fibers::timed_mutex timed_mtx; + timed_mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn8, std::ref( timed_mtx) ); + boost::this_fiber::sleep_for( ms(300) + ms(1000) ); + timed_mtx.unlock(); + f.join(); + } +} + +void test_timed_mutex() { + boost::fibers::fiber( boost::fibers::launch::dispatch, & do_test_timed_mutex).join(); +} + +void do_test_recursive_timed_mutex() { + test_lock< boost::fibers::recursive_timed_mutex >()(); + test_exclusive< boost::fibers::recursive_timed_mutex >()(); + test_recursive_lock< boost::fibers::recursive_timed_mutex >()(); + + { + boost::fibers::recursive_timed_mutex timed_mtx; + timed_mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn9, std::ref( timed_mtx) ); + boost::this_fiber::sleep_for( ms(250) ); + timed_mtx.unlock(); + f.join(); + } + + { + boost::fibers::recursive_timed_mutex timed_mtx; + timed_mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn10, std::ref( timed_mtx) ); + boost::this_fiber::sleep_for( ms(250) ); + timed_mtx.unlock(); + f.join(); + } + + { + boost::fibers::recursive_timed_mutex timed_mtx; + timed_mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn11, std::ref( timed_mtx) ); + boost::this_fiber::sleep_for( ms(250) ); + timed_mtx.unlock(); + f.join(); + } + + { + boost::fibers::recursive_timed_mutex timed_mtx; + timed_mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn12, std::ref( timed_mtx) ); + boost::this_fiber::sleep_for( ms(400) ); + timed_mtx.unlock(); + f.join(); + } + + { + boost::fibers::recursive_timed_mutex timed_mtx; + timed_mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn13, std::ref( timed_mtx) ); + boost::this_fiber::sleep_for( ms(250) ); + timed_mtx.unlock(); + f.join(); + } + + { + boost::fibers::recursive_timed_mutex timed_mtx; + timed_mtx.lock(); + boost::fibers::fiber f( boost::fibers::launch::dispatch, & fn14, std::ref( timed_mtx) ); + boost::this_fiber::sleep_for( ms(300) ); + timed_mtx.unlock(); + f.join(); + } +} + +void test_recursive_timed_mutex() { + boost::fibers::fiber( boost::fibers::launch::dispatch, & do_test_recursive_timed_mutex).join(); +} + +boost::unit_test::test_suite * init_unit_test_suite( int, char* []) { + boost::unit_test::test_suite * test = + BOOST_TEST_SUITE("Boost.Fiber: mutex test suite"); + + 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) ); + + return test; +} -- cgit v1.2.3