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