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 // UNSUPPORTED: c++03, c++11 11 12 // dylib support for shared_mutex was added in macosx10.12 13 // XFAIL: with_system_cxx_lib=macosx10.11 14 // XFAIL: with_system_cxx_lib=macosx10.10 15 // XFAIL: with_system_cxx_lib=macosx10.9 16 17 // ALLOW_RETRIES: 2 18 19 // <shared_mutex> 20 21 // template <class Mutex> class shared_lock; 22 23 // void lock(); 24 25 #include <shared_mutex> 26 #include <thread> 27 #include <vector> 28 #include <cstdlib> 29 #include <cassert> 30 31 #include "make_test_thread.h" 32 #include "test_macros.h" 33 34 std::shared_timed_mutex m; 35 36 typedef std::chrono::system_clock Clock; 37 typedef Clock::time_point time_point; 38 typedef Clock::duration duration; 39 typedef std::chrono::milliseconds ms; 40 typedef std::chrono::nanoseconds ns; 41 42 ms WaitTime = ms(250); 43 44 // Thread sanitizer causes more overhead and will sometimes cause this test 45 // to fail. To prevent this we give Thread sanitizer more time to complete the 46 // test. 47 #if !defined(TEST_HAS_SANITIZERS) 48 ms Tolerance = ms(25); 49 #else 50 ms Tolerance = ms(25 * 5); 51 #endif 52 53 f()54void f() 55 { 56 std::shared_lock<std::shared_timed_mutex> lk(m, std::defer_lock); 57 time_point t0 = Clock::now(); 58 lk.lock(); 59 time_point t1 = Clock::now(); 60 assert(lk.owns_lock() == true); 61 ns d = t1 - t0 - WaitTime; 62 assert(d < Tolerance); // within tolerance 63 #ifndef TEST_HAS_NO_EXCEPTIONS 64 try 65 { 66 lk.lock(); 67 assert(false); 68 } 69 catch (std::system_error& e) 70 { 71 assert(e.code().value() == EDEADLK); 72 } 73 #endif 74 lk.unlock(); 75 lk.release(); 76 #ifndef TEST_HAS_NO_EXCEPTIONS 77 try 78 { 79 lk.lock(); 80 assert(false); 81 } 82 catch (std::system_error& e) 83 { 84 assert(e.code().value() == EPERM); 85 } 86 #endif 87 } 88 main(int,char **)89int main(int, char**) 90 { 91 m.lock(); 92 std::vector<std::thread> v; 93 for (int i = 0; i < 5; ++i) 94 v.push_back(support::make_test_thread(f)); 95 std::this_thread::sleep_for(WaitTime); 96 m.unlock(); 97 for (auto& t : v) 98 t.join(); 99 100 return 0; 101 } 102