[PowerPC][NFC] Cleanup PPCCTRLoopsVerify pass
[llvm-project.git] / libcxx / src / shared_mutex.cpp
blob5feef9f4889f445b8f453838bb42f1678bf79200
1 //===---------------------- shared_mutex.cpp ------------------------------===//
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 "__config"
10 #ifndef _LIBCPP_HAS_NO_THREADS
12 #include "shared_mutex"
13 #if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB)
14 #pragma comment(lib, "pthread")
15 #endif
17 _LIBCPP_BEGIN_NAMESPACE_STD
19 // Shared Mutex Base
20 __shared_mutex_base::__shared_mutex_base()
21 : __state_(0)
25 // Exclusive ownership
27 void
28 __shared_mutex_base::lock()
30 unique_lock<mutex> lk(__mut_);
31 while (__state_ & __write_entered_)
32 __gate1_.wait(lk);
33 __state_ |= __write_entered_;
34 while (__state_ & __n_readers_)
35 __gate2_.wait(lk);
38 bool
39 __shared_mutex_base::try_lock()
41 unique_lock<mutex> lk(__mut_);
42 if (__state_ == 0)
44 __state_ = __write_entered_;
45 return true;
47 return false;
50 void
51 __shared_mutex_base::unlock()
53 lock_guard<mutex> _(__mut_);
54 __state_ = 0;
55 __gate1_.notify_all();
58 // Shared ownership
60 void
61 __shared_mutex_base::lock_shared()
63 unique_lock<mutex> lk(__mut_);
64 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
65 __gate1_.wait(lk);
66 unsigned num_readers = (__state_ & __n_readers_) + 1;
67 __state_ &= ~__n_readers_;
68 __state_ |= num_readers;
71 bool
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_)
78 ++num_readers;
79 __state_ &= ~__n_readers_;
80 __state_ |= num_readers;
81 return true;
83 return false;
86 void
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_)
95 if (num_readers == 0)
96 __gate2_.notify_one();
98 else
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