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
25struct 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
42std::condition_variable cv;
43std::mutex mut;
44
45int test1 = 0;
46int test2 = 0;
47
48int runs = 0;
49
50void 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(50));
69        assert(test2 == 0);
70    }
71    ++runs;
72}
73
74int 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