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