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#include "test_macros.h"
21
22class L0
23{
24    bool locked_;
25
26public:
27    L0() : locked_(false) {}
28
29    bool try_lock()
30    {
31        locked_ = true;
32        return locked_;
33    }
34
35    void unlock() {locked_ = false;}
36
37    bool locked() const {return locked_;}
38};
39
40class L1
41{
42    bool locked_;
43
44public:
45    L1() : locked_(false) {}
46
47    bool try_lock()
48    {
49        locked_ = false;
50        return locked_;
51    }
52
53    void unlock() {locked_ = false;}
54
55    bool locked() const {return locked_;}
56};
57
58class L2
59{
60    bool locked_;
61
62public:
63    L2() : locked_(false) {}
64
65    bool try_lock()
66    {
67        TEST_THROW(1);
68        return locked_;
69    }
70
71    void unlock() {locked_ = false;}
72
73    bool locked() const {return locked_;}
74};
75
76int main()
77{
78    {
79        L0 l0;
80        L0 l1;
81        assert(std::try_lock(l0, l1) == -1);
82        assert(l0.locked());
83        assert(l1.locked());
84    }
85    {
86        L0 l0;
87        L1 l1;
88        assert(std::try_lock(l0, l1) == 1);
89        assert(!l0.locked());
90        assert(!l1.locked());
91    }
92    {
93        L1 l0;
94        L0 l1;
95        assert(std::try_lock(l0, l1) == 0);
96        assert(!l0.locked());
97        assert(!l1.locked());
98    }
99#ifndef TEST_HAS_NO_EXCEPTIONS
100    {
101        L0 l0;
102        L2 l1;
103        try
104        {
105            std::try_lock(l0, l1);
106            assert(false);
107        }
108        catch (int)
109        {
110            assert(!l0.locked());
111            assert(!l1.locked());
112        }
113    }
114    {
115        L2 l0;
116        L0 l1;
117        try
118        {
119            std::try_lock(l0, l1);
120            assert(false);
121        }
122        catch (int)
123        {
124            assert(!l0.locked());
125            assert(!l1.locked());
126        }
127    }
128#endif
129#ifndef _LIBCPP_HAS_NO_VARIADICS
130    {
131        L0 l0;
132        L0 l1;
133        L0 l2;
134        assert(std::try_lock(l0, l1, l2) == -1);
135        assert(l0.locked());
136        assert(l1.locked());
137        assert(l2.locked());
138    }
139    {
140        L1 l0;
141        L1 l1;
142        L1 l2;
143        assert(std::try_lock(l0, l1, l2) == 0);
144        assert(!l0.locked());
145        assert(!l1.locked());
146        assert(!l2.locked());
147    }
148#ifndef TEST_HAS_NO_EXCEPTIONS
149    {
150        L2 l0;
151        L2 l1;
152        L2 l2;
153        try
154        {
155            std::try_lock(l0, l1, l2);
156            assert(false);
157        }
158        catch (int)
159        {
160            assert(!l0.locked());
161            assert(!l1.locked());
162            assert(!l2.locked());
163        }
164    }
165    {
166        L0 l0;
167        L1 l1;
168        L2 l2;
169        assert(std::try_lock(l0, l1, l2) == 1);
170        assert(!l0.locked());
171        assert(!l1.locked());
172        assert(!l2.locked());
173    }
174#endif
175    {
176        L0 l0;
177        L0 l1;
178        L1 l2;
179        assert(std::try_lock(l0, l1, l2) == 2);
180        assert(!l0.locked());
181        assert(!l1.locked());
182        assert(!l2.locked());
183    }
184    {
185        L0 l0;
186        L1 l1;
187        L0 l2;
188        assert(std::try_lock(l0, l1, l2) == 1);
189        assert(!l0.locked());
190        assert(!l1.locked());
191        assert(!l2.locked());
192    }
193    {
194        L1 l0;
195        L0 l1;
196        L0 l2;
197        assert(std::try_lock(l0, l1, l2) == 0);
198        assert(!l0.locked());
199        assert(!l1.locked());
200        assert(!l2.locked());
201    }
202#ifndef TEST_HAS_NO_EXCEPTIONS
203    {
204        L0 l0;
205        L0 l1;
206        L2 l2;
207        try
208        {
209            std::try_lock(l0, l1, l2);
210            assert(false);
211        }
212        catch (int)
213        {
214            assert(!l0.locked());
215            assert(!l1.locked());
216            assert(!l2.locked());
217        }
218    }
219    {
220        L0 l0;
221        L2 l1;
222        L0 l2;
223        try
224        {
225            std::try_lock(l0, l1, l2);
226            assert(false);
227        }
228        catch (int)
229        {
230            assert(!l0.locked());
231            assert(!l1.locked());
232            assert(!l2.locked());
233        }
234    }
235    {
236        L2 l0;
237        L0 l1;
238        L0 l2;
239        try
240        {
241            std::try_lock(l0, l1, l2);
242            assert(false);
243        }
244        catch (int)
245        {
246            assert(!l0.locked());
247            assert(!l1.locked());
248            assert(!l2.locked());
249        }
250    }
251#endif
252    {
253        L1 l0;
254        L1 l1;
255        L0 l2;
256        assert(std::try_lock(l0, l1, l2) == 0);
257        assert(!l0.locked());
258        assert(!l1.locked());
259        assert(!l2.locked());
260    }
261    {
262        L1 l0;
263        L0 l1;
264        L1 l2;
265        assert(std::try_lock(l0, l1, l2) == 0);
266        assert(!l0.locked());
267        assert(!l1.locked());
268        assert(!l2.locked());
269    }
270    {
271        L0 l0;
272        L1 l1;
273        L1 l2;
274        assert(std::try_lock(l0, l1, l2) == 1);
275        assert(!l0.locked());
276        assert(!l1.locked());
277        assert(!l2.locked());
278    }
279#ifndef TEST_HAS_NO_EXCEPTIONS
280    {
281        L1 l0;
282        L1 l1;
283        L2 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        L1 l0;
291        L2 l1;
292        L1 l2;
293        assert(std::try_lock(l0, l1, l2) == 0);
294        assert(!l0.locked());
295        assert(!l1.locked());
296        assert(!l2.locked());
297    }
298    {
299        L2 l0;
300        L1 l1;
301        L1 l2;
302        try
303        {
304            std::try_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        L2 l1;
317        L0 l2;
318        try
319        {
320            std::try_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        L2 l0;
332        L0 l1;
333        L2 l2;
334        try
335        {
336            std::try_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        L0 l0;
348        L2 l1;
349        L2 l2;
350        try
351        {
352            std::try_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        L2 l1;
365        L1 l2;
366        try
367        {
368            std::try_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        L2 l0;
380        L1 l1;
381        L2 l2;
382        try
383        {
384            std::try_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    {
395        L1 l0;
396        L2 l1;
397        L2 l2;
398        assert(std::try_lock(l0, l1, l2) == 0);
399        assert(!l0.locked());
400        assert(!l1.locked());
401        assert(!l2.locked());
402    }
403    {
404        L0 l0;
405        L2 l1;
406        L1 l2;
407        try
408        {
409            std::try_lock(l0, l1, l2);
410            assert(false);
411        }
412        catch (int)
413        {
414            assert(!l0.locked());
415            assert(!l1.locked());
416            assert(!l2.locked());
417        }
418    }
419    {
420        L1 l0;
421        L0 l1;
422        L2 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        L1 l0;
430        L2 l1;
431        L0 l2;
432        assert(std::try_lock(l0, l1, l2) == 0);
433        assert(!l0.locked());
434        assert(!l1.locked());
435        assert(!l2.locked());
436    }
437    {
438        L2 l0;
439        L0 l1;
440        L1 l2;
441        try
442        {
443            std::try_lock(l0, l1, l2);
444            assert(false);
445        }
446        catch (int)
447        {
448            assert(!l0.locked());
449            assert(!l1.locked());
450            assert(!l2.locked());
451        }
452    }
453    {
454        L2 l0;
455        L1 l1;
456        L0 l2;
457        try
458        {
459            std::try_lock(l0, l1, l2);
460            assert(false);
461        }
462        catch (int)
463        {
464            assert(!l0.locked());
465            assert(!l1.locked());
466            assert(!l2.locked());
467        }
468    }
469#endif  // TEST_HAS_NO_EXCEPTIONS
470    {
471        L0 l0;
472        L0 l1;
473        L0 l2;
474        L0 l3;
475        assert(std::try_lock(l0, l1, l2, l3) == -1);
476        assert(l0.locked());
477        assert(l1.locked());
478        assert(l2.locked());
479        assert(l3.locked());
480    }
481    {
482        L1 l0;
483        L0 l1;
484        L0 l2;
485        L0 l3;
486        assert(std::try_lock(l0, l1, l2, l3) == 0);
487        assert(!l0.locked());
488        assert(!l1.locked());
489        assert(!l2.locked());
490        assert(!l3.locked());
491    }
492    {
493        L0 l0;
494        L1 l1;
495        L0 l2;
496        L0 l3;
497        assert(std::try_lock(l0, l1, l2, l3) == 1);
498        assert(!l0.locked());
499        assert(!l1.locked());
500        assert(!l2.locked());
501        assert(!l3.locked());
502    }
503    {
504        L0 l0;
505        L0 l1;
506        L1 l2;
507        L0 l3;
508        assert(std::try_lock(l0, l1, l2, l3) == 2);
509        assert(!l0.locked());
510        assert(!l1.locked());
511        assert(!l2.locked());
512        assert(!l3.locked());
513    }
514    {
515        L0 l0;
516        L0 l1;
517        L0 l2;
518        L1 l3;
519        assert(std::try_lock(l0, l1, l2, l3) == 3);
520        assert(!l0.locked());
521        assert(!l1.locked());
522        assert(!l2.locked());
523        assert(!l3.locked());
524    }
525#endif  // _LIBCPP_HAS_NO_VARIADICS
526}
527