Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/system/lib/libcxx/src/shared_mutex.cpp
6175 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
{
42
lock_guard<mutex> _(__mut_);
43
__state_ = 0;
44
}
45
__gate1_.notify_all();
46
}
47
48
// Shared ownership
49
50
void __shared_mutex_base::lock_shared() {
51
unique_lock<mutex> lk(__mut_);
52
while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
53
__gate1_.wait(lk);
54
unsigned num_readers = (__state_ & __n_readers_) + 1;
55
__state_ &= ~__n_readers_;
56
__state_ |= num_readers;
57
}
58
59
bool __shared_mutex_base::try_lock_shared() {
60
unique_lock<mutex> lk(__mut_);
61
unsigned num_readers = __state_ & __n_readers_;
62
if (!(__state_ & __write_entered_) && num_readers != __n_readers_) {
63
++num_readers;
64
__state_ &= ~__n_readers_;
65
__state_ |= num_readers;
66
return true;
67
}
68
return false;
69
}
70
71
void __shared_mutex_base::unlock_shared() {
72
unique_lock<mutex> lk(__mut_);
73
unsigned num_readers = (__state_ & __n_readers_) - 1;
74
__state_ &= ~__n_readers_;
75
__state_ |= num_readers;
76
if (__state_ & __write_entered_) {
77
if (num_readers == 0) {
78
lk.unlock();
79
__gate2_.notify_one();
80
}
81
} else {
82
if (num_readers == __n_readers_ - 1) {
83
lk.unlock();
84
__gate1_.notify_one();
85
}
86
}
87
}
88
89
// Shared Timed Mutex
90
// These routines are here for ABI stability
91
shared_timed_mutex::shared_timed_mutex() : __base_() {}
92
void shared_timed_mutex::lock() { return __base_.lock(); }
93
bool shared_timed_mutex::try_lock() { return __base_.try_lock(); }
94
void shared_timed_mutex::unlock() { return __base_.unlock(); }
95
void shared_timed_mutex::lock_shared() { return __base_.lock_shared(); }
96
bool shared_timed_mutex::try_lock_shared() { return __base_.try_lock_shared(); }
97
void shared_timed_mutex::unlock_shared() { return __base_.unlock_shared(); }
98
99
_LIBCPP_END_NAMESPACE_STD
100
101