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