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