528 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// UNSUPPORTED: no-threads10 11// This test hangs forever when built against libstdc++ (Oct 2016).12// UNSUPPORTED: stdlib=libstdc++13 14// This test isn't quite standards-conforming: it's testing our specific15// algorithm, where when lx.try_lock() fails we start the next attempt16// with an unconditional lx.lock(). Thus our algorithm can handle a list17// of mutexes where at-most-one of them is of the evil type `class L1`,18// but will loop forever if two or more of them are `class L1`.19 20// <mutex>21 22// template <class L1, class L2, class... L3>23// void lock(L1&, L2&, L3&...);24 25#include <mutex>26#include <cassert>27 28#include "test_macros.h"29 30class L031{32 bool locked_;33 34public:35 L0() : locked_(false) {}36 37 void lock()38 {39 locked_ = true;40 }41 42 bool try_lock()43 {44 locked_ = true;45 return locked_;46 }47 48 void unlock() {locked_ = false;}49 50 bool locked() const {return locked_;}51};52 53class L154{55 bool locked_;56 57public:58 L1() : locked_(false) {}59 60 void lock()61 {62 locked_ = true;63 }64 65 bool try_lock()66 {67 locked_ = false;68 return locked_;69 }70 71 void unlock() {locked_ = false;}72 73 bool locked() const {return locked_;}74};75 76class L277{78 bool locked_;79 80public:81 L2() : locked_(false) {}82 83 void lock()84 {85 TEST_THROW(1);86 }87 88 bool try_lock()89 {90 TEST_THROW(1);91 return locked_;92 }93 94 void unlock() {locked_ = false;}95 96 bool locked() const {return locked_;}97};98 99int main(int, char**)100{101 {102 L0 l0;103 L0 l1;104 std::lock(l0, l1);105 assert(l0.locked());106 assert(l1.locked());107 }108 {109 L0 l0;110 L1 l1;111 std::lock(l0, l1);112 assert(l0.locked());113 assert(l1.locked());114 }115 {116 L1 l0;117 L0 l1;118 std::lock(l0, l1);119 assert(l0.locked());120 assert(l1.locked());121 }122#ifndef TEST_HAS_NO_EXCEPTIONS123 {124 L0 l0;125 L2 l1;126 try127 {128 std::lock(l0, l1);129 assert(false);130 }131 catch (int)132 {133 assert(!l0.locked());134 assert(!l1.locked());135 }136 }137 {138 L2 l0;139 L0 l1;140 try141 {142 std::lock(l0, l1);143 assert(false);144 }145 catch (int)146 {147 assert(!l0.locked());148 assert(!l1.locked());149 }150 }151 {152 L1 l0;153 L2 l1;154 try155 {156 std::lock(l0, l1);157 assert(false);158 }159 catch (int)160 {161 assert(!l0.locked());162 assert(!l1.locked());163 }164 }165 {166 L2 l0;167 L1 l1;168 try169 {170 std::lock(l0, l1);171 assert(false);172 }173 catch (int)174 {175 assert(!l0.locked());176 assert(!l1.locked());177 }178 }179 {180 L2 l0;181 L2 l1;182 try183 {184 std::lock(l0, l1);185 assert(false);186 }187 catch (int)188 {189 assert(!l0.locked());190 assert(!l1.locked());191 }192 }193#endif194#if TEST_STD_VER >= 11195 {196 L0 l0;197 L0 l1;198 L0 l2;199 std::lock(l0, l1, l2);200 assert(l0.locked());201 assert(l1.locked());202 assert(l2.locked());203 }204#ifndef TEST_HAS_NO_EXCEPTIONS205 {206 L2 l0;207 L2 l1;208 L2 l2;209 try210 {211 std::lock(l0, l1, l2);212 assert(false);213 }214 catch (int)215 {216 assert(!l0.locked());217 assert(!l1.locked());218 assert(!l2.locked());219 }220 }221#endif222 {223 L0 l0;224 L0 l1;225 L1 l2;226 std::lock(l0, l1, l2);227 assert(l0.locked());228 assert(l1.locked());229 assert(l2.locked());230 }231 {232 L0 l0;233 L1 l1;234 L0 l2;235 std::lock(l0, l1, l2);236 assert(l0.locked());237 assert(l1.locked());238 assert(l2.locked());239 }240 {241 L1 l0;242 L0 l1;243 L0 l2;244 std::lock(l0, l1, l2);245 assert(l0.locked());246 assert(l1.locked());247 assert(l2.locked());248 }249#ifndef TEST_HAS_NO_EXCEPTIONS250 {251 L0 l0;252 L0 l1;253 L2 l2;254 try255 {256 std::lock(l0, l1, l2);257 assert(false);258 }259 catch (int)260 {261 assert(!l0.locked());262 assert(!l1.locked());263 assert(!l2.locked());264 }265 }266 {267 L0 l0;268 L2 l1;269 L0 l2;270 try271 {272 std::lock(l0, l1, l2);273 assert(false);274 }275 catch (int)276 {277 assert(!l0.locked());278 assert(!l1.locked());279 assert(!l2.locked());280 }281 }282 {283 L2 l0;284 L0 l1;285 L0 l2;286 try287 {288 std::lock(l0, l1, l2);289 assert(false);290 }291 catch (int)292 {293 assert(!l0.locked());294 assert(!l1.locked());295 assert(!l2.locked());296 }297 }298 {299 L2 l0;300 L2 l1;301 L0 l2;302 try303 {304 std::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 L0 l1;317 L2 l2;318 try319 {320 std::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 L0 l0;332 L2 l1;333 L2 l2;334 try335 {336 std::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 L2 l0;348 L2 l1;349 L1 l2;350 try351 {352 std::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 L1 l1;365 L2 l2;366 try367 {368 std::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 L1 l0;380 L2 l1;381 L2 l2;382 try383 {384 std::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#endif // TEST_HAS_NO_EXCEPTIONS395 {396 L0 l0;397 L0 l1;398 L0 l2;399 L0 l3;400 std::lock(l0, l1, l2, l3);401 assert(l0.locked());402 assert(l1.locked());403 assert(l2.locked());404 assert(l3.locked());405 }406 {407 L0 l0;408 L0 l1;409 L0 l2;410 L1 l3;411 std::lock(l0, l1, l2, l3);412 assert(l0.locked());413 assert(l1.locked());414 assert(l2.locked());415 assert(l3.locked());416 }417 {418 L0 l0;419 L0 l1;420 L1 l2;421 L0 l3;422 std::lock(l0, l1, l2, l3);423 assert(l0.locked());424 assert(l1.locked());425 assert(l2.locked());426 assert(l3.locked());427 }428 {429 L0 l0;430 L1 l1;431 L0 l2;432 L0 l3;433 std::lock(l0, l1, l2, l3);434 assert(l0.locked());435 assert(l1.locked());436 assert(l2.locked());437 assert(l3.locked());438 }439 {440 L1 l0;441 L0 l1;442 L0 l2;443 L0 l3;444 std::lock(l0, l1, l2, l3);445 assert(l0.locked());446 assert(l1.locked());447 assert(l2.locked());448 assert(l3.locked());449 }450#ifndef TEST_HAS_NO_EXCEPTIONS451 {452 L0 l0;453 L0 l1;454 L0 l2;455 L2 l3;456 try457 {458 std::lock(l0, l1, l2, l3);459 assert(false);460 }461 catch (int)462 {463 assert(!l0.locked());464 assert(!l1.locked());465 assert(!l2.locked());466 assert(!l3.locked());467 }468 }469 {470 L0 l0;471 L0 l1;472 L2 l2;473 L0 l3;474 try475 {476 std::lock(l0, l1, l2, l3);477 assert(false);478 }479 catch (int)480 {481 assert(!l0.locked());482 assert(!l1.locked());483 assert(!l2.locked());484 assert(!l3.locked());485 }486 }487 {488 L0 l0;489 L2 l1;490 L0 l2;491 L0 l3;492 try493 {494 std::lock(l0, l1, l2, l3);495 assert(false);496 }497 catch (int)498 {499 assert(!l0.locked());500 assert(!l1.locked());501 assert(!l2.locked());502 assert(!l3.locked());503 }504 }505 {506 L2 l0;507 L0 l1;508 L0 l2;509 L0 l3;510 try511 {512 std::lock(l0, l1, l2, l3);513 assert(false);514 }515 catch (int)516 {517 assert(!l0.locked());518 assert(!l1.locked());519 assert(!l2.locked());520 assert(!l3.locked());521 }522 }523#endif // TEST_HAS_NO_EXCEPTIONS524#endif // TEST_STD_VER >= 11525 526 return 0;527}528