wait_until_pred.pass.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // UNSUPPORTED: libcpp-has-no-threads
  10. // FLAKY_TEST.
  11. // <condition_variable>
  12. // class condition_variable;
  13. // template <class Clock, class Duration, class Predicate>
  14. // bool
  15. // wait_until(unique_lock<mutex>& lock,
  16. // const chrono::time_point<Clock, Duration>& abs_time,
  17. // Predicate pred);
  18. #include <condition_variable>
  19. #include <mutex>
  20. #include <thread>
  21. #include <chrono>
  22. #include <cassert>
  23. #include "test_macros.h"
  24. struct Clock
  25. {
  26. typedef std::chrono::milliseconds duration;
  27. typedef duration::rep rep;
  28. typedef duration::period period;
  29. typedef std::chrono::time_point<Clock> time_point;
  30. static const bool is_steady = true;
  31. static time_point now()
  32. {
  33. using namespace std::chrono;
  34. return time_point(duration_cast<duration>(
  35. steady_clock::now().time_since_epoch()
  36. ));
  37. }
  38. };
  39. class Pred
  40. {
  41. int& i_;
  42. public:
  43. explicit Pred(int& i) : i_(i) {}
  44. bool operator()() {return i_ != 0;}
  45. };
  46. std::condition_variable cv;
  47. std::mutex mut;
  48. int test1 = 0;
  49. int test2 = 0;
  50. int runs = 0;
  51. void f()
  52. {
  53. std::unique_lock<std::mutex> lk(mut);
  54. assert(test2 == 0);
  55. test1 = 1;
  56. cv.notify_one();
  57. Clock::time_point t0 = Clock::now();
  58. Clock::time_point t = t0 + Clock::duration(250);
  59. bool r = cv.wait_until(lk, t, Pred(test2));
  60. Clock::time_point t1 = Clock::now();
  61. if (runs == 0)
  62. {
  63. assert(t1 - t0 < Clock::duration(250));
  64. assert(test2 != 0);
  65. assert(r);
  66. }
  67. else
  68. {
  69. assert(t1 - t0 - Clock::duration(250) < Clock::duration(50));
  70. assert(test2 == 0);
  71. assert(!r);
  72. }
  73. ++runs;
  74. }
  75. int main(int, char**)
  76. {
  77. {
  78. std::unique_lock<std::mutex>lk(mut);
  79. std::thread t(f);
  80. assert(test1 == 0);
  81. while (test1 == 0)
  82. cv.wait(lk);
  83. assert(test1 != 0);
  84. test2 = 1;
  85. lk.unlock();
  86. cv.notify_one();
  87. t.join();
  88. }
  89. test1 = 0;
  90. test2 = 0;
  91. {
  92. std::unique_lock<std::mutex>lk(mut);
  93. std::thread t(f);
  94. assert(test1 == 0);
  95. while (test1 == 0)
  96. cv.wait(lk);
  97. assert(test1 != 0);
  98. lk.unlock();
  99. t.join();
  100. }
  101. return 0;
  102. }