summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/src/backend/libc/thread
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/rustix/src/backend/libc/thread
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-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.rs43
-rw-r--r--vendor/rustix/src/backend/libc/thread/mod.rs2
-rw-r--r--vendor/rustix/src/backend/libc/thread/syscalls.rs122
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)
+}