Remove building with NOCRYPTO option
[minix.git] / external / bsd / libc++ / dist / libcxx / src / shared_mutex.cpp
blob874aceb1b03a96f50f4b65002a68e2f14a04df1c
1 //===---------------------- shared_mutex.cpp ------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
10 #include "__config"
11 #ifndef _LIBCPP_HAS_NO_THREADS
13 #define _LIBCPP_BUILDING_SHARED_MUTEX
14 #include "shared_mutex"
16 _LIBCPP_BEGIN_NAMESPACE_STD
18 // Shared Mutex Base
19 __shared_mutex_base::__shared_mutex_base()
20 : __state_(0)
24 // Exclusive ownership
26 void
27 __shared_mutex_base::lock()
29 unique_lock<mutex> lk(__mut_);
30 while (__state_ & __write_entered_)
31 __gate1_.wait(lk);
32 __state_ |= __write_entered_;
33 while (__state_ & __n_readers_)
34 __gate2_.wait(lk);
37 bool
38 __shared_mutex_base::try_lock()
40 unique_lock<mutex> lk(__mut_);
41 if (__state_ == 0)
43 __state_ = __write_entered_;
44 return true;
46 return false;
49 void
50 __shared_mutex_base::unlock()
52 lock_guard<mutex> _(__mut_);
53 __state_ = 0;
54 __gate1_.notify_all();
57 // Shared ownership
59 void
60 __shared_mutex_base::lock_shared()
62 unique_lock<mutex> lk(__mut_);
63 while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
64 __gate1_.wait(lk);
65 unsigned num_readers = (__state_ & __n_readers_) + 1;
66 __state_ &= ~__n_readers_;
67 __state_ |= num_readers;
70 bool
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_)
77 ++num_readers;
78 __state_ &= ~__n_readers_;
79 __state_ |= num_readers;
80 return true;
82 return false;
85 void
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_)
94 if (num_readers == 0)
95 __gate2_.notify_one();
97 else
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