Always return false in futex_wake on {Free,DragonFly}BSD.

This commit is contained in:
Mara Bos 2022-04-29 16:44:28 +02:00
parent 0b4df22f55
commit c4c69143a9
2 changed files with 13 additions and 16 deletions

View File

@ -104,6 +104,8 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
///
/// Returns true if this actually woke up such a thread,
/// or false if no thread was waiting on this futex.
///
/// On some platforms, this always returns false.
#[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
pub fn futex_wake(futex: &AtomicU32) -> bool {
let ptr = futex as *const AtomicU32;
@ -135,9 +137,9 @@ pub fn futex_wake_all(futex: &AtomicU32) {
}
}
// FreeBSD doesn't tell us how many threads are woken up, so this doesn't return a bool.
// FreeBSD doesn't tell us how many threads are woken up, so this always returns false.
#[cfg(target_os = "freebsd")]
pub fn futex_wake(futex: &AtomicU32) {
pub fn futex_wake(futex: &AtomicU32) -> bool {
use crate::ptr::null_mut;
unsafe {
libc::_umtx_op(
@ -148,6 +150,7 @@ pub fn futex_wake(futex: &AtomicU32) {
null_mut(),
)
};
false
}
#[cfg(target_os = "freebsd")]
@ -231,10 +234,11 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
r == 0 || super::os::errno() != libc::ETIMEDOUT
}
// DragonflyBSD doesn't tell us how many threads are woken up, so this doesn't return a bool.
// DragonflyBSD doesn't tell us how many threads are woken up, so this always returns false.
#[cfg(target_os = "dragonfly")]
pub fn futex_wake(futex: &AtomicU32) {
pub fn futex_wake(futex: &AtomicU32) -> bool {
unsafe { libc::umtx_wakeup(futex as *const AtomicU32 as *const i32, 1) };
false
}
#[cfg(target_os = "dragonfly")]

View File

@ -283,18 +283,11 @@ impl RwLock {
/// writer that was about to go to sleep.
fn wake_writer(&self) -> bool {
self.writer_notify.fetch_add(1, Release);
cfg_if::cfg_if! {
if #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] {
// FreeBSD and DragonFlyBSD don't tell us whether they woke up any threads or not.
// So, we always return `false` here, as that still results in correct behaviour.
// The downside is an extra syscall in case both readers and writers were waiting,
// and unnecessarily waking up readers when a writer is about to attempt to lock the lock.
futex_wake(&self.writer_notify);
false
} else {
futex_wake(&self.writer_notify)
}
}
futex_wake(&self.writer_notify)
// Note that FreeBSD and DragonFlyBSD don't tell us whether they woke
// up any threads or not, and always return `false` here. That still
// results in correct behaviour: it just means readers get woken up as
// well in case both readers and writers were waiting.
}
/// Spin for a while, but stop directly at the given condition.