1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_HAS_NO_THREADS
14 # include <shared_mutex>
15 # if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
16 # pragma comment(lib, "pthread")
19 _LIBCPP_BEGIN_NAMESPACE_STD
22 __shared_mutex_base::__shared_mutex_base() : __state_(0) {}
24 // Exclusive ownership
26 void __shared_mutex_base::lock() {
27 unique_lock
<mutex
> lk(__mut_
);
28 while (__state_
& __write_entered_
)
30 __state_
|= __write_entered_
;
31 while (__state_
& __n_readers_
)
35 bool __shared_mutex_base::try_lock() {
36 unique_lock
<mutex
> lk(__mut_
);
38 __state_
= __write_entered_
;
44 void __shared_mutex_base::unlock() {
45 lock_guard
<mutex
> _(__mut_
);
47 __gate1_
.notify_all();
52 void __shared_mutex_base::lock_shared() {
53 unique_lock
<mutex
> lk(__mut_
);
54 while ((__state_
& __write_entered_
) || (__state_
& __n_readers_
) == __n_readers_
)
56 unsigned num_readers
= (__state_
& __n_readers_
) + 1;
57 __state_
&= ~__n_readers_
;
58 __state_
|= num_readers
;
61 bool __shared_mutex_base::try_lock_shared() {
62 unique_lock
<mutex
> lk(__mut_
);
63 unsigned num_readers
= __state_
& __n_readers_
;
64 if (!(__state_
& __write_entered_
) && num_readers
!= __n_readers_
) {
66 __state_
&= ~__n_readers_
;
67 __state_
|= num_readers
;
73 void __shared_mutex_base::unlock_shared() {
74 lock_guard
<mutex
> _(__mut_
);
75 unsigned num_readers
= (__state_
& __n_readers_
) - 1;
76 __state_
&= ~__n_readers_
;
77 __state_
|= num_readers
;
78 if (__state_
& __write_entered_
) {
80 __gate2_
.notify_one();
82 if (num_readers
== __n_readers_
- 1)
83 __gate1_
.notify_one();
88 // These routines are here for ABI stability
89 shared_timed_mutex::shared_timed_mutex() : __base_() {}
90 void shared_timed_mutex::lock() { return __base_
.lock(); }
91 bool shared_timed_mutex::try_lock() { return __base_
.try_lock(); }
92 void shared_timed_mutex::unlock() { return __base_
.unlock(); }
93 void shared_timed_mutex::lock_shared() { return __base_
.lock_shared(); }
94 bool shared_timed_mutex::try_lock_shared() { return __base_
.try_lock_shared(); }
95 void shared_timed_mutex::unlock_shared() { return __base_
.unlock_shared(); }
97 _LIBCPP_END_NAMESPACE_STD
99 #endif // !_LIBCPP_HAS_NO_THREADS