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