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