1ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant//===---------------------- shared_mutex.cpp ------------------------------===//
2ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant//
3ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant//                     The LLVM Compiler Infrastructure
4ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant//
5ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
6ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
7ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant//
8ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant//===----------------------------------------------------------------------===//
9ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
10ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant#define _LIBCPP_BUILDING_SHARED_MUTEX
11ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant#include "shared_mutex"
12ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
13ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant_LIBCPP_BEGIN_NAMESPACE_STD
14ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
15f9f95be93091c60e7c9034670f298d5a2fba8686David Majnemershared_timed_mutex::shared_timed_mutex()
16ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    : __state_(0)
17ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant{
18ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant}
19ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
20ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant// Exclusive ownership
21ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
22ba898e42081aec544a04d282834aa99b13d57803Howard Hinnantvoid
23f9f95be93091c60e7c9034670f298d5a2fba8686David Majnemershared_timed_mutex::lock()
24ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant{
25ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    unique_lock<mutex> lk(__mut_);
26ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    while (__state_ & __write_entered_)
27ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant        __gate1_.wait(lk);
28ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    __state_ |= __write_entered_;
29ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    while (__state_ & __n_readers_)
30ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant        __gate2_.wait(lk);
31ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant}
32ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
33ba898e42081aec544a04d282834aa99b13d57803Howard Hinnantbool
34f9f95be93091c60e7c9034670f298d5a2fba8686David Majnemershared_timed_mutex::try_lock()
35ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant{
36ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    unique_lock<mutex> lk(__mut_);
37ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    if (__state_ == 0)
38ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    {
39ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant        __state_ = __write_entered_;
40ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant        return true;
41ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    }
42ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    return false;
43ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant}
44ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
45ba898e42081aec544a04d282834aa99b13d57803Howard Hinnantvoid
46f9f95be93091c60e7c9034670f298d5a2fba8686David Majnemershared_timed_mutex::unlock()
47ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant{
48ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    lock_guard<mutex> _(__mut_);
49ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    __state_ = 0;
50ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    __gate1_.notify_all();
51ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant}
52ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
53ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant// Shared ownership
54ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
55ba898e42081aec544a04d282834aa99b13d57803Howard Hinnantvoid
56f9f95be93091c60e7c9034670f298d5a2fba8686David Majnemershared_timed_mutex::lock_shared()
57ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant{
58ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    unique_lock<mutex> lk(__mut_);
59ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
60ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant        __gate1_.wait(lk);
61ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    unsigned num_readers = (__state_ & __n_readers_) + 1;
62ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    __state_ &= ~__n_readers_;
63ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    __state_ |= num_readers;
64ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant}
65ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
66ba898e42081aec544a04d282834aa99b13d57803Howard Hinnantbool
67f9f95be93091c60e7c9034670f298d5a2fba8686David Majnemershared_timed_mutex::try_lock_shared()
68ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant{
69ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    unique_lock<mutex> lk(__mut_);
70ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    unsigned num_readers = __state_ & __n_readers_;
71ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
72ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    {
73ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant        ++num_readers;
74ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant        __state_ &= ~__n_readers_;
75ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant        __state_ |= num_readers;
76ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant        return true;
77ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    }
78ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    return false;
79ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant}
80ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
81ba898e42081aec544a04d282834aa99b13d57803Howard Hinnantvoid
82f9f95be93091c60e7c9034670f298d5a2fba8686David Majnemershared_timed_mutex::unlock_shared()
83ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant{
84ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    lock_guard<mutex> _(__mut_);
85ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    unsigned num_readers = (__state_ & __n_readers_) - 1;
86ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    __state_ &= ~__n_readers_;
87ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    __state_ |= num_readers;
88ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    if (__state_ & __write_entered_)
89ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    {
90ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant        if (num_readers == 0)
91ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant            __gate2_.notify_one();
92ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    }
93ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    else
94ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    {
95ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant        if (num_readers == __n_readers_ - 1)
96ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant            __gate1_.notify_one();
97ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant    }
98ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant}
99ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
100ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant
101ba898e42081aec544a04d282834aa99b13d57803Howard Hinnant_LIBCPP_END_NAMESPACE_STD
102