[MemProf] Templatize CallStackRadixTreeBuilder (NFC) (#117014)
[llvm-project.git] / libcxx / src / shared_mutex.cpp
blob1a346dda027f8e03fe0181a73a8730fb0b71c365
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 //===----------------------------------------------------------------------===//
9 #include <mutex>
10 #include <shared_mutex>
11 #if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
12 # pragma comment(lib, "pthread")
13 #endif
15 _LIBCPP_BEGIN_NAMESPACE_STD
17 // Shared Mutex Base
18 __shared_mutex_base::__shared_mutex_base() : __state_(0) {}
20 // Exclusive ownership
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);
31 bool __shared_mutex_base::try_lock() {
32 unique_lock<mutex> lk(__mut_);
33 if (__state_ == 0) {
34 __state_ = __write_entered_;
35 return true;
37 return false;
40 void __shared_mutex_base::unlock() {
41 lock_guard<mutex> _(__mut_);
42 __state_ = 0;
43 __gate1_.notify_all();
46 // Shared ownership
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;
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;
66 return false;
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();
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(); }
93 _LIBCPP_END_NAMESPACE_STD