wait_until.pass.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. // <condition_variable>
  11. // class condition_variable;
  12. // template <class Clock, class Duration>
  13. // cv_status
  14. // wait_until(unique_lock<mutex>& lock,
  15. // const chrono::time_point<Clock, Duration>& abs_time);
  16. #include <condition_variable>
  17. #include <mutex>
  18. #include <thread>
  19. #include <chrono>
  20. #include <cassert>
  21. #include "test_macros.h"
  22. struct TestClock
  23. {
  24. typedef std::chrono::milliseconds duration;
  25. typedef duration::rep rep;
  26. typedef duration::period period;
  27. typedef std::chrono::time_point<TestClock> time_point;
  28. static const bool is_steady = true;
  29. static time_point now()
  30. {
  31. using namespace std::chrono;
  32. return time_point(duration_cast<duration>(
  33. steady_clock::now().time_since_epoch()
  34. ));
  35. }
  36. };
  37. std::condition_variable cv;
  38. std::mutex mut;
  39. int test1 = 0;
  40. int test2 = 0;
  41. int runs = 0;
  42. template <typename Clock>
  43. void f()
  44. {
  45. std::unique_lock<std::mutex> lk(mut);
  46. assert(test2 == 0);
  47. test1 = 1;
  48. cv.notify_one();
  49. typename Clock::time_point t0 = Clock::now();
  50. typename Clock::time_point t = t0 + std::chrono::milliseconds(250);
  51. while (test2 == 0 && cv.wait_until(lk, t) == std::cv_status::no_timeout)
  52. ;
  53. typename Clock::time_point t1 = Clock::now();
  54. if (runs == 0)
  55. {
  56. assert(t1 - t0 < std::chrono::milliseconds(250));
  57. assert(test2 != 0);
  58. }
  59. else
  60. {
  61. assert(t1 - t0 - std::chrono::milliseconds(250) < std::chrono::milliseconds(50));
  62. assert(test2 == 0);
  63. }
  64. ++runs;
  65. }
  66. template <typename Clock>
  67. void run_test()
  68. {
  69. runs = 0;
  70. test1 = 0;
  71. test2 = 0;
  72. {
  73. std::unique_lock<std::mutex>lk(mut);
  74. std::thread t(f<Clock>);
  75. assert(test1 == 0);
  76. while (test1 == 0)
  77. cv.wait(lk);
  78. assert(test1 != 0);
  79. test2 = 1;
  80. lk.unlock();
  81. cv.notify_one();
  82. t.join();
  83. }
  84. test1 = 0;
  85. test2 = 0;
  86. {
  87. std::unique_lock<std::mutex>lk(mut);
  88. std::thread t(f<Clock>);
  89. assert(test1 == 0);
  90. while (test1 == 0)
  91. cv.wait(lk);
  92. assert(test1 != 0);
  93. lk.unlock();
  94. t.join();
  95. }
  96. }
  97. int main(int, char**)
  98. {
  99. run_test<TestClock>();
  100. run_test<std::chrono::steady_clock>();
  101. run_test<std::chrono::system_clock>();
  102. return 0;
  103. }