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