diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:44 +0000 |
commit | c23a457e72abe608715ac76f076f47dc42af07a5 (patch) | |
tree | 2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/rustix/src/backend/libc/thread | |
parent | Releasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/rustix/src/backend/libc/thread')
-rw-r--r-- | vendor/rustix/src/backend/libc/thread/futex.rs | 43 | ||||
-rw-r--r-- | vendor/rustix/src/backend/libc/thread/mod.rs | 2 | ||||
-rw-r--r-- | vendor/rustix/src/backend/libc/thread/syscalls.rs | 122 |
3 files changed, 165 insertions, 2 deletions
diff --git a/vendor/rustix/src/backend/libc/thread/futex.rs b/vendor/rustix/src/backend/libc/thread/futex.rs new file mode 100644 index 000000000..44d96f0f6 --- /dev/null +++ b/vendor/rustix/src/backend/libc/thread/futex.rs @@ -0,0 +1,43 @@ +use crate::backend::c; + +bitflags::bitflags! { + /// `FUTEX_*` flags for use with [`futex`]. + /// + /// [`futex`]: crate::thread::futex + #[repr(transparent)] + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] + pub struct FutexFlags: u32 { + /// `FUTEX_PRIVATE_FLAG` + const PRIVATE = bitcast!(c::FUTEX_PRIVATE_FLAG); + /// `FUTEX_CLOCK_REALTIME` + const CLOCK_REALTIME = bitcast!(c::FUTEX_CLOCK_REALTIME); + } +} + +/// `FUTEX_*` operations for use with [`futex`]. +/// +/// [`futex`]: crate::thread::futex +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +#[repr(u32)] +pub enum FutexOperation { + /// `FUTEX_WAIT` + Wait = bitcast!(c::FUTEX_WAIT), + /// `FUTEX_WAKE` + Wake = bitcast!(c::FUTEX_WAKE), + /// `FUTEX_FD` + Fd = bitcast!(c::FUTEX_FD), + /// `FUTEX_REQUEUE` + Requeue = bitcast!(c::FUTEX_REQUEUE), + /// `FUTEX_CMP_REQUEUE` + CmpRequeue = bitcast!(c::FUTEX_CMP_REQUEUE), + /// `FUTEX_WAKE_OP` + WakeOp = bitcast!(c::FUTEX_WAKE_OP), + /// `FUTEX_LOCK_PI` + LockPi = bitcast!(c::FUTEX_LOCK_PI), + /// `FUTEX_UNLOCK_PI` + UnlockPi = bitcast!(c::FUTEX_UNLOCK_PI), + /// `FUTEX_TRYLOCK_PI` + TrylockPi = bitcast!(c::FUTEX_TRYLOCK_PI), + /// `FUTEX_WAIT_BITSET` + WaitBitset = bitcast!(c::FUTEX_WAIT_BITSET), +} diff --git a/vendor/rustix/src/backend/libc/thread/mod.rs b/vendor/rustix/src/backend/libc/thread/mod.rs index 40e0d1135..4f8c87cd2 100644 --- a/vendor/rustix/src/backend/libc/thread/mod.rs +++ b/vendor/rustix/src/backend/libc/thread/mod.rs @@ -1,2 +1,4 @@ +#[cfg(linux_kernel)] +pub(crate) mod futex; #[cfg(not(windows))] pub(crate) mod syscalls; diff --git a/vendor/rustix/src/backend/libc/thread/syscalls.rs b/vendor/rustix/src/backend/libc/thread/syscalls.rs index 5260c39f4..846f0e2a8 100644 --- a/vendor/rustix/src/backend/libc/thread/syscalls.rs +++ b/vendor/rustix/src/backend/libc/thread/syscalls.rs @@ -10,9 +10,10 @@ use crate::timespec::LibcTimespec; use core::mem::MaybeUninit; #[cfg(linux_kernel)] use { - crate::backend::conv::{borrowed_fd, ret_c_int}, + crate::backend::conv::{borrowed_fd, ret_c_int, ret_usize}, crate::fd::BorrowedFd, crate::pid::Pid, + crate::thread::{FutexFlags, FutexOperation}, crate::utils::as_mut_ptr, }; #[cfg(not(any( @@ -279,7 +280,7 @@ pub(crate) fn gettid() -> Pid { #[cfg(linux_kernel)] #[inline] -pub(crate) fn setns(fd: BorrowedFd, nstype: c::c_int) -> io::Result<c::c_int> { +pub(crate) fn setns(fd: BorrowedFd<'_>, nstype: c::c_int) -> io::Result<c::c_int> { // `setns` wasn't supported in glibc until 2.14, and musl until 0.9.5, // so use `syscall`. weak_or_syscall! { @@ -390,3 +391,120 @@ 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( + uaddr: *mut u32, + op: FutexOperation, + flags: FutexFlags, + val: u32, + utime: *const Timespec, + uaddr2: *mut u32, + val3: u32, +) -> io::Result<usize> { + #[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: *mut u32, + futex_op: c::c_int, + val: u32, + timeout: *const Timespec, + uaddr2: *mut u32, + 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, + )) + .or_else(|err| { + // 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) + } else { + Err(err) + } + }) + } + + #[cfg(any( + target_pointer_width = "64", + target_arch = "aarch64", + target_arch = "x86_64" + ))] + { + syscall! { + fn futex( + uaddr: *mut u32, + futex_op: c::c_int, + val: u32, + timeout: *const linux_raw_sys::general::__kernel_timespec, + uaddr2: *mut u32, + 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)] +#[cfg(all( + target_pointer_width = "32", + not(any(target_arch = "aarch64", target_arch = "x86_64")) +))] +unsafe fn futex_old( + uaddr: *mut u32, + op: FutexOperation, + flags: FutexFlags, + val: u32, + utime: *const Timespec, + uaddr2: *mut u32, + val3: u32, +) -> io::Result<usize> { + syscall! { + fn futex( + uaddr: *mut u32, + futex_op: c::c_int, + val: u32, + timeout: *const linux_raw_sys::general::__kernel_old_timespec, + uaddr2: *mut u32, + val3: u32 + ) 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)?, + }; + ret_usize(futex( + uaddr, + op as i32 | flags.bits() as i32, + val, + &old_utime, + uaddr2, + val3, + ) as isize) +} |