From 2cf0f64722a92dffa12d43a4c0383a9d76becbcc Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 19 Sep 2020 18:03:10 +0200 Subject: Move linux-specific futex code into `sys` module. --- library/std/src/sys/unix/futex.rs | 38 ++++++++++++++++++++++++++++++++++++++ library/std/src/sys/unix/mod.rs | 1 + 2 files changed, 39 insertions(+) create mode 100644 library/std/src/sys/unix/futex.rs (limited to 'library/std/src/sys') diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs new file mode 100644 index 00000000000..6af06aa5f7e --- /dev/null +++ b/library/std/src/sys/unix/futex.rs @@ -0,0 +1,38 @@ +#![cfg(any(target_os = "linux", target_os = "android"))] + +use crate::sync::atomic::AtomicI32; +use crate::time::Duration; + +pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option) { + let timespec; + let timespec_ptr = match timeout { + Some(timeout) => { + timespec = libc::timespec { + tv_sec: timeout.as_secs() as _, + tv_nsec: timeout.subsec_nanos() as _, + }; + ×pec as *const libc::timespec + } + None => crate::ptr::null(), + }; + unsafe { + libc::syscall( + libc::SYS_futex, + futex as *const AtomicI32, + libc::FUTEX_WAIT | libc::FUTEX_PRIVATE_FLAG, + expected, + timespec_ptr, + ); + } +} + +pub fn futex_wake(futex: &AtomicI32) { + unsafe { + libc::syscall( + libc::SYS_futex, + futex as *const AtomicI32, + libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG, + 1, + ); + } +} diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs index eddf00d3979..6c623e21099 100644 --- a/library/std/src/sys/unix/mod.rs +++ b/library/std/src/sys/unix/mod.rs @@ -49,6 +49,7 @@ pub mod env; pub mod ext; pub mod fd; pub mod fs; +pub mod futex; pub mod io; #[cfg(target_os = "l4re")] mod l4re; -- cgit 1.4.1-3-g733a5 From 485f882d7713b0e0b864fc8b21368910e5b8b0a7 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sun, 20 Sep 2020 00:17:05 +0200 Subject: Check conversion from Duration to timespec in futex_wait. --- library/std/src/sys/unix/futex.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'library/std/src/sys') diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs index 6af06aa5f7e..e6f0c48c59b 100644 --- a/library/std/src/sys/unix/futex.rs +++ b/library/std/src/sys/unix/futex.rs @@ -1,27 +1,26 @@ #![cfg(any(target_os = "linux", target_os = "android"))] +use crate::convert::TryInto; +use crate::ptr::null; use crate::sync::atomic::AtomicI32; use crate::time::Duration; pub fn futex_wait(futex: &AtomicI32, expected: i32, timeout: Option) { - let timespec; - let timespec_ptr = match timeout { - Some(timeout) => { - timespec = libc::timespec { - tv_sec: timeout.as_secs() as _, - tv_nsec: timeout.subsec_nanos() as _, - }; - ×pec as *const libc::timespec - } - None => crate::ptr::null(), - }; + let timespec = timeout.and_then(|d| { + Some(libc::timespec { + // Sleep forever if the timeout is longer than fits in a timespec. + tv_sec: d.as_secs().try_into().ok()?, + // This conversion never truncates, as subsec_nanos is always <1e9. + tv_nsec: d.subsec_nanos() as _, + }) + }); unsafe { libc::syscall( libc::SYS_futex, futex as *const AtomicI32, libc::FUTEX_WAIT | libc::FUTEX_PRIVATE_FLAG, expected, - timespec_ptr, + timespec.as_ref().map_or(null(), |d| d as *const libc::timespec), ); } } -- cgit 1.4.1-3-g733a5