1 //===---------------------- shared_mutex.cpp ------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 #ifndef _LIBCPP_HAS_NO_THREADS
13 #define _LIBCPP_BUILDING_SHARED_MUTEX
14 #include "shared_mutex"
16 _LIBCPP_BEGIN_NAMESPACE_STD
19 __shared_mutex_base::__shared_mutex_base()
24 // Exclusive ownership
27 __shared_mutex_base::lock()
29 unique_lock<mutex> lk(__mut_);
30 while (__state_ & __write_entered_)
32 __state_ |= __write_entered_;
33 while (__state_ & __n_readers_)
38 __shared_mutex_base::try_lock()
40 unique_lock<mutex> lk(__mut_);
43 __state_ = __write_entered_;
50 __shared_mutex_base::unlock()
52 lock_guard<mutex> _(__mut_);
54 __gate1_.notify_all();
60 __shared_mutex_base::lock_shared()
62 unique_lock<mutex> lk(__mut_);
63 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
65 unsigned num_readers = (__state_ & __n_readers_) + 1;
66 __state_ &= ~__n_readers_;
67 __state_ |= num_readers;
71 __shared_mutex_base::try_lock_shared()
73 unique_lock<mutex> lk(__mut_);
74 unsigned num_readers = __state_ & __n_readers_;
75 if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
78 __state_ &= ~__n_readers_;
79 __state_ |= num_readers;
86 __shared_mutex_base::unlock_shared()
88 lock_guard<mutex> _(__mut_);
89 unsigned num_readers = (__state_ & __n_readers_) - 1;
90 __state_ &= ~__n_readers_;
91 __state_ |= num_readers;
92 if (__state_ & __write_entered_)
95 __gate2_.notify_one();
99 if (num_readers == __n_readers_ - 1)
100 __gate1_.notify_one();
105 // Shared Timed Mutex
106 // These routines are here for ABI stability
107 shared_timed_mutex::shared_timed_mutex() : __base() {}
108 void shared_timed_mutex::lock() { return __base.lock(); }
109 bool shared_timed_mutex::try_lock() { return __base.try_lock(); }
110 void shared_timed_mutex::unlock() { return __base.unlock(); }
111 void shared_timed_mutex::lock_shared() { return __base.lock_shared(); }
112 bool shared_timed_mutex::try_lock_shared() { return __base.try_lock_shared(); }
113 void shared_timed_mutex::unlock_shared() { return __base.unlock_shared(); }
115 _LIBCPP_END_NAMESPACE_STD
117 #endif // !_LIBCPP_HAS_NO_THREADS