Skip to content

Commit

Permalink
Miscellaneous documentation and clippy fixes for futex. (#1134)
Browse files Browse the repository at this point in the history
  • Loading branch information
sunfishcode committed Aug 27, 2024
1 parent d0c4b8f commit e2014c5
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 118 deletions.
30 changes: 23 additions & 7 deletions src/backend/libc/thread/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ use crate::io;
use crate::thread::{NanosleepRelativeResult, Timespec};
#[cfg(all(target_env = "gnu", fix_y2038))]
use crate::timespec::LibcTimespec;
#[cfg(all(
linux_kernel,
target_pointer_width = "32",
not(any(target_arch = "aarch64", target_arch = "x86_64"))
))]
use crate::utils::option_as_ptr;
use core::mem::MaybeUninit;
#[cfg(linux_kernel)]
use core::sync::atomic::AtomicU32;
#[cfg(linux_kernel)]
use {
Expand Down Expand Up @@ -416,6 +423,9 @@ pub(crate) fn setresgid_thread(
unsafe { ret(setresgid(rgid.as_raw(), egid.as_raw(), sgid.as_raw())) }
}

/// # Safety
///
/// The raw pointers must point to valid aligned memory.
#[cfg(linux_kernel)]
pub(crate) unsafe fn futex_val2(
uaddr: *const AtomicU32,
Expand All @@ -426,9 +436,12 @@ pub(crate) unsafe fn futex_val2(
uaddr2: *const AtomicU32,
val3: u32,
) -> io::Result<usize> {
// 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.
// Pass `val2` in the least-significant bytes of the `timeout` argument.
// [“the kernel casts the timeout value first to unsigned long, then to
// uint32_t”], so we perform that exact conversion in reverse to create
// the pointer.
//
// [“the kernel casts the timeout value first to unsigned long, then to uint32_t”]: https://man7.org/linux/man-pages/man2/futex.2.html
let timeout = val2 as usize as *const Timespec;

#[cfg(all(
Expand Down Expand Up @@ -489,6 +502,9 @@ pub(crate) unsafe fn futex_val2(
}
}

/// # Safety
///
/// The raw pointers must point to valid aligned memory.
#[cfg(linux_kernel)]
pub(crate) unsafe fn futex_timeout(
uaddr: *const AtomicU32,
Expand Down Expand Up @@ -566,6 +582,9 @@ pub(crate) unsafe fn futex_timeout(
}
}

/// # Safety
///
/// The raw pointers must point to valid aligned memory.
#[cfg(linux_kernel)]
#[cfg(all(
target_pointer_width = "32",
Expand Down Expand Up @@ -606,10 +625,7 @@ unsafe fn futex_old_timespec(
uaddr,
op as i32 | flags.bits() as i32,
val,
old_timeout
.as_ref()
.map(|timeout| timeout as *const linux_raw_sys::general::__kernel_old_timespec)
.unwrap_or(core::ptr::null()),
option_as_ptr(old_timeout.as_ref()),
uaddr2,
val3,
) as isize)
Expand Down
27 changes: 18 additions & 9 deletions src/backend/linux_raw/thread/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ use crate::pid::Pid;
use crate::thread::{futex, ClockId, NanosleepRelativeResult, Timespec};
use core::mem::MaybeUninit;
use core::sync::atomic::AtomicU32;
#[cfg(target_pointer_width = "32")]
use linux_raw_sys::general::timespec as __kernel_old_timespec;
use linux_raw_sys::general::{__kernel_timespec, TIMER_ABSTIME};
#[cfg(target_pointer_width = "32")]
use {crate::utils::option_as_ptr, linux_raw_sys::general::timespec as __kernel_old_timespec};

#[inline]
pub(crate) fn clock_nanosleep_relative(
Expand Down Expand Up @@ -204,6 +204,9 @@ pub(crate) fn gettid() -> Pid {
}
}

/// # Safety
///
/// The raw pointers must point to valid aligned memory.
#[inline]
pub(crate) unsafe fn futex_val2(
uaddr: *const AtomicU32,
Expand All @@ -214,9 +217,12 @@ pub(crate) unsafe fn futex_val2(
uaddr2: *const AtomicU32,
val3: u32,
) -> io::Result<usize> {
// 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.
// Pass `val2` in the least-significant bytes of the `timeout` argument.
// [“the kernel casts the timeout value first to unsigned long, then to
// uint32_t”], so we perform that exact conversion in reverse to create
// the pointer.
//
// [“the kernel casts the timeout value first to unsigned long, then to uint32_t”]: https://man7.org/linux/man-pages/man2/futex.2.html
let timeout = val2 as usize as *const Timespec;

#[cfg(target_pointer_width = "32")]
Expand All @@ -243,6 +249,9 @@ pub(crate) unsafe fn futex_val2(
))
}

/// # Safety
///
/// The raw pointers must point to valid aligned memory.
#[inline]
pub(crate) unsafe fn futex_timeout(
uaddr: *const AtomicU32,
Expand Down Expand Up @@ -286,6 +295,9 @@ pub(crate) unsafe fn futex_timeout(
))
}

/// # Safety
///
/// The raw pointers must point to valid aligned memory.
#[cfg(target_pointer_width = "32")]
unsafe fn futex_old_timespec(
uaddr: *const AtomicU32,
Expand All @@ -312,10 +324,7 @@ unsafe fn futex_old_timespec(
uaddr,
(op, flags),
c_uint(val),
old_timeout
.as_ref()
.map(|timeout| timeout as *const __kernel_old_timespec)
.unwrap_or(core::ptr::null()),
option_as_ptr(old_timeout.as_ref()),
uaddr2,
c_uint(val3)
))
Expand Down
Loading

0 comments on commit e2014c5

Please sign in to comment.