15a83710eSEric Fiselier //===----------------------------------------------------------------------===// 25a83710eSEric Fiselier // 357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65a83710eSEric Fiselier // 75a83710eSEric Fiselier //===----------------------------------------------------------------------===// 85a83710eSEric Fiselier // 9*a7f9895cSLouis Dionne // UNSUPPORTED: no-threads 1031cbe0f2SLouis Dionne // UNSUPPORTED: c++03, c++11 11a55632a0SLouis Dionne // ALLOW_RETRIES: 2 122659663eSLouis Dionne 132659663eSLouis Dionne // dylib support for shared_mutex was added in macosx10.12 14c360553cSLouis Dionne // XFAIL: use_system_cxx_lib && target={{.+}}-apple-macosx10.{{9|10|11}} 155a83710eSEric Fiselier 165a83710eSEric Fiselier // <shared_mutex> 175a83710eSEric Fiselier 185a83710eSEric Fiselier // template <class Mutex> class shared_lock; 195a83710eSEric Fiselier 205a83710eSEric Fiselier // void lock(); 215a83710eSEric Fiselier 225a83710eSEric Fiselier #include <shared_mutex> 235a83710eSEric Fiselier #include <thread> 245a83710eSEric Fiselier #include <vector> 255a83710eSEric Fiselier #include <cstdlib> 265a83710eSEric Fiselier #include <cassert> 275a83710eSEric Fiselier 2856462801SLouis Dionne #include "make_test_thread.h" 294c0a2a98SEric Fiselier #include "test_macros.h" 305a83710eSEric Fiselier 315a83710eSEric Fiselier std::shared_timed_mutex m; 325a83710eSEric Fiselier 335a83710eSEric Fiselier typedef std::chrono::system_clock Clock; 345a83710eSEric Fiselier typedef Clock::time_point time_point; 355a83710eSEric Fiselier typedef Clock::duration duration; 365a83710eSEric Fiselier typedef std::chrono::milliseconds ms; 375a83710eSEric Fiselier typedef std::chrono::nanoseconds ns; 385a83710eSEric Fiselier 394c0a2a98SEric Fiselier ms WaitTime = ms(250); 404c0a2a98SEric Fiselier 414c0a2a98SEric Fiselier // Thread sanitizer causes more overhead and will sometimes cause this test 424c0a2a98SEric Fiselier // to fail. To prevent this we give Thread sanitizer more time to complete the 434c0a2a98SEric Fiselier // test. 447362982eSEric Fiselier #if !defined(TEST_HAS_SANITIZERS) 454c0a2a98SEric Fiselier ms Tolerance = ms(25); 464c0a2a98SEric Fiselier #else 477362982eSEric Fiselier ms Tolerance = ms(25 * 5); 484c0a2a98SEric Fiselier #endif 494c0a2a98SEric Fiselier 504c0a2a98SEric Fiselier f()515a83710eSEric Fiseliervoid f() 525a83710eSEric Fiselier { 535a83710eSEric Fiselier std::shared_lock<std::shared_timed_mutex> lk(m, std::defer_lock); 545a83710eSEric Fiselier time_point t0 = Clock::now(); 555a83710eSEric Fiselier lk.lock(); 565a83710eSEric Fiselier time_point t1 = Clock::now(); 575a83710eSEric Fiselier assert(lk.owns_lock() == true); 584c0a2a98SEric Fiselier ns d = t1 - t0 - WaitTime; 594c0a2a98SEric Fiselier assert(d < Tolerance); // within tolerance 6060d6ef63SRoger Ferrer Ibanez #ifndef TEST_HAS_NO_EXCEPTIONS 615a83710eSEric Fiselier try 625a83710eSEric Fiselier { 635a83710eSEric Fiselier lk.lock(); 645a83710eSEric Fiselier assert(false); 655a83710eSEric Fiselier } 665a83710eSEric Fiselier catch (std::system_error& e) 675a83710eSEric Fiselier { 685a83710eSEric Fiselier assert(e.code().value() == EDEADLK); 695a83710eSEric Fiselier } 7060d6ef63SRoger Ferrer Ibanez #endif 715a83710eSEric Fiselier lk.unlock(); 725a83710eSEric Fiselier lk.release(); 7360d6ef63SRoger Ferrer Ibanez #ifndef TEST_HAS_NO_EXCEPTIONS 745a83710eSEric Fiselier try 755a83710eSEric Fiselier { 765a83710eSEric Fiselier lk.lock(); 775a83710eSEric Fiselier assert(false); 785a83710eSEric Fiselier } 795a83710eSEric Fiselier catch (std::system_error& e) 805a83710eSEric Fiselier { 815a83710eSEric Fiselier assert(e.code().value() == EPERM); 825a83710eSEric Fiselier } 8360d6ef63SRoger Ferrer Ibanez #endif 845a83710eSEric Fiselier } 855a83710eSEric Fiselier main(int,char **)862df59c50SJF Bastienint main(int, char**) 875a83710eSEric Fiselier { 885a83710eSEric Fiselier m.lock(); 895a83710eSEric Fiselier std::vector<std::thread> v; 905a83710eSEric Fiselier for (int i = 0; i < 5; ++i) 9156462801SLouis Dionne v.push_back(support::make_test_thread(f)); 924c0a2a98SEric Fiselier std::this_thread::sleep_for(WaitTime); 935a83710eSEric Fiselier m.unlock(); 945a83710eSEric Fiselier for (auto& t : v) 955a83710eSEric Fiselier t.join(); 962df59c50SJF Bastien 972df59c50SJF Bastien return 0; 985a83710eSEric Fiselier } 99