Skip to content

Commit bc4b4ed

Browse files
committed
futex failed attempt
1 parent da56501 commit bc4b4ed

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

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

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,21 @@ impl RwLock {
134134
// Wait for the state to change.
135135
futex_wait(&self.state, state | READERS_WAITING, None);
136136

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

@@ -164,9 +177,26 @@ impl RwLock {
164177
}
165178
}
166179

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

172202
#[cold]

0 commit comments

Comments
 (0)