Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/c++/src/shared_mutex.cpp
12346 views
1
//===---------------------- shared_mutex.cpp ------------------------------===//
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
#include "__config"
11
#ifndef _LIBCPP_HAS_NO_THREADS
12
13
#include "shared_mutex"
14
15
_LIBCPP_BEGIN_NAMESPACE_STD
16
17
// Shared Mutex Base
18
__shared_mutex_base::__shared_mutex_base()
19
: __state_(0)
20
{
21
}
22
23
// Exclusive ownership
24
25
void
26
__shared_mutex_base::lock()
27
{
28
unique_lock<mutex> lk(__mut_);
29
while (__state_ & __write_entered_)
30
__gate1_.wait(lk);
31
__state_ |= __write_entered_;
32
while (__state_ & __n_readers_)
33
__gate2_.wait(lk);
34
}
35
36
bool
37
__shared_mutex_base::try_lock()
38
{
39
unique_lock<mutex> lk(__mut_);
40
if (__state_ == 0)
41
{
42
__state_ = __write_entered_;
43
return true;
44
}
45
return false;
46
}
47
48
void
49
__shared_mutex_base::unlock()
50
{
51
lock_guard<mutex> _(__mut_);
52
__state_ = 0;
53
__gate1_.notify_all();
54
}
55
56
// Shared ownership
57
58
void
59
__shared_mutex_base::lock_shared()
60
{
61
unique_lock<mutex> lk(__mut_);
62
while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
63
__gate1_.wait(lk);
64
unsigned num_readers = (__state_ & __n_readers_) + 1;
65
__state_ &= ~__n_readers_;
66
__state_ |= num_readers;
67
}
68
69
bool
70
__shared_mutex_base::try_lock_shared()
71
{
72
unique_lock<mutex> lk(__mut_);
73
unsigned num_readers = __state_ & __n_readers_;
74
if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
75
{
76
++num_readers;
77
__state_ &= ~__n_readers_;
78
__state_ |= num_readers;
79
return true;
80
}
81
return false;
82
}
83
84
void
85
__shared_mutex_base::unlock_shared()
86
{
87
lock_guard<mutex> _(__mut_);
88
unsigned num_readers = (__state_ & __n_readers_) - 1;
89
__state_ &= ~__n_readers_;
90
__state_ |= num_readers;
91
if (__state_ & __write_entered_)
92
{
93
if (num_readers == 0)
94
__gate2_.notify_one();
95
}
96
else
97
{
98
if (num_readers == __n_readers_ - 1)
99
__gate1_.notify_one();
100
}
101
}
102
103
104
// Shared Timed Mutex
105
// These routines are here for ABI stability
106
shared_timed_mutex::shared_timed_mutex() : __base() {}
107
void shared_timed_mutex::lock() { return __base.lock(); }
108
bool shared_timed_mutex::try_lock() { return __base.try_lock(); }
109
void shared_timed_mutex::unlock() { return __base.unlock(); }
110
void shared_timed_mutex::lock_shared() { return __base.lock_shared(); }
111
bool shared_timed_mutex::try_lock_shared() { return __base.try_lock_shared(); }
112
void shared_timed_mutex::unlock_shared() { return __base.unlock_shared(); }
113
114
_LIBCPP_END_NAMESPACE_STD
115
116
#endif // !_LIBCPP_HAS_NO_THREADS
117
118