[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / libcxx / test / std / thread / thread.mutex / thread.once / thread.once.callonce / call_once.pass.cpp
blob7708efcb54c7f98b3704ca60faff74c24ac166c9
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: no-threads
11 // <mutex>
13 // struct once_flag;
15 // template<class Callable, class ...Args>
16 // void call_once(once_flag& flag, Callable&& func, Args&&... args);
18 #include <mutex>
19 #include <thread>
20 #include <cassert>
22 #include "make_test_thread.h"
23 #include "test_macros.h"
25 typedef std::chrono::milliseconds ms;
27 std::once_flag flg0;
29 int init0_called = 0;
31 void init0()
33 std::this_thread::sleep_for(ms(250));
34 ++init0_called;
37 void f0()
39 std::call_once(flg0, init0);
42 std::once_flag flg3;
44 int init3_called = 0;
45 int init3_completed = 0;
47 void init3()
49 ++init3_called;
50 std::this_thread::sleep_for(ms(250));
51 if (init3_called == 1)
52 TEST_THROW(1);
53 ++init3_completed;
56 void f3()
58 #ifndef TEST_HAS_NO_EXCEPTIONS
59 try
61 std::call_once(flg3, init3);
63 catch (...)
66 #endif
69 #if TEST_STD_VER >= 11
71 struct init1
73 static int called;
75 void operator()(int i) {called += i;}
78 int init1::called = 0;
80 std::once_flag flg1;
82 void f1()
84 std::call_once(flg1, init1(), 1);
87 struct init2
89 static int called;
91 void operator()(int i, int j) const {called += i + j;}
94 int init2::called = 0;
96 std::once_flag flg2;
98 void f2()
100 std::call_once(flg2, init2(), 2, 3);
101 std::call_once(flg2, init2(), 4, 5);
104 #endif // TEST_STD_VER >= 11
106 std::once_flag flg41;
107 std::once_flag flg42;
109 int init41_called = 0;
110 int init42_called = 0;
112 void init42();
114 void init41()
116 std::this_thread::sleep_for(ms(250));
117 ++init41_called;
120 void init42()
122 std::this_thread::sleep_for(ms(250));
123 ++init42_called;
126 void f41()
128 std::call_once(flg41, init41);
129 std::call_once(flg42, init42);
132 void f42()
134 std::call_once(flg42, init42);
135 std::call_once(flg41, init41);
138 #if TEST_STD_VER >= 11
140 class MoveOnly
142 #if !defined(__clang__)
143 // GCC 4.8 complains about the following being private
144 public:
145 MoveOnly(const MoveOnly&)
148 #else
149 MoveOnly(const MoveOnly&);
150 #endif
151 public:
152 MoveOnly() {}
153 MoveOnly(MoveOnly&&) {}
155 void operator()(MoveOnly&&)
160 class NonCopyable
162 #if !defined(__clang__)
163 // GCC 4.8 complains about the following being private
164 public:
165 NonCopyable(const NonCopyable&)
168 #else
169 NonCopyable(const NonCopyable&);
170 #endif
171 public:
172 NonCopyable() {}
174 void operator()(int&) {}
177 // reference qualifiers on functions are a C++11 extension
178 struct RefQual
180 int lv_called, rv_called;
182 RefQual() : lv_called(0), rv_called(0) {}
184 void operator()() & { ++lv_called; }
185 void operator()() && { ++rv_called; }
188 #endif // TEST_STD_VER >= 11
190 int main(int, char**)
192 // check basic functionality
194 std::thread t0 = support::make_test_thread(f0);
195 std::thread t1 = support::make_test_thread(f0);
196 t0.join();
197 t1.join();
198 assert(init0_called == 1);
200 #ifndef TEST_HAS_NO_EXCEPTIONS
201 // check basic exception safety
203 std::thread t0 = support::make_test_thread(f3);
204 std::thread t1 = support::make_test_thread(f3);
205 t0.join();
206 t1.join();
207 assert(init3_called == 2);
208 assert(init3_completed == 1);
210 #endif
211 // check deadlock avoidance
213 std::thread t0 = support::make_test_thread(f41);
214 std::thread t1 = support::make_test_thread(f42);
215 t0.join();
216 t1.join();
217 assert(init41_called == 1);
218 assert(init42_called == 1);
220 #if TEST_STD_VER >= 11
221 // check functors with 1 arg
223 std::thread t0 = support::make_test_thread(f1);
224 std::thread t1 = support::make_test_thread(f1);
225 t0.join();
226 t1.join();
227 assert(init1::called == 1);
229 // check functors with 2 args
231 std::thread t0 = support::make_test_thread(f2);
232 std::thread t1 = support::make_test_thread(f2);
233 t0.join();
234 t1.join();
235 assert(init2::called == 5);
238 std::once_flag f;
239 std::call_once(f, MoveOnly(), MoveOnly());
241 // check LWG2442: call_once() shouldn't DECAY_COPY()
243 std::once_flag f;
244 int i = 0;
245 std::call_once(f, NonCopyable(), i);
247 // reference qualifiers on functions are a C++11 extension
249 std::once_flag f1, f2;
250 RefQual rq;
251 std::call_once(f1, rq);
252 assert(rq.lv_called == 1);
253 std::call_once(f2, std::move(rq));
254 assert(rq.rv_called == 1);
256 #endif // TEST_STD_VER >= 11
258 return 0;