]>
git.proxmox.com Git - rustc.git/blob - library/std/src/sys/hermit/rwlock.rs
1 use crate::cell
::UnsafeCell
;
2 use crate::sys
::locks
::{MovableCondvar, Mutex}
;
3 use crate::sys_common
::lazy_box
::{LazyBox, LazyInit}
;
8 state
: UnsafeCell
<State
>,
11 pub type MovableRwLock
= RwLock
;
19 unsafe impl Send
for RwLock {}
20 unsafe impl Sync
for RwLock {}
22 // This rwlock implementation is a relatively simple implementation which has a
23 // condition variable for readers/writers as well as a mutex protecting the
24 // internal state of the lock. A current downside of the implementation is that
25 // unlocking the lock will notify *all* waiters rather than just readers or just
26 // writers. This can cause lots of "thundering stampede" problems. While
27 // hopefully correct this implementation is very likely to want to be changed in
31 pub const fn new() -> RwLock
{
34 cond
: MovableCondvar
::new(),
35 state
: UnsafeCell
::new(State
::Unlocked
),
40 pub unsafe fn read(&self) {
42 while !(*self.state
.get()).inc_readers() {
43 self.cond
.wait(&self.lock
);
49 pub unsafe fn try_read(&self) -> bool
{
51 let ok
= (*self.state
.get()).inc_readers();
57 pub unsafe fn write(&self) {
59 while !(*self.state
.get()).inc_writers() {
60 self.cond
.wait(&self.lock
);
66 pub unsafe fn try_write(&self) -> bool
{
68 let ok
= (*self.state
.get()).inc_writers();
74 pub unsafe fn read_unlock(&self) {
76 let notify
= (*self.state
.get()).dec_readers();
79 // FIXME: should only wake up one of these some of the time
80 self.cond
.notify_all();
85 pub unsafe fn write_unlock(&self) {
87 (*self.state
.get()).dec_writers();
89 // FIXME: should only wake up one of these some of the time
90 self.cond
.notify_all();
95 fn inc_readers(&mut self) -> bool
{
98 *self = State
::Reading(1);
101 State
::Reading(ref mut cnt
) => {
105 State
::Writing
=> false,
109 fn inc_writers(&mut self) -> bool
{
112 *self = State
::Writing
;
115 State
::Reading(_
) | State
::Writing
=> false,
119 fn dec_readers(&mut self) -> bool
{
120 let zero
= match *self {
121 State
::Reading(ref mut cnt
) => {
125 State
::Unlocked
| State
::Writing
=> invalid(),
128 *self = State
::Unlocked
;
133 fn dec_writers(&mut self) {
136 State
::Unlocked
| State
::Reading(_
) => invalid(),
138 *self = State
::Unlocked
;
143 panic
!("inconsistent rwlock");