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
27struct 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
44std::condition_variable cv;
45std::mutex mut;
46
47int test1 = 0;
48int test2 = 0;
49
50int runs = 0;
51
52void 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
76int 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