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