wait_until_pred_pass.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. // Copyright (C) 2011 Vicente J. Botet Escriba
  10. //
  11. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  12. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  13. // <boost/thread/condition_variable>
  14. // class condition_variable;
  15. // condition_variable(const condition_variable&) = delete;
  16. #include <boost/thread/condition_variable.hpp>
  17. #include <boost/thread/mutex.hpp>
  18. #include <boost/thread/thread.hpp>
  19. #include <boost/detail/lightweight_test.hpp>
  20. #include <cassert>
  21. #include <iostream>
  22. #include "../../../timming.hpp"
  23. #if defined BOOST_THREAD_USES_CHRONO
  24. typedef boost::chrono::milliseconds milliseconds;
  25. typedef boost::chrono::nanoseconds nanoseconds;
  26. typedef boost::chrono::milliseconds ms;
  27. typedef boost::chrono::nanoseconds ns;
  28. struct Clock
  29. {
  30. typedef boost::chrono::milliseconds duration;
  31. typedef duration::rep rep;
  32. typedef duration::period period;
  33. typedef boost::chrono::time_point<Clock> time_point;
  34. static const bool is_steady = true;
  35. static time_point now()
  36. {
  37. using namespace boost::chrono;
  38. return time_point(duration_cast<duration> (steady_clock::now().time_since_epoch()));
  39. }
  40. };
  41. class Pred
  42. {
  43. int& i_;
  44. public:
  45. explicit Pred(int& i) :
  46. i_(i)
  47. {
  48. }
  49. bool operator()()
  50. {
  51. return i_ != 0;
  52. }
  53. };
  54. boost::condition_variable cv;
  55. boost::mutex mut;
  56. int test1 = 0;
  57. int test2 = 0;
  58. int runs = 0;
  59. const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
  60. void f()
  61. {
  62. try {
  63. boost::unique_lock<boost::mutex> lk(mut);
  64. assert(test2 == 0);
  65. test1 = 1;
  66. cv.notify_one();
  67. Clock::time_point t0 = Clock::now();
  68. Clock::time_point t = t0 + Clock::duration(250);
  69. bool r = cv.wait_until(lk, t, Pred(test2));
  70. Clock::time_point t1 = Clock::now();
  71. if (runs == 0)
  72. {
  73. assert(t1 - t0 < max_diff);
  74. assert(test2 != 0);
  75. assert(r);
  76. }
  77. else
  78. {
  79. const nanoseconds d = t1 - t0 - milliseconds(250);
  80. std::cout << "diff= " << d.count() << std::endl;
  81. std::cout << "max_diff= " << max_diff.count() << std::endl;
  82. assert(d < max_diff);
  83. assert(test2 == 0);
  84. assert(!r);
  85. }
  86. ++runs;
  87. } catch(...) {
  88. std::cout << "ERROR exception" << __LINE__ << std::endl;
  89. assert(false);
  90. }
  91. }
  92. int main()
  93. {
  94. try
  95. {
  96. boost::unique_lock<boost::mutex> lk(mut);
  97. boost::thread t(f);
  98. BOOST_TEST(test1 == 0);
  99. while (test1 == 0)
  100. cv.wait(lk);
  101. BOOST_TEST(test1 != 0);
  102. test2 = 1;
  103. lk.unlock();
  104. cv.notify_one();
  105. t.join();
  106. } catch(...) {
  107. BOOST_TEST(false);
  108. std::cout << "ERROR exception" << __LINE__ << std::endl;
  109. }
  110. test1 = 0;
  111. test2 = 0;
  112. try
  113. {
  114. boost::unique_lock<boost::mutex> lk(mut);
  115. boost::thread t(f);
  116. BOOST_TEST(test1 == 0);
  117. while (test1 == 0)
  118. cv.wait(lk);
  119. BOOST_TEST(test1 != 0);
  120. lk.unlock();
  121. t.join();
  122. } catch(...) {
  123. BOOST_TEST(false);
  124. std::cout << "ERROR exception" << __LINE__ << std::endl;
  125. }
  126. return boost::report_errors();
  127. }
  128. #else
  129. #error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
  130. #endif