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++03, c++98, c++11
12 
13 // <shared_mutex>
14 
15 // class shared_timed_mutex;
16 
17 // void lock_shared();
18 
19 #include <shared_mutex>
20 #include <thread>
21 #include <vector>
22 #include <cstdlib>
23 #include <cassert>
24 
25 #include "test_macros.h"
26 
27 std::shared_timed_mutex m;
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 
36 ms WaitTime = ms(250);
37 
38 // Thread sanitizer causes more overhead and will sometimes cause this test
39 // to fail. To prevent this we give Thread sanitizer more time to complete the
40 // test.
41 #if !TEST_HAS_FEATURE(thread_sanitizer)
42 ms Tolerance = ms(50);
43 #else
44 ms Tolerance = ms(100);
45 #endif
46 
47 
48 void f()
49 {
50     time_point t0 = Clock::now();
51     m.lock_shared();
52     time_point t1 = Clock::now();
53     m.unlock_shared();
54     ns d = t1 - t0 - WaitTime;
55     assert(d < Tolerance);  // within tolerance
56 }
57 
58 void g()
59 {
60     time_point t0 = Clock::now();
61     m.lock_shared();
62     time_point t1 = Clock::now();
63     m.unlock_shared();
64     ns d = t1 - t0;
65     assert(d < Tolerance);  // within tolerance
66 }
67 
68 
69 int main()
70 {
71     m.lock();
72     std::vector<std::thread> v;
73     for (int i = 0; i < 5; ++i)
74         v.push_back(std::thread(f));
75     std::this_thread::sleep_for(WaitTime);
76     m.unlock();
77     for (auto& t : v)
78         t.join();
79     m.lock_shared();
80     for (auto& t : v)
81         t = std::thread(g);
82     std::thread q(f);
83     std::this_thread::sleep_for(WaitTime);
84     m.unlock_shared();
85     for (auto& t : v)
86         t.join();
87     q.join();
88 }
89