1*89a1d03eSRichard // RUN: %check_clang_tidy %s bugprone-spuriously-wake-up-functions %t -- --
2*89a1d03eSRichard #define NULL 0
3*89a1d03eSRichard
4*89a1d03eSRichard namespace std {
5*89a1d03eSRichard using intmax_t = int;
6*89a1d03eSRichard
7*89a1d03eSRichard template <intmax_t N, intmax_t D = 1>
8*89a1d03eSRichard class ratio {
9*89a1d03eSRichard public:
10*89a1d03eSRichard static constexpr intmax_t num = 0;
11*89a1d03eSRichard static constexpr intmax_t den = 0;
12*89a1d03eSRichard typedef ratio<num, den> type;
13*89a1d03eSRichard };
14*89a1d03eSRichard typedef ratio<1, 1000> milli;
15*89a1d03eSRichard namespace chrono {
16*89a1d03eSRichard
17*89a1d03eSRichard template <class Rep, class Period = ratio<1>>
18*89a1d03eSRichard class duration {
19*89a1d03eSRichard public:
20*89a1d03eSRichard using rep = Rep;
21*89a1d03eSRichard using period = Period;
22*89a1d03eSRichard
23*89a1d03eSRichard public:
24*89a1d03eSRichard constexpr duration() = default;
25*89a1d03eSRichard template <class Rep2>
26*89a1d03eSRichard constexpr explicit duration(const Rep2 &r);
27*89a1d03eSRichard template <class Rep2, class Period2>
28*89a1d03eSRichard constexpr duration(const duration<Rep2, Period2> &d);
29*89a1d03eSRichard ~duration() = default;
30*89a1d03eSRichard duration(const duration &) = default;
31*89a1d03eSRichard };
32*89a1d03eSRichard
33*89a1d03eSRichard template <class Clock, class Duration = typename Clock::duration>
34*89a1d03eSRichard class time_point {
35*89a1d03eSRichard public:
36*89a1d03eSRichard using clock = Clock;
37*89a1d03eSRichard using duration = Duration;
38*89a1d03eSRichard
39*89a1d03eSRichard public:
40*89a1d03eSRichard constexpr time_point();
41*89a1d03eSRichard constexpr explicit time_point(const duration &d);
42*89a1d03eSRichard template <class Duration2>
43*89a1d03eSRichard constexpr time_point(const time_point<clock, Duration2> &t);
44*89a1d03eSRichard };
45*89a1d03eSRichard
46*89a1d03eSRichard using milliseconds = duration<int, milli>;
47*89a1d03eSRichard
48*89a1d03eSRichard class system_clock {
49*89a1d03eSRichard public:
50*89a1d03eSRichard typedef milliseconds duration;
51*89a1d03eSRichard typedef duration::rep rep;
52*89a1d03eSRichard typedef duration::period period;
53*89a1d03eSRichard typedef chrono::time_point<system_clock> time_point;
54*89a1d03eSRichard
55*89a1d03eSRichard static time_point now() noexcept;
56*89a1d03eSRichard };
57*89a1d03eSRichard } // namespace chrono
58*89a1d03eSRichard
59*89a1d03eSRichard class mutex;
60*89a1d03eSRichard template <class Mutex>
61*89a1d03eSRichard class unique_lock {
62*89a1d03eSRichard public:
63*89a1d03eSRichard typedef Mutex mutex_type;
64*89a1d03eSRichard
65*89a1d03eSRichard unique_lock() noexcept;
66*89a1d03eSRichard explicit unique_lock(mutex_type &m);
67*89a1d03eSRichard };
68*89a1d03eSRichard
69*89a1d03eSRichard class mutex {
70*89a1d03eSRichard public:
71*89a1d03eSRichard constexpr mutex() noexcept;
72*89a1d03eSRichard ~mutex();
73*89a1d03eSRichard mutex(const mutex &) = delete;
74*89a1d03eSRichard mutex &operator=(const mutex &) = delete;
75*89a1d03eSRichard };
76*89a1d03eSRichard
77*89a1d03eSRichard enum class cv_status {
78*89a1d03eSRichard no_timeout,
79*89a1d03eSRichard timeout
80*89a1d03eSRichard };
81*89a1d03eSRichard
82*89a1d03eSRichard class condition_variable {
83*89a1d03eSRichard public:
84*89a1d03eSRichard condition_variable();
85*89a1d03eSRichard ~condition_variable();
86*89a1d03eSRichard condition_variable(const condition_variable &) = delete;
87*89a1d03eSRichard
88*89a1d03eSRichard void wait(unique_lock<mutex> &lock);
89*89a1d03eSRichard template <class Predicate>
90*89a1d03eSRichard void wait(unique_lock<mutex> &lock, Predicate pred);
91*89a1d03eSRichard template <class Clock, class Duration>
wait_until(unique_lock<mutex> & lock,const chrono::time_point<Clock,Duration> & abs_time)92*89a1d03eSRichard cv_status wait_until(unique_lock<mutex> &lock,
93*89a1d03eSRichard const chrono::time_point<Clock, Duration> &abs_time){};
94*89a1d03eSRichard template <class Clock, class Duration, class Predicate>
wait_until(unique_lock<mutex> & lock,const chrono::time_point<Clock,Duration> & abs_time,Predicate pred)95*89a1d03eSRichard bool wait_until(unique_lock<mutex> &lock,
96*89a1d03eSRichard const chrono::time_point<Clock, Duration> &abs_time,
97*89a1d03eSRichard Predicate pred){};
98*89a1d03eSRichard template <class Rep, class Period>
wait_for(unique_lock<mutex> & lock,const chrono::duration<Rep,Period> & rel_time)99*89a1d03eSRichard cv_status wait_for(unique_lock<mutex> &lock,
100*89a1d03eSRichard const chrono::duration<Rep, Period> &rel_time){};
101*89a1d03eSRichard template <class Rep, class Period, class Predicate>
wait_for(unique_lock<mutex> & lock,const chrono::duration<Rep,Period> & rel_time,Predicate pred)102*89a1d03eSRichard bool wait_for(unique_lock<mutex> &lock,
103*89a1d03eSRichard const chrono::duration<Rep, Period> &rel_time,
104*89a1d03eSRichard Predicate pred){};
105*89a1d03eSRichard };
106*89a1d03eSRichard
107*89a1d03eSRichard } // namespace std
108*89a1d03eSRichard
109*89a1d03eSRichard struct Node1 {
110*89a1d03eSRichard void *Node1;
111*89a1d03eSRichard struct Node1 *next;
112*89a1d03eSRichard };
113*89a1d03eSRichard
114*89a1d03eSRichard static Node1 list;
115*89a1d03eSRichard static std::mutex m;
116*89a1d03eSRichard static std::condition_variable condition;
117*89a1d03eSRichard
consume_list_element(std::condition_variable & condition)118*89a1d03eSRichard void consume_list_element(std::condition_variable &condition) {
119*89a1d03eSRichard std::unique_lock<std::mutex> lk(m);
120*89a1d03eSRichard
121*89a1d03eSRichard if (list.next == nullptr) {
122*89a1d03eSRichard condition.wait(lk);
123*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'wait' should be placed inside a while statement or used with a conditional parameter [bugprone-spuriously-wake-up-functions]
124*89a1d03eSRichard }
125*89a1d03eSRichard
126*89a1d03eSRichard while (list.next == nullptr) {
127*89a1d03eSRichard condition.wait(lk);
128*89a1d03eSRichard }
129*89a1d03eSRichard
130*89a1d03eSRichard do {
131*89a1d03eSRichard condition.wait(lk);
132*89a1d03eSRichard } while (list.next == nullptr);
133*89a1d03eSRichard
134*89a1d03eSRichard for (;; list.next == nullptr) {
135*89a1d03eSRichard condition.wait(lk);
136*89a1d03eSRichard }
137*89a1d03eSRichard
138*89a1d03eSRichard if (list.next == nullptr) {
139*89a1d03eSRichard while (list.next == nullptr) {
140*89a1d03eSRichard condition.wait(lk);
141*89a1d03eSRichard }
142*89a1d03eSRichard }
143*89a1d03eSRichard
144*89a1d03eSRichard if (list.next == nullptr) {
145*89a1d03eSRichard do {
146*89a1d03eSRichard condition.wait(lk);
147*89a1d03eSRichard } while (list.next == nullptr);
148*89a1d03eSRichard }
149*89a1d03eSRichard
150*89a1d03eSRichard if (list.next == nullptr) {
151*89a1d03eSRichard for (;; list.next == nullptr) {
152*89a1d03eSRichard condition.wait(lk);
153*89a1d03eSRichard }
154*89a1d03eSRichard }
155*89a1d03eSRichard using durtype = std::chrono::duration<int, std::milli>;
156*89a1d03eSRichard durtype dur = std::chrono::duration<int, std::milli>();
157*89a1d03eSRichard if (list.next == nullptr) {
158*89a1d03eSRichard condition.wait_for(lk, dur);
159*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'wait_for' should be placed inside a while statement or used with a conditional parameter [bugprone-spuriously-wake-up-functions]
160*89a1d03eSRichard }
161*89a1d03eSRichard if (list.next == nullptr) {
162*89a1d03eSRichard condition.wait_for(lk, dur, [] { return 1; });
163*89a1d03eSRichard }
164*89a1d03eSRichard while (list.next == nullptr) {
165*89a1d03eSRichard condition.wait_for(lk, dur);
166*89a1d03eSRichard }
167*89a1d03eSRichard do {
168*89a1d03eSRichard condition.wait_for(lk, dur);
169*89a1d03eSRichard } while (list.next == nullptr);
170*89a1d03eSRichard for (;; list.next == nullptr) {
171*89a1d03eSRichard condition.wait_for(lk, dur);
172*89a1d03eSRichard }
173*89a1d03eSRichard
174*89a1d03eSRichard auto now = std::chrono::system_clock::now();
175*89a1d03eSRichard if (list.next == nullptr) {
176*89a1d03eSRichard condition.wait_until(lk, now);
177*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'wait_until' should be placed inside a while statement or used with a conditional parameter [bugprone-spuriously-wake-up-functions]
178*89a1d03eSRichard }
179*89a1d03eSRichard if (list.next == nullptr) {
180*89a1d03eSRichard condition.wait_until(lk, now, [] { return 1; });
181*89a1d03eSRichard }
182*89a1d03eSRichard while (list.next == nullptr) {
183*89a1d03eSRichard condition.wait_until(lk, now);
184*89a1d03eSRichard }
185*89a1d03eSRichard do {
186*89a1d03eSRichard condition.wait_until(lk, now);
187*89a1d03eSRichard } while (list.next == nullptr);
188*89a1d03eSRichard for (;; list.next == nullptr) {
189*89a1d03eSRichard condition.wait_until(lk, now);
190*89a1d03eSRichard }
191*89a1d03eSRichard }
192