1 //===---------------------- shared_mutex.cpp ------------------------------===//
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 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_HAS_NO_THREADS
12 #include "shared_mutex"
13 #if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
14 #pragma comment(lib, "pthread")
17 _LIBCPP_BEGIN_NAMESPACE_STD
20 __shared_mutex_base::__shared_mutex_base()
25 // Exclusive ownership
28 __shared_mutex_base::lock()
30 unique_lock
<mutex
> lk(__mut_
);
31 while (__state_
& __write_entered_
)
33 __state_
|= __write_entered_
;
34 while (__state_
& __n_readers_
)
39 __shared_mutex_base::try_lock()
41 unique_lock
<mutex
> lk(__mut_
);
44 __state_
= __write_entered_
;
51 __shared_mutex_base::unlock()
53 lock_guard
<mutex
> _(__mut_
);
55 __gate1_
.notify_all();
61 __shared_mutex_base::lock_shared()
63 unique_lock
<mutex
> lk(__mut_
);
64 while ((__state_
& __write_entered_
) || (__state_
& __n_readers_
) == __n_readers_
)
66 unsigned num_readers
= (__state_
& __n_readers_
) + 1;
67 __state_
&= ~__n_readers_
;
68 __state_
|= num_readers
;
72 __shared_mutex_base::try_lock_shared()
74 unique_lock
<mutex
> lk(__mut_
);
75 unsigned num_readers
= __state_
& __n_readers_
;
76 if (!(__state_
& __write_entered_
) && num_readers
!= __n_readers_
)
79 __state_
&= ~__n_readers_
;
80 __state_
|= num_readers
;
87 __shared_mutex_base::unlock_shared()
89 lock_guard
<mutex
> _(__mut_
);
90 unsigned num_readers
= (__state_
& __n_readers_
) - 1;
91 __state_
&= ~__n_readers_
;
92 __state_
|= num_readers
;
93 if (__state_
& __write_entered_
)
96 __gate2_
.notify_one();
100 if (num_readers
== __n_readers_
- 1)
101 __gate1_
.notify_one();
106 // Shared Timed Mutex
107 // These routines are here for ABI stability
108 shared_timed_mutex::shared_timed_mutex() : __base() {}
109 void shared_timed_mutex::lock() { return __base
.lock(); }
110 bool shared_timed_mutex::try_lock() { return __base
.try_lock(); }
111 void shared_timed_mutex::unlock() { return __base
.unlock(); }
112 void shared_timed_mutex::lock_shared() { return __base
.lock_shared(); }
113 bool shared_timed_mutex::try_lock_shared() { return __base
.try_lock_shared(); }
114 void shared_timed_mutex::unlock_shared() { return __base
.unlock_shared(); }
116 _LIBCPP_END_NAMESPACE_STD
118 #endif // !_LIBCPP_HAS_NO_THREADS