Skip to content

Commit d8456d6

Browse files
committed
futex failed attempt
1 parent 53bce7b commit d8456d6

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

library/std/src/sys/sync/rwlock/futex.rs

+33-3
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,21 @@ impl RwLock {
136136
// Wait for the state to change.
137137
futex_wait(&self.state, state | READERS_WAITING, None);
138138

139-
// Spin again after waking up.
140-
state = self.spin_read();
139+
// FIXME this protocol does not work
140+
state = self.state.load(Relaxed);
141+
if state & MASK < MAX_READERS && !has_readers_waiting(state) {
142+
match self.state.compare_exchange_weak(state, state + READ_LOCKED, Acquire, Relaxed)
143+
{
144+
Ok(_) => return, // Locked!
145+
Err(s) => {
146+
state = s;
147+
continue;
148+
}
149+
}
150+
} else {
151+
// Otherwise, spin again after waking up.
152+
state = self.spin_read();
153+
}
141154
}
142155
}
143156

@@ -166,9 +179,26 @@ impl RwLock {
166179
}
167180
}
168181

182+
// FIXME this does not work
169183
#[inline]
170184
pub unsafe fn downgrade(&self) {
171-
todo!()
185+
// Removes all the write bits and adds a single read bit.
186+
let old_state = self.state.fetch_sub(WRITE_LOCKED - READ_LOCKED, Relaxed);
187+
debug_assert!(
188+
is_write_locked(old_state),
189+
"RwLock must be write locked to call `downgrade`"
190+
);
191+
192+
let state = old_state - WRITE_LOCKED + READ_LOCKED;
193+
debug_assert!(
194+
!is_unlocked(state) && !is_write_locked(state),
195+
"RwLock is somehow not in read mode after `downgrade`"
196+
);
197+
198+
if has_readers_waiting(state) {
199+
self.state.fetch_sub(READERS_WAITING, Relaxed);
200+
futex_wake_all(&self.state);
201+
}
172202
}
173203

174204
#[cold]

0 commit comments

Comments
 (0)