• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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