wait_for_pred_pass.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. class Pred
  25. {
  26. int& i_;
  27. public:
  28. explicit Pred(int& i) :
  29. i_(i)
  30. {
  31. }
  32. bool operator()()
  33. {
  34. return i_ != 0;
  35. }
  36. };
  37. boost::condition_variable cv;
  38. boost::mutex mut;
  39. int test1 = 0;
  40. int test2 = 0;
  41. int runs = 0;
  42. typedef boost::chrono::system_clock Clock;
  43. typedef boost::chrono::milliseconds milliseconds;
  44. typedef boost::chrono::milliseconds ms;
  45. typedef boost::chrono::nanoseconds ns;
  46. const ms max_diff(BOOST_THREAD_TEST_TIME_MS);
  47. void f()
  48. {
  49. try {
  50. boost::unique_lock < boost::mutex > lk(mut);
  51. assert(test2 == 0);
  52. test1 = 1;
  53. cv.notify_one();
  54. Clock::time_point t0 = Clock::now();
  55. cv.wait_for(lk, milliseconds(250), Pred(test2));
  56. Clock::time_point t1 = Clock::now();
  57. if (runs == 0)
  58. {
  59. assert(t1 - t0 < max_diff);
  60. assert(test2 != 0);
  61. }
  62. else
  63. {
  64. assert(t1 - t0 - milliseconds(250) < max_diff);
  65. assert(test2 == 0);
  66. }
  67. ++runs;
  68. } catch(...) {
  69. std::cout << "ERROR exception" << __LINE__ << std::endl;
  70. assert(false);
  71. }
  72. }
  73. int main()
  74. {
  75. try
  76. {
  77. boost::unique_lock < boost::mutex > lk(mut);
  78. boost::thread t(f);
  79. BOOST_TEST(test1 == 0);
  80. while (test1 == 0)
  81. cv.wait(lk);
  82. BOOST_TEST(test1 != 0);
  83. test2 = 1;
  84. lk.unlock();
  85. cv.notify_one();
  86. t.join();
  87. } catch(...) {
  88. BOOST_TEST(false);
  89. std::cout << "ERROR exception" << __LINE__ << std::endl;
  90. }
  91. test1 = 0;
  92. test2 = 0;
  93. try
  94. {
  95. boost::unique_lock < boost::mutex > lk(mut);
  96. boost::thread t(f);
  97. BOOST_TEST(test1 == 0);
  98. while (test1 == 0)
  99. cv.wait(lk);
  100. BOOST_TEST(test1 != 0);
  101. lk.unlock();
  102. t.join();
  103. } catch(...) {
  104. BOOST_TEST(false);
  105. std::cout << "ERROR exception" << __LINE__ << std::endl;
  106. }
  107. return boost::report_errors();
  108. }
  109. #else
  110. #error "Test not applicable: BOOST_THREAD_USES_CHRONO not defined for this platform as not supported"
  111. #endif