From 6012fade54a1ceb6be9bc22567cebe41039fc093 Mon Sep 17 00:00:00 2001 From: Daniel Schemmel Date: Sat, 27 Jul 2024 20:19:53 +0100 Subject: [PATCH] futex: split backend into val2 and timespec versions, reorganize new functions --- src/backend/libc/thread/futex.rs | 4 +- src/backend/libc/thread/syscalls.rs | 95 ++++++++++-- src/backend/linux_raw/thread/futex.rs | 4 +- src/backend/linux_raw/thread/syscalls.rs | 61 ++++++-- src/thread/futex.rs | 176 +++++++++++++---------- src/thread/mod.rs | 10 +- 6 files changed, 246 insertions(+), 104 deletions(-) diff --git a/src/backend/libc/thread/futex.rs b/src/backend/libc/thread/futex.rs index 5083dae94..078e608fa 100644 --- a/src/backend/libc/thread/futex.rs +++ b/src/backend/libc/thread/futex.rs @@ -3,7 +3,7 @@ use crate::backend::c; bitflags::bitflags! { /// `FUTEX_*` flags for use with [`futex`]. /// - /// [`futex`]: crate::thread::futex + /// [`futex`]: mod@crate::thread::futex #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct FutexFlags: u32 { @@ -16,7 +16,7 @@ bitflags::bitflags! { /// `FUTEX_*` operations for use with [`futex`]. /// -/// [`futex`]: crate::thread::futex +/// [`futex`]: mod@crate::thread::futex #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[repr(u32)] pub enum FutexOperation { diff --git a/src/backend/libc/thread/syscalls.rs b/src/backend/libc/thread/syscalls.rs index 34c44da47..33a14dc0d 100644 --- a/src/backend/libc/thread/syscalls.rs +++ b/src/backend/libc/thread/syscalls.rs @@ -417,9 +417,81 @@ pub(crate) fn setresgid_thread( unsafe { ret(setresgid(rgid.as_raw(), egid.as_raw(), sgid.as_raw())) } } -// TODO: This could be de-multiplexed. #[cfg(linux_kernel)] -pub(crate) unsafe fn futex( +pub(crate) unsafe fn futex_val2( + uaddr: *const AtomicU32, + op: FutexOperation, + flags: FutexFlags, + val: u32, + val2: u32, + uaddr2: *const AtomicU32, + val3: u32, +) -> io::Result { + // the least significant four bytes of the timeout pointer are used as `val2`. + // ["the kernel casts the timeout value first to unsigned long, then to uint32_t"](https://man7.org/linux/man-pages/man2/futex.2.html), + // so we perform that exact conversion in reverse to create the pointer. + let utime = val2 as usize as *const Timespec; + + #[cfg(all( + target_pointer_width = "32", + not(any(target_arch = "aarch64", target_arch = "x86_64")) + ))] + { + // TODO: Upstream this to the libc crate. + #[allow(non_upper_case_globals)] + const SYS_futex_time64: i32 = linux_raw_sys::general::__NR_futex_time64 as i32; + + syscall! { + fn futex_time64( + uaddr: *const AtomicU32, + futex_op: c::c_int, + val: u32, + timeout: *const Timespec, + uaddr2: *const AtomicU32, + val3: u32 + ) via SYS_futex_time64 -> c::ssize_t + } + + ret_usize(futex_time64( + uaddr, + op as i32 | flags.bits() as i32, + val, + utime, + uaddr2, + val3, + )) + } + + #[cfg(any( + target_pointer_width = "64", + target_arch = "aarch64", + target_arch = "x86_64" + ))] + { + syscall! { + fn futex( + uaddr: *const AtomicU32, + futex_op: c::c_int, + val: u32, + timeout: *const linux_raw_sys::general::__kernel_timespec, + uaddr2: *const AtomicU32, + val3: u32 + ) via SYS_futex -> c::c_long + } + + ret_usize(futex( + uaddr, + op as i32 | flags.bits() as i32, + val, + utime.cast(), + uaddr2, + val3, + ) as isize) + } +} + +#[cfg(linux_kernel)] +pub(crate) unsafe fn futex_timespec( uaddr: *const AtomicU32, op: FutexOperation, flags: FutexFlags, @@ -460,7 +532,7 @@ pub(crate) unsafe fn futex( // See the comments in `rustix_clock_gettime_via_syscall` about // emulation. if err == io::Errno::NOSYS { - futex_old(uaddr, op, flags, val, utime, uaddr2, val3) + futex_old_timespec(uaddr, op, flags, val, utime, uaddr2, val3) } else { Err(err) } @@ -500,7 +572,7 @@ pub(crate) unsafe fn futex( target_pointer_width = "32", not(any(target_arch = "aarch64", target_arch = "x86_64")) ))] -unsafe fn futex_old( +unsafe fn futex_old_timespec( uaddr: *const AtomicU32, op: FutexOperation, flags: FutexFlags, @@ -520,15 +592,22 @@ unsafe fn futex_old( ) via SYS_futex -> c::c_long } - let old_utime = linux_raw_sys::general::__kernel_old_timespec { - tv_sec: (*utime).tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, - tv_nsec: (*utime).tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, + let old_utime = if utime.is_null() { + None + } else { + Some(linux_raw_sys::general::__kernel_old_timespec { + tv_sec: (*utime).tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, + tv_nsec: (*utime).tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, + }) }; ret_usize(futex( uaddr, op as i32 | flags.bits() as i32, val, - &old_utime, + old_utime + .as_ref() + .map(|r| r as *const linux_raw_sys::general::__kernel_old_timespec) + .unwrap_or(core::ptr::null()), uaddr2, val3, ) as isize) diff --git a/src/backend/linux_raw/thread/futex.rs b/src/backend/linux_raw/thread/futex.rs index 9da7bd02e..ed1a34a7e 100644 --- a/src/backend/linux_raw/thread/futex.rs +++ b/src/backend/linux_raw/thread/futex.rs @@ -1,7 +1,7 @@ bitflags::bitflags! { /// `FUTEX_*` flags for use with [`futex`]. /// - /// [`futex`]: crate::thread::futex + /// [`futex`]: mod@crate::thread::futex #[repr(transparent)] #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] pub struct FutexFlags: u32 { @@ -18,7 +18,7 @@ bitflags::bitflags! { /// `FUTEX_*` operations for use with [`futex`]. /// -/// [`futex`]: crate::thread::futex +/// [`futex`]: mod@crate::thread::futex #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[repr(u32)] pub enum FutexOperation { diff --git a/src/backend/linux_raw/thread/syscalls.rs b/src/backend/linux_raw/thread/syscalls.rs index fbfb83c34..ffabb5cb6 100644 --- a/src/backend/linux_raw/thread/syscalls.rs +++ b/src/backend/linux_raw/thread/syscalls.rs @@ -205,9 +205,47 @@ pub(crate) fn gettid() -> Pid { } } -// TODO: This could be de-multiplexed. #[inline] -pub(crate) unsafe fn futex( +pub(crate) unsafe fn futex_val2( + uaddr: *const AtomicU32, + op: FutexOperation, + flags: FutexFlags, + val: u32, + val2: u32, + uaddr2: *const AtomicU32, + val3: u32, +) -> io::Result { + // the least significant four bytes of the timeout pointer are used as `val2`. + // ["the kernel casts the timeout value first to unsigned long, then to uint32_t"](https://man7.org/linux/man-pages/man2/futex.2.html), + // so we perform that exact conversion in reverse to create the pointer. + let utime = val2 as usize as *const Timespec; + + #[cfg(target_pointer_width = "32")] + { + ret_usize(syscall!( + __NR_futex_time64, + uaddr, + (op, flags), + c_uint(val), + utime, + uaddr2, + c_uint(val3) + )) + } + #[cfg(target_pointer_width = "64")] + ret_usize(syscall!( + __NR_futex, + uaddr, + (op, flags), + c_uint(val), + utime, + uaddr2, + c_uint(val3) + )) +} + +#[inline] +pub(crate) unsafe fn futex_timespec( uaddr: *const AtomicU32, op: FutexOperation, flags: FutexFlags, @@ -231,7 +269,7 @@ pub(crate) unsafe fn futex( // See the comments in `rustix_clock_gettime_via_syscall` about // emulation. if err == io::Errno::NOSYS { - futex_old(uaddr, op, flags, val, utime, uaddr2, val3) + futex_old_timespec(uaddr, op, flags, val, utime, uaddr2, val3) } else { Err(err) } @@ -250,7 +288,7 @@ pub(crate) unsafe fn futex( } #[cfg(target_pointer_width = "32")] -unsafe fn futex_old( +unsafe fn futex_old_timespec( uaddr: *const AtomicU32, op: FutexOperation, flags: FutexFlags, @@ -259,16 +297,23 @@ unsafe fn futex_old( uaddr2: *const AtomicU32, val3: u32, ) -> io::Result { - let old_utime = __kernel_old_timespec { - tv_sec: (*utime).tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, - tv_nsec: (*utime).tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, + let old_utime = if utime.is_null() { + None + } else { + Some(__kernel_old_timespec { + tv_sec: (*utime).tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, + tv_nsec: (*utime).tv_nsec.try_into().map_err(|_| io::Errno::INVAL)?, + }) }; ret_usize(syscall!( __NR_futex, uaddr, (op, flags), c_uint(val), - by_ref(&old_utime), + old_utime + .as_ref() + .map(|r| r as *const __kernel_old_timespec) + .unwrap_or(core::ptr::null()), uaddr2, c_uint(val3) )) diff --git a/src/thread/futex.rs b/src/thread/futex.rs index 3d8715426..6b0a9f68d 100644 --- a/src/thread/futex.rs +++ b/src/thread/futex.rs @@ -10,18 +10,73 @@ use core::num::NonZeroU32; use core::ptr; use core::sync::atomic::AtomicU32; +use crate::backend::thread::syscalls::{futex_timespec, futex_val2}; use crate::fd::{FromRawFd, OwnedFd}; use crate::thread::Timespec; use crate::{backend, io}; pub use backend::thread::futex::FutexFlags; -use backend::thread::futex::FutexOperation; +pub use backend::thread::futex::FutexOperation; /// `FUTEX_WAITERS` pub const FUTEX_WAITERS: u32 = backend::thread::futex::FUTEX_WAITERS; /// `FUTEX_OWNER_DIED` pub const FUTEX_OWNER_DIED: u32 = backend::thread::futex::FUTEX_OWNER_DIED; +/// DEPRECATED: There are now individual functions available to perform futex operations with improved type safety. See the [futex module](`self`). +/// +/// `futex(uaddr, op, val, utime, uaddr2, val3)` +/// +/// # References +/// - [Linux `futex` system call] +/// - [Linux `futex` feature] +/// +/// # Safety +/// +/// This is a very low-level feature for implementing synchronization +/// primitives. See the references links above. +/// +/// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html +/// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html +#[deprecated( + since = "0.38.35", + note = "There are now individual functions available to perform futex operations with improved type safety. See the futex module." +)] +#[inline] +pub unsafe fn futex( + uaddr: *mut u32, + op: FutexOperation, + flags: FutexFlags, + val: u32, + utime: *const Timespec, + uaddr2: *mut u32, + val3: u32, +) -> io::Result { + use FutexOperation::*; + + match op { + Wait | LockPi | WaitBitset | WaitRequeuePi | LockPi2 => futex_timespec( + uaddr as *const AtomicU32, + op, + flags, + val, + utime, + uaddr2 as *const AtomicU32, + val3, + ), + Wake | Fd | Requeue | CmpRequeue | WakeOp | UnlockPi | TrylockPi | WakeBitset + | CmpRequeuePi => futex_val2( + uaddr as *const AtomicU32, + op, + flags, + val, + utime as usize as u32, + uaddr2 as *const AtomicU32, + val3, + ), + } +} + /// Equivalent to `syscall(SYS_futex, uaddr, FUTEX_WAIT, val, timeout, NULL, 0)` /// /// # References @@ -36,13 +91,13 @@ pub const FUTEX_OWNER_DIED: u32 = backend::thread::futex::FUTEX_OWNER_DIED; /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_wait( +pub unsafe fn wait( uaddr: &AtomicU32, flags: FutexFlags, val: u32, timeout: Option, ) -> io::Result<()> { - backend::thread::syscalls::futex( + backend::thread::syscalls::futex_timespec( uaddr, FutexOperation::Wait, flags, @@ -70,13 +125,13 @@ pub unsafe fn futex_wait( /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_wake(uaddr: &AtomicU32, flags: FutexFlags, val: u32) -> io::Result { - backend::thread::syscalls::futex( +pub unsafe fn wake(uaddr: &AtomicU32, flags: FutexFlags, val: u32) -> io::Result { + backend::thread::syscalls::futex_val2( uaddr, FutexOperation::Wake, flags, val, - ptr::null(), + 0, ptr::null(), 0, ) @@ -96,17 +151,9 @@ pub unsafe fn futex_wake(uaddr: &AtomicU32, flags: FutexFlags, val: u32) -> io:: /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_fd(uaddr: &AtomicU32, flags: FutexFlags, val: u32) -> io::Result { - backend::thread::syscalls::futex( - uaddr, - FutexOperation::Fd, - flags, - val, - ptr::null(), - ptr::null(), - 0, - ) - .map(|fd| OwnedFd::from_raw_fd(fd.try_into().expect("return value should be a valid fd"))) +pub unsafe fn fd(uaddr: &AtomicU32, flags: FutexFlags, val: u32) -> io::Result { + backend::thread::syscalls::futex_val2(uaddr, FutexOperation::Fd, flags, val, 0, ptr::null(), 0) + .map(|fd| OwnedFd::from_raw_fd(fd.try_into().expect("return value should be a valid fd"))) } /// Equivalent to `syscall(SYS_futex, uaddr, FUTEX_REQUEUE, val, val2, uaddr2, 0)` @@ -123,23 +170,19 @@ pub unsafe fn futex_fd(uaddr: &AtomicU32, flags: FutexFlags, val: u32) -> io::Re /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_requeue( +pub unsafe fn requeue( uaddr: &AtomicU32, flags: FutexFlags, val: u32, val2: u32, uaddr2: &AtomicU32, ) -> io::Result { - // the least significant four bytes of the timeout pointer are used as `val2`. - // ["the kernel casts the timeout value first to unsigned long, then to uint32_t"](https://man7.org/linux/man-pages/man2/futex.2.html), - // so we perform that exact conversion in reverse to create the pointer. - let timeout = val2 as usize as *const Timespec; - backend::thread::syscalls::futex( + backend::thread::syscalls::futex_val2( uaddr, FutexOperation::Requeue, flags, val, - timeout, + val2, uaddr2, 0, ) @@ -159,7 +202,7 @@ pub unsafe fn futex_requeue( /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_cmp_requeue( +pub unsafe fn cmp_requeue( uaddr: &AtomicU32, flags: FutexFlags, val: u32, @@ -167,27 +210,21 @@ pub unsafe fn futex_cmp_requeue( uaddr2: &AtomicU32, val3: u32, ) -> io::Result { - // the least significant four bytes of the timeout pointer are used as `val2`. - // ["the kernel casts the timeout value first to unsigned long, then to uint32_t"](https://man7.org/linux/man-pages/man2/futex.2.html), - // so we perform that exact conversion in reverse to create the pointer. - let timeout = val2 as usize as *const Timespec; - backend::thread::syscalls::futex( + backend::thread::syscalls::futex_val2( uaddr, FutexOperation::CmpRequeue, flags, val, - timeout, + val2, uaddr2, val3, ) } -/// `FUTEX_OP_*` operations for use with [`futex_wake_op`]. -/// -/// [`futex`]: crate::thread::futex +/// `FUTEX_OP_*` operations for use with [`wake_op`]. #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[repr(u32)] -pub enum FutexOp { +pub enum WakeOp { /// `FUTEX_OP_SET`: `uaddr2 = oparg;` Set = 0, /// `FUTEX_OP_ADD`: `uaddr2 += oparg;` @@ -210,12 +247,10 @@ pub enum FutexOp { XOrShift = 4 | 8, } -/// `FUTEX_OP_CMP_*` operations for use with [`futex_wake_op`]. -/// -/// [`futex`]: crate::thread::futex +/// `FUTEX_OP_CMP_*` operations for use with [`wake_op`]. #[derive(Debug, Copy, Clone, Eq, PartialEq)] #[repr(u32)] -pub enum FutexOpCmp { +pub enum WakeOpCmp { /// `FUTEX_OP_CMP_EQ`: `if oldval == cmparg { wake(); }` Eq = 0, /// `FUTEX_OP_CMP_EQ`: `if oldval != cmparg { wake(); }` @@ -244,14 +279,14 @@ pub enum FutexOpCmp { /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_wake_op( +pub unsafe fn wake_op( uaddr: &AtomicU32, flags: FutexFlags, val: u32, val2: u32, uaddr2: &AtomicU32, - op: FutexOp, - cmp: FutexOpCmp, + op: WakeOp, + cmp: WakeOpCmp, oparg: u16, cmparg: u16, ) -> io::Result { @@ -259,20 +294,15 @@ pub unsafe fn futex_wake_op( return Err(io::Errno::INVAL); } - // the least significant four bytes of the timeout pointer are used as `val2`. - // ["the kernel casts the timeout value first to unsigned long, then to uint32_t"](https://man7.org/linux/man-pages/man2/futex.2.html), - // so we perform that exact conversion in reverse to create the pointer. - let timeout = val2 as usize as *const Timespec; - let val3 = ((op as u32) << 28) | ((cmp as u32) << 24) | ((oparg as u32) << 12) | (cmparg as u32); - backend::thread::syscalls::futex( + backend::thread::syscalls::futex_val2( uaddr, FutexOperation::WakeOp, flags, val, - timeout, + val2, uaddr2, val3, ) @@ -292,12 +322,12 @@ pub unsafe fn futex_wake_op( /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_lock_pi( +pub unsafe fn lock_pi( uaddr: &AtomicU32, flags: FutexFlags, timeout: Option, ) -> io::Result<()> { - backend::thread::syscalls::futex( + backend::thread::syscalls::futex_timespec( uaddr, FutexOperation::LockPi, flags, @@ -325,13 +355,13 @@ pub unsafe fn futex_lock_pi( /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_unlock_pi(uaddr: &AtomicU32, flags: FutexFlags) -> io::Result<()> { - backend::thread::syscalls::futex( +pub unsafe fn unlock_pi(uaddr: &AtomicU32, flags: FutexFlags) -> io::Result<()> { + backend::thread::syscalls::futex_val2( uaddr, FutexOperation::UnlockPi, flags, 0, - ptr::null(), + 0, ptr::null(), 0, )?; @@ -352,13 +382,13 @@ pub unsafe fn futex_unlock_pi(uaddr: &AtomicU32, flags: FutexFlags) -> io::Resul /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_trylock_pi(uaddr: &AtomicU32, flags: FutexFlags) -> io::Result<()> { - backend::thread::syscalls::futex( +pub unsafe fn trylock_pi(uaddr: &AtomicU32, flags: FutexFlags) -> io::Result<()> { + backend::thread::syscalls::futex_val2( uaddr, FutexOperation::TrylockPi, flags, 0, - ptr::null(), + 0, ptr::null(), 0, )?; @@ -379,14 +409,14 @@ pub unsafe fn futex_trylock_pi(uaddr: &AtomicU32, flags: FutexFlags) -> io::Resu /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_wait_bitset( +pub unsafe fn wait_bitset( uaddr: &AtomicU32, flags: FutexFlags, val: u32, timeout: Option, val3: NonZeroU32, ) -> io::Result<()> { - backend::thread::syscalls::futex( + backend::thread::syscalls::futex_timespec( uaddr, FutexOperation::WaitBitset, flags, @@ -414,18 +444,18 @@ pub unsafe fn futex_wait_bitset( /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_wake_bitset( +pub unsafe fn wake_bitset( uaddr: &AtomicU32, flags: FutexFlags, val: u32, val3: NonZeroU32, ) -> io::Result { - backend::thread::syscalls::futex( + backend::thread::syscalls::futex_val2( uaddr, FutexOperation::WakeBitset, flags, val, - ptr::null(), + 0, ptr::null(), val3.get(), ) @@ -445,14 +475,14 @@ pub unsafe fn futex_wake_bitset( /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_wait_requeue_pi( +pub unsafe fn wait_requeue_pi( uaddr: &AtomicU32, flags: FutexFlags, val: u32, timeout: Option, uaddr2: &AtomicU32, ) -> io::Result<()> { - backend::thread::syscalls::futex( + backend::thread::syscalls::futex_timespec( uaddr, FutexOperation::WaitRequeuePi, flags, @@ -480,23 +510,19 @@ pub unsafe fn futex_wait_requeue_pi( /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_cmp_requeue_pi( +pub unsafe fn cmp_requeue_pi( uaddr: &AtomicU32, flags: FutexFlags, val2: u32, uaddr2: &AtomicU32, val3: u32, ) -> io::Result { - // the least significant four bytes of the timeout pointer are used as `val2`. - // ["the kernel casts the timeout value first to unsigned long, then to uint32_t"](https://man7.org/linux/man-pages/man2/futex.2.html), - // so we perform that exact conversion in reverse to create the pointer. - let timeout = val2 as usize as *const Timespec; - backend::thread::syscalls::futex( + backend::thread::syscalls::futex_val2( uaddr, FutexOperation::CmpRequeuePi, flags, 1, - timeout, + val2, uaddr2, val3, ) @@ -516,12 +542,8 @@ pub unsafe fn futex_cmp_requeue_pi( /// [Linux `futex` system call]: https://man7.org/linux/man-pages/man2/futex.2.html /// [Linux `futex` feature]: https://man7.org/linux/man-pages/man7/futex.7.html #[inline] -pub unsafe fn futex_lock_pi2( - uaddr: &AtomicU32, - flags: FutexFlags, - timeout: &Timespec, -) -> io::Result<()> { - backend::thread::syscalls::futex( +pub unsafe fn lock_pi2(uaddr: &AtomicU32, flags: FutexFlags, timeout: &Timespec) -> io::Result<()> { + backend::thread::syscalls::futex_timespec( uaddr, FutexOperation::LockPi2, flags, diff --git a/src/thread/mod.rs b/src/thread/mod.rs index d717c99b0..cb5d566f3 100644 --- a/src/thread/mod.rs +++ b/src/thread/mod.rs @@ -3,7 +3,7 @@ #[cfg(not(target_os = "redox"))] mod clock; #[cfg(linux_kernel)] -mod futex; +pub mod futex; #[cfg(linux_kernel)] mod id; #[cfg(linux_kernel)] @@ -16,12 +16,8 @@ mod setns; #[cfg(not(target_os = "redox"))] pub use clock::*; #[cfg(linux_kernel)] -pub use futex::{ - futex_cmp_requeue, futex_cmp_requeue_pi, futex_fd, futex_lock_pi, futex_lock_pi2, - futex_requeue, futex_trylock_pi, futex_unlock_pi, futex_wait, futex_wait_bitset, - futex_wait_requeue_pi, futex_wake, futex_wake_bitset, futex_wake_op, FutexFlags, - FUTEX_OWNER_DIED, FUTEX_WAITERS, -}; +#[allow(deprecated)] +pub use futex::{futex, FutexFlags, FutexOperation, FUTEX_OWNER_DIED, FUTEX_WAITERS}; #[cfg(linux_kernel)] pub use id::{ gettid, set_thread_gid, set_thread_groups, set_thread_res_gid, set_thread_res_uid,