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