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