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 //===----------------------------------------------------------------------===//
8 //
9 // UNSUPPORTED: no-threads
10
11 // This test hangs forever when built against libstdc++ (Oct 2016).
12 // UNSUPPORTED: stdlib=libstdc++
13
14 // This test isn't quite standards-conforming: it's testing our specific
15 // algorithm, where when lx.try_lock() fails we start the next attempt
16 // with an unconditional lx.lock(). Thus our algorithm can handle a list
17 // of mutexes where at-most-one of them is of the evil type `class L1`,
18 // but will loop forever if two or more of them are `class L1`.
19
20 // <mutex>
21
22 // template <class L1, class L2, class... L3>
23 // void lock(L1&, L2&, L3&...);
24
25 #include <mutex>
26 #include <cassert>
27
28 #include "test_macros.h"
29
30 class L0
31 {
32 bool locked_;
33
34 public:
L0()35 L0() : locked_(false) {}
36
lock()37 void lock()
38 {
39 locked_ = true;
40 }
41
try_lock()42 bool try_lock()
43 {
44 locked_ = true;
45 return locked_;
46 }
47
unlock()48 void unlock() {locked_ = false;}
49
locked() const50 bool locked() const {return locked_;}
51 };
52
53 class L1
54 {
55 bool locked_;
56
57 public:
L1()58 L1() : locked_(false) {}
59
lock()60 void lock()
61 {
62 locked_ = true;
63 }
64
try_lock()65 bool try_lock()
66 {
67 locked_ = false;
68 return locked_;
69 }
70
unlock()71 void unlock() {locked_ = false;}
72
locked() const73 bool locked() const {return locked_;}
74 };
75
76 class L2
77 {
78 bool locked_;
79
80 public:
L2()81 L2() : locked_(false) {}
82
lock()83 void lock()
84 {
85 TEST_THROW(1);
86 }
87
try_lock()88 bool try_lock()
89 {
90 TEST_THROW(1);
91 return locked_;
92 }
93
unlock()94 void unlock() {locked_ = false;}
95
locked() const96 bool locked() const {return locked_;}
97 };
98
main(int,char **)99 int main(int, char**)
100 {
101 {
102 L0 l0;
103 L0 l1;
104 std::lock(l0, l1);
105 assert(l0.locked());
106 assert(l1.locked());
107 }
108 {
109 L0 l0;
110 L1 l1;
111 std::lock(l0, l1);
112 assert(l0.locked());
113 assert(l1.locked());
114 }
115 {
116 L1 l0;
117 L0 l1;
118 std::lock(l0, l1);
119 assert(l0.locked());
120 assert(l1.locked());
121 }
122 #ifndef TEST_HAS_NO_EXCEPTIONS
123 {
124 L0 l0;
125 L2 l1;
126 try
127 {
128 std::lock(l0, l1);
129 assert(false);
130 }
131 catch (int)
132 {
133 assert(!l0.locked());
134 assert(!l1.locked());
135 }
136 }
137 {
138 L2 l0;
139 L0 l1;
140 try
141 {
142 std::lock(l0, l1);
143 assert(false);
144 }
145 catch (int)
146 {
147 assert(!l0.locked());
148 assert(!l1.locked());
149 }
150 }
151 {
152 L1 l0;
153 L2 l1;
154 try
155 {
156 std::lock(l0, l1);
157 assert(false);
158 }
159 catch (int)
160 {
161 assert(!l0.locked());
162 assert(!l1.locked());
163 }
164 }
165 {
166 L2 l0;
167 L1 l1;
168 try
169 {
170 std::lock(l0, l1);
171 assert(false);
172 }
173 catch (int)
174 {
175 assert(!l0.locked());
176 assert(!l1.locked());
177 }
178 }
179 {
180 L2 l0;
181 L2 l1;
182 try
183 {
184 std::lock(l0, l1);
185 assert(false);
186 }
187 catch (int)
188 {
189 assert(!l0.locked());
190 assert(!l1.locked());
191 }
192 }
193 #endif
194 #if TEST_STD_VER >= 11
195 {
196 L0 l0;
197 L0 l1;
198 L0 l2;
199 std::lock(l0, l1, l2);
200 assert(l0.locked());
201 assert(l1.locked());
202 assert(l2.locked());
203 }
204 #ifndef TEST_HAS_NO_EXCEPTIONS
205 {
206 L2 l0;
207 L2 l1;
208 L2 l2;
209 try
210 {
211 std::lock(l0, l1, l2);
212 assert(false);
213 }
214 catch (int)
215 {
216 assert(!l0.locked());
217 assert(!l1.locked());
218 assert(!l2.locked());
219 }
220 }
221 #endif
222 {
223 L0 l0;
224 L0 l1;
225 L1 l2;
226 std::lock(l0, l1, l2);
227 assert(l0.locked());
228 assert(l1.locked());
229 assert(l2.locked());
230 }
231 {
232 L0 l0;
233 L1 l1;
234 L0 l2;
235 std::lock(l0, l1, l2);
236 assert(l0.locked());
237 assert(l1.locked());
238 assert(l2.locked());
239 }
240 {
241 L1 l0;
242 L0 l1;
243 L0 l2;
244 std::lock(l0, l1, l2);
245 assert(l0.locked());
246 assert(l1.locked());
247 assert(l2.locked());
248 }
249 #ifndef TEST_HAS_NO_EXCEPTIONS
250 {
251 L0 l0;
252 L0 l1;
253 L2 l2;
254 try
255 {
256 std::lock(l0, l1, l2);
257 assert(false);
258 }
259 catch (int)
260 {
261 assert(!l0.locked());
262 assert(!l1.locked());
263 assert(!l2.locked());
264 }
265 }
266 {
267 L0 l0;
268 L2 l1;
269 L0 l2;
270 try
271 {
272 std::lock(l0, l1, l2);
273 assert(false);
274 }
275 catch (int)
276 {
277 assert(!l0.locked());
278 assert(!l1.locked());
279 assert(!l2.locked());
280 }
281 }
282 {
283 L2 l0;
284 L0 l1;
285 L0 l2;
286 try
287 {
288 std::lock(l0, l1, l2);
289 assert(false);
290 }
291 catch (int)
292 {
293 assert(!l0.locked());
294 assert(!l1.locked());
295 assert(!l2.locked());
296 }
297 }
298 {
299 L2 l0;
300 L2 l1;
301 L0 l2;
302 try
303 {
304 std::lock(l0, l1, l2);
305 assert(false);
306 }
307 catch (int)
308 {
309 assert(!l0.locked());
310 assert(!l1.locked());
311 assert(!l2.locked());
312 }
313 }
314 {
315 L2 l0;
316 L0 l1;
317 L2 l2;
318 try
319 {
320 std::lock(l0, l1, l2);
321 assert(false);
322 }
323 catch (int)
324 {
325 assert(!l0.locked());
326 assert(!l1.locked());
327 assert(!l2.locked());
328 }
329 }
330 {
331 L0 l0;
332 L2 l1;
333 L2 l2;
334 try
335 {
336 std::lock(l0, l1, l2);
337 assert(false);
338 }
339 catch (int)
340 {
341 assert(!l0.locked());
342 assert(!l1.locked());
343 assert(!l2.locked());
344 }
345 }
346 {
347 L2 l0;
348 L2 l1;
349 L1 l2;
350 try
351 {
352 std::lock(l0, l1, l2);
353 assert(false);
354 }
355 catch (int)
356 {
357 assert(!l0.locked());
358 assert(!l1.locked());
359 assert(!l2.locked());
360 }
361 }
362 {
363 L2 l0;
364 L1 l1;
365 L2 l2;
366 try
367 {
368 std::lock(l0, l1, l2);
369 assert(false);
370 }
371 catch (int)
372 {
373 assert(!l0.locked());
374 assert(!l1.locked());
375 assert(!l2.locked());
376 }
377 }
378 {
379 L1 l0;
380 L2 l1;
381 L2 l2;
382 try
383 {
384 std::lock(l0, l1, l2);
385 assert(false);
386 }
387 catch (int)
388 {
389 assert(!l0.locked());
390 assert(!l1.locked());
391 assert(!l2.locked());
392 }
393 }
394 #endif // TEST_HAS_NO_EXCEPTIONS
395 {
396 L0 l0;
397 L0 l1;
398 L0 l2;
399 L0 l3;
400 std::lock(l0, l1, l2, l3);
401 assert(l0.locked());
402 assert(l1.locked());
403 assert(l2.locked());
404 assert(l3.locked());
405 }
406 {
407 L0 l0;
408 L0 l1;
409 L0 l2;
410 L1 l3;
411 std::lock(l0, l1, l2, l3);
412 assert(l0.locked());
413 assert(l1.locked());
414 assert(l2.locked());
415 assert(l3.locked());
416 }
417 {
418 L0 l0;
419 L0 l1;
420 L1 l2;
421 L0 l3;
422 std::lock(l0, l1, l2, l3);
423 assert(l0.locked());
424 assert(l1.locked());
425 assert(l2.locked());
426 assert(l3.locked());
427 }
428 {
429 L0 l0;
430 L1 l1;
431 L0 l2;
432 L0 l3;
433 std::lock(l0, l1, l2, l3);
434 assert(l0.locked());
435 assert(l1.locked());
436 assert(l2.locked());
437 assert(l3.locked());
438 }
439 {
440 L1 l0;
441 L0 l1;
442 L0 l2;
443 L0 l3;
444 std::lock(l0, l1, l2, l3);
445 assert(l0.locked());
446 assert(l1.locked());
447 assert(l2.locked());
448 assert(l3.locked());
449 }
450 #ifndef TEST_HAS_NO_EXCEPTIONS
451 {
452 L0 l0;
453 L0 l1;
454 L0 l2;
455 L2 l3;
456 try
457 {
458 std::lock(l0, l1, l2, l3);
459 assert(false);
460 }
461 catch (int)
462 {
463 assert(!l0.locked());
464 assert(!l1.locked());
465 assert(!l2.locked());
466 assert(!l3.locked());
467 }
468 }
469 {
470 L0 l0;
471 L0 l1;
472 L2 l2;
473 L0 l3;
474 try
475 {
476 std::lock(l0, l1, l2, l3);
477 assert(false);
478 }
479 catch (int)
480 {
481 assert(!l0.locked());
482 assert(!l1.locked());
483 assert(!l2.locked());
484 assert(!l3.locked());
485 }
486 }
487 {
488 L0 l0;
489 L2 l1;
490 L0 l2;
491 L0 l3;
492 try
493 {
494 std::lock(l0, l1, l2, l3);
495 assert(false);
496 }
497 catch (int)
498 {
499 assert(!l0.locked());
500 assert(!l1.locked());
501 assert(!l2.locked());
502 assert(!l3.locked());
503 }
504 }
505 {
506 L2 l0;
507 L0 l1;
508 L0 l2;
509 L0 l3;
510 try
511 {
512 std::lock(l0, l1, l2, l3);
513 assert(false);
514 }
515 catch (int)
516 {
517 assert(!l0.locked());
518 assert(!l1.locked());
519 assert(!l2.locked());
520 assert(!l3.locked());
521 }
522 }
523 #endif // TEST_HAS_NO_EXCEPTIONS
524 #endif // TEST_STD_VER >= 11
525
526 return 0;
527 }
528