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