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