-
Notifications
You must be signed in to change notification settings - Fork 171
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move
futex
to be a top-level module.
With `rustix::thread::futex` being both a deprecated function and a public module, I'm seeing warnings like this when I use it in some simple testcases: ```console warning: use of deprecated function `rustix::thread::futex`: There are now individual functions available to perform futex operations with improved type safety. See the futex module. --> test.rs:2:21 | 2 | use rustix::thread::futex; | ^^^^^ | = note: `#[warn(deprecated)]` on by default ``` I think we can fix this by moving `futex` to be a top-level module, at `rustix::futex`. And this also reflects that, strictly speaking, futexes aren't specific to threads and can be used between processes too. Of course, this leaves the deprecated `rustix::thread::futex` and the associated types and constants in place. Also while using the API, I found `futex::FutexFlags` to be a little redundant, so I think it makes sense to rename it to `futex::Flags`, and similarly rename `futex::FUTEX_WAITERS` to `futex::WAITERS` and so on.
- Loading branch information
1 parent
777fbc6
commit 4f66307
Showing
21 changed files
with
513 additions
and
553 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub(crate) mod syscalls; | ||
pub(crate) mod types; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
use crate::backend::c; | ||
use crate::backend::conv::ret_usize; | ||
use crate::futex; | ||
use crate::io; | ||
use crate::timespec::Timespec; | ||
use core::sync::atomic::AtomicU32; | ||
|
||
pub(crate) unsafe fn futex_val2( | ||
uaddr: *const AtomicU32, | ||
op: super::types::Operation, | ||
flags: futex::Flags, | ||
val: u32, | ||
val2: u32, | ||
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. | ||
let timeout = 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, | ||
timeout, | ||
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, | ||
timeout.cast(), | ||
uaddr2, | ||
val3, | ||
) as isize) | ||
} | ||
} | ||
|
||
pub(crate) unsafe fn futex_timeout( | ||
uaddr: *const AtomicU32, | ||
op: super::types::Operation, | ||
flags: futex::Flags, | ||
val: u32, | ||
timeout: *const Timespec, | ||
uaddr2: *const AtomicU32, | ||
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: *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, | ||
timeout, | ||
uaddr2, | ||
val3, | ||
)) | ||
.or_else(|err| { | ||
// See the comments in `rustix_clock_gettime_via_syscall` about | ||
// emulation. | ||
if err == io::Errno::NOSYS { | ||
futex_old_timespec(uaddr, op, flags, val, timeout, uaddr2, val3) | ||
} else { | ||
Err(err) | ||
} | ||
}) | ||
} | ||
|
||
#[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, | ||
timeout.cast(), | ||
uaddr2, | ||
val3, | ||
) as isize) | ||
} | ||
} | ||
|
||
#[cfg(all( | ||
target_pointer_width = "32", | ||
not(any(target_arch = "aarch64", target_arch = "x86_64")) | ||
))] | ||
unsafe fn futex_old_timespec( | ||
uaddr: *const AtomicU32, | ||
op: super::types::Operation, | ||
flags: futex::Flags, | ||
val: u32, | ||
timeout: *const Timespec, | ||
uaddr2: *const AtomicU32, | ||
val3: u32, | ||
) -> io::Result<usize> { | ||
syscall! { | ||
fn futex( | ||
uaddr: *const AtomicU32, | ||
futex_op: c::c_int, | ||
val: u32, | ||
timeout: *const linux_raw_sys::general::__kernel_old_timespec, | ||
uaddr2: *const AtomicU32, | ||
val3: u32 | ||
) via SYS_futex -> c::c_long | ||
} | ||
|
||
let old_timeout = if timeout.is_null() { | ||
None | ||
} else { | ||
Some(linux_raw_sys::general::__kernel_old_timespec { | ||
tv_sec: (*timeout).tv_sec.try_into().map_err(|_| io::Errno::INVAL)?, | ||
tv_nsec: (*timeout) | ||
.tv_nsec | ||
.try_into() | ||
.map_err(|_| io::Errno::INVAL)?, | ||
}) | ||
}; | ||
ret_usize(futex( | ||
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()), | ||
uaddr2, | ||
val3, | ||
) as isize) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,2 @@ | ||
#[cfg(linux_kernel)] | ||
pub(crate) mod futex; | ||
#[cfg(not(windows))] | ||
pub(crate) mod syscalls; |
Oops, something went wrong.