Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/libcxx/src/shared_mutex.cpp
35147 views
1
//===----------------------------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include <mutex>
10
#include <shared_mutex>
11
#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
12
# pragma comment(lib, "pthread")
13
#endif
14
15
_LIBCPP_BEGIN_NAMESPACE_STD
16
17
// Shared Mutex Base
18
__shared_mutex_base::__shared_mutex_base() : __state_(0) {}
19
20
// Exclusive ownership
21
22
void __shared_mutex_base::lock() {
23
unique_lock<mutex> lk(__mut_);
24
while (__state_ & __write_entered_)
25
__gate1_.wait(lk);
26
__state_ |= __write_entered_;
27
while (__state_ & __n_readers_)
28
__gate2_.wait(lk);
29
}
30
31
bool __shared_mutex_base::try_lock() {
32
unique_lock<mutex> lk(__mut_);
33
if (__state_ == 0) {
34
__state_ = __write_entered_;
35
return true;
36
}
37
return false;
38
}
39
40
void __shared_mutex_base::unlock() {
41
lock_guard<mutex> _(__mut_);
42
__state_ = 0;
43
__gate1_.notify_all();
44
}
45
46
// Shared ownership
47
48
void __shared_mutex_base::lock_shared() {
49
unique_lock<mutex> lk(__mut_);
50
while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
51
__gate1_.wait(lk);
52
unsigned num_readers = (__state_ & __n_readers_) + 1;
53
__state_ &= ~__n_readers_;
54
__state_ |= num_readers;
55
}
56
57
bool __shared_mutex_base::try_lock_shared() {
58
unique_lock<mutex> lk(__mut_);
59
unsigned num_readers = __state_ & __n_readers_;
60
if (!(__state_ & __write_entered_) && num_readers != __n_readers_) {
61
++num_readers;
62
__state_ &= ~__n_readers_;
63
__state_ |= num_readers;
64
return true;
65
}
66
return false;
67
}
68
69
void __shared_mutex_base::unlock_shared() {
70
lock_guard<mutex> _(__mut_);
71
unsigned num_readers = (__state_ & __n_readers_) - 1;
72
__state_ &= ~__n_readers_;
73
__state_ |= num_readers;
74
if (__state_ & __write_entered_) {
75
if (num_readers == 0)
76
__gate2_.notify_one();
77
} else {
78
if (num_readers == __n_readers_ - 1)
79
__gate1_.notify_one();
80
}
81
}
82
83
// Shared Timed Mutex
84
// These routines are here for ABI stability
85
shared_timed_mutex::shared_timed_mutex() : __base_() {}
86
void shared_timed_mutex::lock() { return __base_.lock(); }
87
bool shared_timed_mutex::try_lock() { return __base_.try_lock(); }
88
void shared_timed_mutex::unlock() { return __base_.unlock(); }
89
void shared_timed_mutex::lock_shared() { return __base_.lock_shared(); }
90
bool shared_timed_mutex::try_lock_shared() { return __base_.try_lock_shared(); }
91
void shared_timed_mutex::unlock_shared() { return __base_.unlock_shared(); }
92
93
_LIBCPP_END_NAMESPACE_STD
94
95