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 // <shared_mutex>
11 
12 // template <class Mutex> class shared_lock;
13 
14 // explicit shared_lock(mutex_type& m);
15 
16 #include <shared_mutex>
17 #include <thread>
18 #include <vector>
19 #include <cstdlib>
20 #include <cassert>
21 
22 #if _LIBCPP_STD_VER > 11
23 
24 std::shared_mutex m;
25 
26 typedef std::chrono::system_clock Clock;
27 typedef Clock::time_point time_point;
28 typedef Clock::duration duration;
29 typedef std::chrono::milliseconds ms;
30 typedef std::chrono::nanoseconds ns;
31 
32 void f()
33 {
34     time_point t0 = Clock::now();
35     time_point t1;
36     {
37     std::shared_lock<std::shared_mutex> ul(m);
38     t1 = Clock::now();
39     }
40     ns d = t1 - t0 - ms(250);
41     assert(d < ms(50));  // within 50ms
42 }
43 
44 void g()
45 {
46     time_point t0 = Clock::now();
47     time_point t1;
48     {
49     std::shared_lock<std::shared_mutex> ul(m);
50     t1 = Clock::now();
51     }
52     ns d = t1 - t0;
53     assert(d < ms(50));  // within 50ms
54 }
55 
56 #endif  // _LIBCPP_STD_VER > 11
57 
58 int main()
59 {
60 #if _LIBCPP_STD_VER > 11
61     m.lock();
62     std::vector<std::thread> v;
63     for (int i = 0; i < 5; ++i)
64         v.push_back(std::thread(f));
65     std::this_thread::sleep_for(ms(250));
66     m.unlock();
67     for (auto& t : v)
68         t.join();
69     m.lock_shared();
70     for (auto& t : v)
71         t = std::thread(g);
72     std::thread q(f);
73     std::this_thread::sleep_for(ms(250));
74     m.unlock_shared();
75     for (auto& t : v)
76         t.join();
77     q.join();
78 #endif  // _LIBCPP_STD_VER > 11
79 }
80