]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/30_threads/lock/4.cc
2 // { dg-additional-options "-pthread" { target pthread } }
3 // { dg-require-effective-target c++11 }
4 // { dg-require-gthreads "" }
6 // Copyright (C) 2010-2024 Free Software Foundation, Inc.
8 // This file is part of the GNU ISO C++ Library. This library is free
9 // software; you can redistribute it and/or modify it under the
10 // terms of the GNU General Public License as published by the
11 // Free Software Foundation; either version 3, or (at your option)
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
19 // You should have received a copy of the GNU General Public License along
20 // with this library; see the file COPYING3. If not see
21 // <http://www.gnu.org/licenses/>.
25 #include <testsuite_hooks.h>
27 struct unreliable_lock
30 std::unique_lock
<std::mutex
> l
;
36 unreliable_lock() : l(m
, std::defer_lock
) { }
40 VERIFY( !l
.owns_lock() );
45 if (count
== throw_on
)
52 if (count
== throw_on
)
54 std::unique_lock
<std::mutex
> l2(m
, std::defer_lock
);
63 VERIFY( l
.owns_lock() );
69 int unreliable_lock::count
= 0;
70 int unreliable_lock::throw_on
= -1;
71 int unreliable_lock::lock_on
= -1;
75 unreliable_lock l1
, l2
, l3
;
76 std::mutex m1
, m2
, m3
;
80 unreliable_lock::count
= 0;
81 std::lock(l1
, l2
, l3
);
82 VERIFY( unreliable_lock::count
== 3 );
92 // Repeat with non-heterogeneous arguments
96 unreliable_lock::count
= 0;
97 std::lock(l1
, l2
, l3
, m1
);
98 VERIFY( unreliable_lock::count
== 3 );
102 VERIFY( !m1
.try_lock() ); // already locked
112 unreliable_lock::count
= 0;
113 std::lock(m1
, l1
, l2
, l3
);
114 VERIFY( unreliable_lock::count
== 3 );
115 VERIFY( !m1
.try_lock() ); // already locked
128 unreliable_lock::count
= 0;
129 std::lock(l1
, m1
, l2
, m2
, l3
, m3
);
130 VERIFY( unreliable_lock::count
== 3 );
134 VERIFY( !m1
.try_lock() ); // already locked
135 VERIFY( !m2
.try_lock() ); // already locked
136 VERIFY( !m3
.try_lock() ); // already locked
149 // test behaviour when a lock is already held
152 unreliable_lock::lock_on
= 1;
153 while (unreliable_lock::lock_on
< 3)
155 unreliable_lock::count
= 0;
156 unreliable_lock l1
, l2
, l3
;
157 std::lock(l1
, l2
, l3
);
158 VERIFY( unreliable_lock::count
> 3 );
162 ++unreliable_lock::lock_on
;
170 // Repeat with non-heterogeneous arguments
174 unreliable_lock::lock_on
= 1;
175 while (unreliable_lock::lock_on
< 3)
177 unreliable_lock::count
= 0;
178 unreliable_lock l1
, l2
, l3
;
180 std::lock(l1
, l2
, l3
, m1
);
181 VERIFY( unreliable_lock::count
> 3 );
185 VERIFY( !m1
.try_lock() ); // already locked
187 ++unreliable_lock::lock_on
;
198 // test behaviour when an exception is thrown
199 unreliable_lock::throw_on
= 0;
200 while (unreliable_lock::throw_on
< 3)
202 unreliable_lock::count
= 0;
203 unreliable_lock l1
, l2
, l3
;
207 std::lock(l1
, l2
, l3
);
214 ++unreliable_lock::throw_on
;
217 // Repeat with non-heterogeneous arguments
219 unreliable_lock::throw_on
= 0;
220 while (unreliable_lock::throw_on
< 3)
222 unreliable_lock::count
= 0;
223 unreliable_lock l1
, l2
, l3
;
228 std::lock(l1
, l2
, l3
, m1
);
235 VERIFY( m1
.try_lock() ); // m1 was not left locked by failed std::lock
237 ++unreliable_lock::throw_on
;
240 unreliable_lock::throw_on
= 0;
241 while (unreliable_lock::throw_on
< 3)
243 unreliable_lock::count
= 0;
244 unreliable_lock l1
, l2
, l3
;
249 std::lock(m1
, l1
, l2
, l3
);
256 VERIFY( m1
.try_lock() ); // m1 was not left locked by failed std::lock
258 ++unreliable_lock::throw_on
;