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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // UNSUPPORTED: libcpp-has-no-threads 10 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 specific 15 // algorithm, where when lx.try_lock() fails we start the next attempt 16 // with an unconditional lx.lock(). Thus our algorithm can handle a list 17 // 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 30 class L0 31 { 32 bool locked_; 33 34 public: 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 53 class L1 54 { 55 bool locked_; 56 57 public: 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 76 class L2 77 { 78 bool locked_; 79 80 public: 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 99 int 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_EXCEPTIONS 123 { 124 L0 l0; 125 L2 l1; 126 try 127 { 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 try 141 { 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 try 155 { 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 try 169 { 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 try 183 { 184 std::lock(l0, l1); 185 assert(false); 186 } 187 catch (int) 188 { 189 assert(!l0.locked()); 190 assert(!l1.locked()); 191 } 192 } 193 #endif 194 #if TEST_STD_VER >= 11 195 { 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_EXCEPTIONS 205 { 206 L2 l0; 207 L2 l1; 208 L2 l2; 209 try 210 { 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 #endif 222 { 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_EXCEPTIONS 250 { 251 L0 l0; 252 L0 l1; 253 L2 l2; 254 try 255 { 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 try 271 { 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 try 287 { 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 try 303 { 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 try 319 { 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 try 335 { 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 try 351 { 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 try 367 { 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 try 383 { 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_EXCEPTIONS 395 { 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_EXCEPTIONS 451 { 452 L0 l0; 453 L0 l1; 454 L0 l2; 455 L2 l3; 456 try 457 { 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 try 475 { 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 try 493 { 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 try 511 { 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_EXCEPTIONS 524 #endif // TEST_STD_VER >= 11 525 526 return 0; 527 } 528