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