test_mutex_mt_dispatch.cpp 3.9 KB

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