From ea12b81b1a5e7099161b1607283c3f1516443b66 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Jan 2025 08:38:29 -0800 Subject: [PATCH 1/4] Move `sched_*` and `membarrier_*` into `rustix::thread`. These functions and their associated types operate on threads, rather than processes. --- src/backend/libc/process/mod.rs | 2 - src/backend/libc/process/syscalls.rs | 96 --------------- src/backend/libc/process/types.rs | 53 -------- .../libc/{process => thread}/cpu_set.rs | 0 src/backend/libc/thread/mod.rs | 3 + src/backend/libc/thread/syscalls.rs | 96 ++++++++++++++- src/backend/libc/thread/types.rs | 59 +++++++++ src/backend/linux_raw/conv.rs | 12 +- src/backend/linux_raw/process/mod.rs | 1 - src/backend/linux_raw/process/syscalls.rs | 114 +----------------- src/backend/linux_raw/process/types.rs | 62 ---------- .../linux_raw/{process => thread}/cpu_set.rs | 0 src/backend/linux_raw/thread/mod.rs | 2 + src/backend/linux_raw/thread/syscalls.rs | 111 ++++++++++++++++- src/backend/linux_raw/thread/types.rs | 61 ++++++++++ src/process/id.rs | 27 ----- src/process/mod.rs | 10 -- src/thread/id.rs | 35 ++++++ src/{process => thread}/membarrier.rs | 10 +- src/thread/mod.rs | 15 ++- src/{process => thread}/sched.rs | 30 ++--- src/{process => thread}/sched_yield.rs | 2 +- tests/process/main.rs | 4 - tests/{process => thread}/cpu_set.rs | 4 +- tests/thread/main.rs | 4 + tests/{process => thread}/membarrier.rs | 2 +- tests/{process => thread}/sched.rs | 6 +- 27 files changed, 415 insertions(+), 406 deletions(-) rename src/backend/libc/{process => thread}/cpu_set.rs (100%) create mode 100644 src/backend/libc/thread/types.rs rename src/backend/linux_raw/{process => thread}/cpu_set.rs (100%) create mode 100644 src/backend/linux_raw/thread/types.rs rename src/{process => thread}/membarrier.rs (93%) rename src/{process => thread}/sched.rs (78%) rename src/{process => thread}/sched_yield.rs (89%) rename tests/{process => thread}/cpu_set.rs (60%) rename tests/{process => thread}/membarrier.rs (91%) rename tests/{process => thread}/sched.rs (57%) diff --git a/src/backend/libc/process/mod.rs b/src/backend/libc/process/mod.rs index 39803b521..a937d7f86 100644 --- a/src/backend/libc/process/mod.rs +++ b/src/backend/libc/process/mod.rs @@ -1,5 +1,3 @@ -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -pub(crate) mod cpu_set; #[cfg(not(windows))] pub(crate) mod syscalls; pub(crate) mod types; diff --git a/src/backend/libc/process/syscalls.rs b/src/backend/libc/process/syscalls.rs index d5ab0aa92..32d5ccaf0 100644 --- a/src/backend/libc/process/syscalls.rs +++ b/src/backend/libc/process/syscalls.rs @@ -1,7 +1,5 @@ //! libc syscalls supporting `rustix::process`. -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -use super::types::RawCpuSet; use crate::backend::c; #[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] use crate::backend::conv::borrowed_fd; @@ -19,8 +17,6 @@ use crate::backend::conv::ret_discarded_char_ptr; use crate::backend::conv::ret_infallible; #[cfg(not(target_os = "wasi"))] use crate::backend::conv::ret_pid_t; -#[cfg(linux_kernel)] -use crate::backend::conv::ret_u32; #[cfg(all(feature = "alloc", not(target_os = "wasi")))] use crate::backend::conv::ret_usize; use crate::backend::conv::{ret, ret_c_int}; @@ -46,8 +42,6 @@ use crate::process::Signal; target_os = "wasi" )))] use crate::process::Uid; -#[cfg(linux_kernel)] -use crate::process::{Cpuid, MembarrierCommand, MembarrierQuery}; #[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] use crate::process::{RawPid, WaitOptions, WaitStatus}; #[cfg(not(any( @@ -72,14 +66,6 @@ use { super::super::conv::ret_owned_fd, crate::process::PidfdFlags, crate::process::PidfdGetfdFlags, }; -#[cfg(any(linux_kernel, target_os = "dragonfly"))] -#[inline] -pub(crate) fn sched_getcpu() -> usize { - let r = unsafe { libc::sched_getcpu() }; - debug_assert!(r >= 0); - r as usize -} - #[cfg(feature = "fs")] #[cfg(not(target_os = "wasi"))] pub(crate) fn chdir(path: &CStr) -> io::Result<()> { @@ -103,57 +89,6 @@ pub(crate) fn getcwd(buf: &mut [MaybeUninit]) -> io::Result<()> { unsafe { ret_discarded_char_ptr(c::getcwd(buf.as_mut_ptr().cast(), buf.len())) } } -// The `membarrier` syscall has a third argument, but it's only used when -// the `flags` argument is `MEMBARRIER_CMD_FLAG_CPU`. -#[cfg(linux_kernel)] -syscall! { - fn membarrier_all( - cmd: c::c_int, - flags: c::c_uint - ) via SYS_membarrier -> c::c_int -} - -#[cfg(linux_kernel)] -pub(crate) fn membarrier_query() -> MembarrierQuery { - // glibc does not have a wrapper for `membarrier`; [the documentation] - // says to use `syscall`. - // - // [the documentation]: https://man7.org/linux/man-pages/man2/membarrier.2.html#NOTES - const MEMBARRIER_CMD_QUERY: u32 = 0; - unsafe { - match ret_u32(membarrier_all(MEMBARRIER_CMD_QUERY as i32, 0)) { - Ok(query) => MembarrierQuery::from_bits_retain(query), - Err(_) => MembarrierQuery::empty(), - } - } -} - -#[cfg(linux_kernel)] -pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { - unsafe { ret(membarrier_all(cmd as i32, 0)) } -} - -#[cfg(linux_kernel)] -pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { - const MEMBARRIER_CMD_FLAG_CPU: u32 = 1; - - syscall! { - fn membarrier_cpu( - cmd: c::c_int, - flags: c::c_uint, - cpu_id: c::c_int - ) via SYS_membarrier -> c::c_int - } - - unsafe { - ret(membarrier_cpu( - cmd as i32, - MEMBARRIER_CMD_FLAG_CPU, - bitcast!(cpu.as_raw()), - )) - } -} - #[cfg(not(target_os = "wasi"))] #[inline] #[must_use] @@ -189,37 +124,6 @@ pub(crate) fn getpgrp() -> Pid { } } -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -#[inline] -pub(crate) fn sched_getaffinity(pid: Option, cpuset: &mut RawCpuSet) -> io::Result<()> { - unsafe { - ret(c::sched_getaffinity( - Pid::as_raw(pid) as _, - core::mem::size_of::(), - cpuset, - )) - } -} - -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -#[inline] -pub(crate) fn sched_setaffinity(pid: Option, cpuset: &RawCpuSet) -> io::Result<()> { - unsafe { - ret(c::sched_setaffinity( - Pid::as_raw(pid) as _, - core::mem::size_of::(), - cpuset, - )) - } -} - -#[inline] -pub(crate) fn sched_yield() { - unsafe { - let _ = c::sched_yield(); - } -} - #[cfg(not(target_os = "wasi"))] #[cfg(feature = "fs")] #[inline] diff --git a/src/backend/libc/process/types.rs b/src/backend/libc/process/types.rs index f914128df..b0428c2a1 100644 --- a/src/backend/libc/process/types.rs +++ b/src/backend/libc/process/types.rs @@ -1,40 +1,6 @@ #[cfg(not(any(target_os = "espidf", target_os = "vita")))] use crate::backend::c; -/// A command for use with [`membarrier`] and [`membarrier_cpu`]. -/// -/// For `MEMBARRIER_CMD_QUERY`, see [`membarrier_query`]. -/// -/// [`membarrier`]: crate::process::membarrier -/// [`membarrier_cpu`]: crate::process::membarrier_cpu -/// [`membarrier_query`]: crate::process::membarrier_query -#[cfg(linux_kernel)] -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -#[repr(u32)] -pub enum MembarrierCommand { - /// `MEMBARRIER_CMD_GLOBAL` - #[doc(alias = "Shared")] - #[doc(alias = "MEMBARRIER_CMD_SHARED")] - Global = c::MEMBARRIER_CMD_GLOBAL as u32, - /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` - GlobalExpedited = c::MEMBARRIER_CMD_GLOBAL_EXPEDITED as u32, - /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` - RegisterGlobalExpedited = c::MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED as u32, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` - PrivateExpedited = c::MEMBARRIER_CMD_PRIVATE_EXPEDITED as u32, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` - RegisterPrivateExpedited = c::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED as u32, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` - PrivateExpeditedSyncCore = c::MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE as u32, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` - RegisterPrivateExpeditedSyncCore = - c::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE as u32, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - PrivateExpeditedRseq = c::MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ as u32, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - RegisterPrivateExpeditedRseq = c::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ as u32, -} - /// A resource value for use with [`getrlimit`], [`setrlimit`], and /// [`prlimit`]. /// @@ -149,24 +115,5 @@ impl Resource { pub const Rss: Self = Self::As; } -/// A CPU identifier as a raw integer. -#[cfg(linux_kernel)] -pub type RawCpuid = u32; #[cfg(freebsdlike)] pub type RawId = c::id_t; - -#[cfg(any(linux_kernel, target_os = "fuchsia"))] -pub(crate) type RawCpuSet = c::cpu_set_t; -#[cfg(freebsdlike)] -pub(crate) type RawCpuSet = c::cpuset_t; - -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -#[inline] -pub(crate) fn raw_cpu_set_new() -> RawCpuSet { - let mut set = unsafe { core::mem::zeroed() }; - super::cpu_set::CPU_ZERO(&mut set); - set -} - -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -pub(crate) const CPU_SETSIZE: usize = c::CPU_SETSIZE as usize; diff --git a/src/backend/libc/process/cpu_set.rs b/src/backend/libc/thread/cpu_set.rs similarity index 100% rename from src/backend/libc/process/cpu_set.rs rename to src/backend/libc/thread/cpu_set.rs diff --git a/src/backend/libc/thread/mod.rs b/src/backend/libc/thread/mod.rs index 4f8c87cd2..ea2bfd719 100644 --- a/src/backend/libc/thread/mod.rs +++ b/src/backend/libc/thread/mod.rs @@ -1,4 +1,7 @@ +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +pub(crate) mod cpu_set; #[cfg(linux_kernel)] pub(crate) mod futex; #[cfg(not(windows))] pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/src/backend/libc/thread/syscalls.rs b/src/backend/libc/thread/syscalls.rs index 3f39814d1..1ac43fb39 100644 --- a/src/backend/libc/thread/syscalls.rs +++ b/src/backend/libc/thread/syscalls.rs @@ -1,5 +1,7 @@ //! libc syscalls supporting `rustix::thread`. +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +use super::types::RawCpuSet; use crate::backend::c; use crate::backend::conv::ret; use crate::io; @@ -15,6 +17,8 @@ use crate::io; target_os = "wasi", )))] use crate::thread::ClockId; +#[cfg(linux_kernel)] +use crate::thread::{Cpuid, MembarrierCommand, MembarrierQuery}; #[cfg(not(target_os = "redox"))] use crate::thread::{NanosleepRelativeResult, Timespec}; #[cfg(all(target_env = "gnu", fix_y2038))] @@ -30,7 +34,7 @@ use core::mem::MaybeUninit; use core::sync::atomic::AtomicU32; #[cfg(linux_kernel)] use { - crate::backend::conv::{borrowed_fd, ret_c_int, ret_usize}, + crate::backend::conv::{borrowed_fd, ret_c_int, ret_u32, ret_usize}, crate::fd::BorrowedFd, crate::pid::Pid, crate::thread::futex, @@ -646,3 +650,93 @@ pub(crate) fn setgroups_thread(groups: &[crate::ugid::Gid]) -> io::Result<()> { } ret(unsafe { setgroups(groups.len(), groups.as_ptr().cast()) }) } + +#[cfg(any(linux_kernel, target_os = "dragonfly"))] +#[inline] +pub(crate) fn sched_getcpu() -> usize { + let r = unsafe { libc::sched_getcpu() }; + debug_assert!(r >= 0); + r as usize +} + +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +#[inline] +pub(crate) fn sched_getaffinity(pid: Option, cpuset: &mut RawCpuSet) -> io::Result<()> { + unsafe { + ret(c::sched_getaffinity( + Pid::as_raw(pid) as _, + core::mem::size_of::(), + cpuset, + )) + } +} + +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +#[inline] +pub(crate) fn sched_setaffinity(pid: Option, cpuset: &RawCpuSet) -> io::Result<()> { + unsafe { + ret(c::sched_setaffinity( + Pid::as_raw(pid) as _, + core::mem::size_of::(), + cpuset, + )) + } +} + +#[inline] +pub(crate) fn sched_yield() { + unsafe { + let _ = c::sched_yield(); + } +} + +// The `membarrier` syscall has a third argument, but it's only used when +// the `flags` argument is `MEMBARRIER_CMD_FLAG_CPU`. +#[cfg(linux_kernel)] +syscall! { + fn membarrier_all( + cmd: c::c_int, + flags: c::c_uint + ) via SYS_membarrier -> c::c_int +} + +#[cfg(linux_kernel)] +pub(crate) fn membarrier_query() -> MembarrierQuery { + // glibc does not have a wrapper for `membarrier`; [the documentation] + // says to use `syscall`. + // + // [the documentation]: https://man7.org/linux/man-pages/man2/membarrier.2.html#NOTES + const MEMBARRIER_CMD_QUERY: u32 = 0; + unsafe { + match ret_u32(membarrier_all(MEMBARRIER_CMD_QUERY as i32, 0)) { + Ok(query) => MembarrierQuery::from_bits_retain(query), + Err(_) => MembarrierQuery::empty(), + } + } +} + +#[cfg(linux_kernel)] +pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { + unsafe { ret(membarrier_all(cmd as i32, 0)) } +} + +#[cfg(linux_kernel)] +pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { + const MEMBARRIER_CMD_FLAG_CPU: u32 = 1; + + syscall! { + fn membarrier_cpu( + cmd: c::c_int, + flags: c::c_uint, + cpu_id: c::c_int + ) via SYS_membarrier -> c::c_int + } + + unsafe { + ret(membarrier_cpu( + cmd as i32, + MEMBARRIER_CMD_FLAG_CPU, + bitcast!(cpu.as_raw()), + )) + } +} diff --git a/src/backend/libc/thread/types.rs b/src/backend/libc/thread/types.rs new file mode 100644 index 000000000..4282695a5 --- /dev/null +++ b/src/backend/libc/thread/types.rs @@ -0,0 +1,59 @@ +#[cfg(all( + any(freebsdlike, linux_kernel, target_os = "fuchsia"), + not(any(target_os = "espidf", target_os = "vita")) +))] +use crate::backend::c; + +/// A command for use with [`membarrier`] and [`membarrier_cpu`]. +/// +/// For `MEMBARRIER_CMD_QUERY`, see [`membarrier_query`]. +/// +/// [`membarrier`]: crate::process::membarrier +/// [`membarrier_cpu`]: crate::process::membarrier_cpu +/// [`membarrier_query`]: crate::process::membarrier_query +#[cfg(linux_kernel)] +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +#[repr(u32)] +pub enum MembarrierCommand { + /// `MEMBARRIER_CMD_GLOBAL` + #[doc(alias = "Shared")] + #[doc(alias = "MEMBARRIER_CMD_SHARED")] + Global = c::MEMBARRIER_CMD_GLOBAL as u32, + /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` + GlobalExpedited = c::MEMBARRIER_CMD_GLOBAL_EXPEDITED as u32, + /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` + RegisterGlobalExpedited = c::MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED as u32, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` + PrivateExpedited = c::MEMBARRIER_CMD_PRIVATE_EXPEDITED as u32, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` + RegisterPrivateExpedited = c::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED as u32, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` + PrivateExpeditedSyncCore = c::MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE as u32, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` + RegisterPrivateExpeditedSyncCore = + c::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE as u32, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) + PrivateExpeditedRseq = c::MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ as u32, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) + RegisterPrivateExpeditedRseq = c::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ as u32, +} + +/// A CPU identifier as a raw integer. +#[cfg(linux_kernel)] +pub type RawCpuid = u32; + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +pub(crate) type RawCpuSet = c::cpu_set_t; +#[cfg(freebsdlike)] +pub(crate) type RawCpuSet = c::cpuset_t; + +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +#[inline] +pub(crate) fn raw_cpu_set_new() -> RawCpuSet { + let mut set = unsafe { core::mem::zeroed() }; + super::cpu_set::CPU_ZERO(&mut set); + set +} + +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +pub(crate) const CPU_SETSIZE: usize = c::CPU_SETSIZE as usize; diff --git a/src/backend/linux_raw/conv.rs b/src/backend/linux_raw/conv.rs index 79efea3c1..cbd45c184 100644 --- a/src/backend/linux_raw/conv.rs +++ b/src/backend/linux_raw/conv.rs @@ -652,20 +652,20 @@ impl<'a, Num: ArgNumber> From for A } } -#[cfg(feature = "process")] -impl<'a, Num: ArgNumber> From +#[cfg(feature = "thread")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { #[inline] - fn from(cmd: crate::backend::process::types::MembarrierCommand) -> Self { + fn from(cmd: crate::backend::thread::types::MembarrierCommand) -> Self { c_uint(cmd as u32) } } -#[cfg(feature = "process")] -impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { +#[cfg(feature = "thread")] +impl<'a, Num: ArgNumber> From for ArgReg<'a, Num> { #[inline] - fn from(cpuid: crate::process::Cpuid) -> Self { + fn from(cpuid: crate::thread::Cpuid) -> Self { c_uint(cpuid.as_raw()) } } diff --git a/src/backend/linux_raw/process/mod.rs b/src/backend/linux_raw/process/mod.rs index 9b2c25f91..6bc9443d7 100644 --- a/src/backend/linux_raw/process/mod.rs +++ b/src/backend/linux_raw/process/mod.rs @@ -1,4 +1,3 @@ -pub(crate) mod cpu_set; pub(crate) mod syscalls; pub(crate) mod types; pub(crate) mod wait; diff --git a/src/backend/linux_raw/process/syscalls.rs b/src/backend/linux_raw/process/syscalls.rs index a7f59a299..f9607338f 100644 --- a/src/backend/linux_raw/process/syscalls.rs +++ b/src/backend/linux_raw/process/syscalls.rs @@ -5,14 +5,12 @@ //! See the `rustix::backend` module documentation for details. #![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] -use super::types::RawCpuSet; use crate::backend::c; #[cfg(all(feature = "alloc", feature = "fs"))] use crate::backend::conv::slice_mut; use crate::backend::conv::{ by_mut, by_ref, c_int, c_uint, negative_pid, pass_usize, raw_fd, ret, ret_c_int, - ret_c_int_infallible, ret_c_uint, ret_infallible, ret_owned_fd, ret_usize, size_of, - slice_just_addr, zero, + ret_c_int_infallible, ret_infallible, ret_owned_fd, ret_usize, zero, }; use crate::fd::{AsRawFd, BorrowedFd, OwnedFd, RawFd}; #[cfg(feature = "fs")] @@ -20,50 +18,18 @@ use crate::ffi::CStr; use crate::io; use crate::pid::RawPid; use crate::process::{ - Cpuid, MembarrierCommand, MembarrierQuery, Pid, PidfdFlags, PidfdGetfdFlags, Resource, Rlimit, - Uid, WaitId, WaitIdOptions, WaitIdStatus, WaitOptions, WaitStatus, + Pid, PidfdFlags, PidfdGetfdFlags, Resource, Rlimit, Uid, WaitId, WaitIdOptions, WaitIdStatus, + WaitOptions, WaitStatus, }; use crate::signal::Signal; -use crate::utils::as_mut_ptr; use core::mem::MaybeUninit; use core::ptr::{null, null_mut}; -use linux_raw_sys::general::{ - membarrier_cmd, membarrier_cmd_flag, rlimit64, PRIO_PGRP, PRIO_PROCESS, PRIO_USER, - RLIM64_INFINITY, -}; +use linux_raw_sys::general::{rlimit64, PRIO_PGRP, PRIO_PROCESS, PRIO_USER, RLIM64_INFINITY}; #[cfg(feature = "fs")] use {crate::backend::conv::ret_c_uint_infallible, crate::fs::Mode}; #[cfg(feature = "alloc")] use {crate::backend::conv::slice_just_addr_mut, crate::process::Gid}; -// `sched_getcpu` has special optimizations via the vDSO on some architectures. -#[cfg(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc64", - target_arch = "s390x" -))] -pub(crate) use crate::backend::vdso_wrappers::sched_getcpu; - -// `sched_getcpu` on platforms without a vDSO entry for it. -#[cfg(not(any( - target_arch = "x86_64", - target_arch = "x86", - target_arch = "riscv64", - target_arch = "powerpc64", - target_arch = "s390x" -)))] -#[inline] -pub(crate) fn sched_getcpu() -> usize { - let mut cpu = MaybeUninit::::uninit(); - unsafe { - let r = ret(syscall!(__NR_getcpu, &mut cpu, zero(), zero())); - debug_assert!(r.is_ok()); - cpu.assume_init() as usize - } -} - #[cfg(feature = "fs")] #[inline] pub(crate) fn chdir(filename: &CStr) -> io::Result<()> { @@ -88,37 +54,6 @@ pub(crate) fn getcwd(buf: &mut [MaybeUninit]) -> io::Result { unsafe { ret_usize(syscall!(__NR_getcwd, buf_addr_mut, buf_len)) } } -#[inline] -pub(crate) fn membarrier_query() -> MembarrierQuery { - unsafe { - match ret_c_uint(syscall!( - __NR_membarrier, - c_int(membarrier_cmd::MEMBARRIER_CMD_QUERY as _), - c_uint(0) - )) { - Ok(query) => MembarrierQuery::from_bits_retain(query), - Err(_) => MembarrierQuery::empty(), - } - } -} - -#[inline] -pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { - unsafe { ret(syscall!(__NR_membarrier, cmd, c_uint(0))) } -} - -#[inline] -pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { - unsafe { - ret(syscall!( - __NR_membarrier, - cmd, - c_uint(membarrier_cmd_flag::MEMBARRIER_CMD_FLAG_CPU as _), - cpu - )) - } -} - #[inline] pub(crate) fn getppid() -> Option { unsafe { @@ -166,47 +101,6 @@ pub(crate) fn getpgrp() -> Pid { } } -#[inline] -pub(crate) fn sched_getaffinity(pid: Option, cpuset: &mut RawCpuSet) -> io::Result<()> { - unsafe { - // The raw Linux syscall returns the size (in bytes) of the `cpumask_t` - // data type that is used internally by the kernel to represent the CPU - // set bit mask. - let size = ret_usize(syscall!( - __NR_sched_getaffinity, - c_int(Pid::as_raw(pid)), - size_of::(), - by_mut(&mut cpuset.bits) - ))?; - let bytes = as_mut_ptr(cpuset).cast::(); - let rest = bytes.wrapping_add(size); - // Zero every byte in the cpuset not set by the kernel. - rest.write_bytes(0, core::mem::size_of::() - size); - Ok(()) - } -} - -#[inline] -pub(crate) fn sched_setaffinity(pid: Option, cpuset: &RawCpuSet) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_sched_setaffinity, - c_int(Pid::as_raw(pid)), - size_of::(), - slice_just_addr(&cpuset.bits) - )) - } -} - -#[inline] -pub(crate) fn sched_yield() { - unsafe { - // See the documentation for [`crate::process::sched_yield`] for why - // errors are ignored. - syscall_readonly!(__NR_sched_yield).decode_void(); - } -} - #[cfg(feature = "fs")] #[inline] pub(crate) fn umask(mode: Mode) -> Mode { diff --git a/src/backend/linux_raw/process/types.rs b/src/backend/linux_raw/process/types.rs index 841668a60..604176e7a 100644 --- a/src/backend/linux_raw/process/types.rs +++ b/src/backend/linux_raw/process/types.rs @@ -1,39 +1,3 @@ -use linux_raw_sys::general::membarrier_cmd; - -/// A command for use with [`membarrier`] and [`membarrier_cpu`]. -/// -/// For `MEMBARRIER_CMD_QUERY`, see [`membarrier_query`]. -/// -/// [`membarrier`]: crate::process::membarrier -/// [`membarrier_cpu`]: crate::process::membarrier_cpu -/// [`membarrier_query`]: crate::process::membarrier_query -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -#[repr(u32)] -pub enum MembarrierCommand { - /// `MEMBARRIER_CMD_GLOBAL` - #[doc(alias = "Shared")] - #[doc(alias = "MEMBARRIER_CMD_SHARED")] - Global = membarrier_cmd::MEMBARRIER_CMD_GLOBAL as _, - /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` - GlobalExpedited = membarrier_cmd::MEMBARRIER_CMD_GLOBAL_EXPEDITED as _, - /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` - RegisterGlobalExpedited = membarrier_cmd::MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED as _, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` - PrivateExpedited = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED as _, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` - RegisterPrivateExpedited = membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED as _, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` - PrivateExpeditedSyncCore = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE as _, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` - RegisterPrivateExpeditedSyncCore = - membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE as _, - /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - PrivateExpeditedRseq = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ as _, - /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) - RegisterPrivateExpeditedRseq = - membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ as _, -} - /// A resource value for use with [`getrlimit`], [`setrlimit`], and /// [`prlimit`]. /// @@ -76,29 +40,3 @@ pub enum Resource { /// `RLIMIT_RTTIME` Rttime = linux_raw_sys::general::RLIMIT_RTTIME, } - -/// A CPU identifier as a raw integer. -pub type RawCpuid = u32; - -#[repr(C)] -#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] -pub(crate) struct RawCpuSet { - #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] - pub(crate) bits: [u32; 32], - #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86_64"))))] - pub(crate) bits: [u64; 16], -} - -#[inline] -pub(crate) fn raw_cpu_set_new() -> RawCpuSet { - #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] - { - RawCpuSet { bits: [0; 32] } - } - #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86_64"))))] - { - RawCpuSet { bits: [0; 16] } - } -} - -pub(crate) const CPU_SETSIZE: usize = 8 * core::mem::size_of::(); diff --git a/src/backend/linux_raw/process/cpu_set.rs b/src/backend/linux_raw/thread/cpu_set.rs similarity index 100% rename from src/backend/linux_raw/process/cpu_set.rs rename to src/backend/linux_raw/thread/cpu_set.rs diff --git a/src/backend/linux_raw/thread/mod.rs b/src/backend/linux_raw/thread/mod.rs index 6a002c632..c1843eddc 100644 --- a/src/backend/linux_raw/thread/mod.rs +++ b/src/backend/linux_raw/thread/mod.rs @@ -1,2 +1,4 @@ +pub(crate) mod cpu_set; pub(crate) mod futex; pub(crate) mod syscalls; +pub(crate) mod types; diff --git a/src/backend/linux_raw/thread/syscalls.rs b/src/backend/linux_raw/thread/syscalls.rs index a88a8e51e..3411a1ed5 100644 --- a/src/backend/linux_raw/thread/syscalls.rs +++ b/src/backend/linux_raw/thread/syscalls.rs @@ -5,18 +5,23 @@ //! See the `rustix::backend` module documentation for details. #![allow(unsafe_code, clippy::undocumented_unsafe_blocks)] +use super::types::RawCpuSet; use crate::backend::c; use crate::backend::conv::{ - by_mut, by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_usize, slice, - slice_just_addr, slice_just_addr_mut, zero, + by_mut, by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_c_uint, ret_usize, + size_of, slice, slice_just_addr, slice_just_addr_mut, zero, }; use crate::fd::BorrowedFd; use crate::io; use crate::pid::Pid; -use crate::thread::{futex, ClockId, NanosleepRelativeResult, Timespec}; +use crate::thread::{ + futex, ClockId, Cpuid, MembarrierCommand, MembarrierQuery, NanosleepRelativeResult, Timespec, +}; +use crate::utils::as_mut_ptr; use core::mem::MaybeUninit; use core::sync::atomic::AtomicU32; use linux_raw_sys::general::{__kernel_timespec, TIMER_ABSTIME}; +use linux_raw_sys::general::{membarrier_cmd, membarrier_cmd_flag}; #[cfg(target_pointer_width = "32")] use {crate::utils::option_as_ptr, linux_raw_sys::general::timespec as __kernel_old_timespec}; @@ -408,3 +413,103 @@ pub(crate) fn setgroups_thread(gids: &[crate::ugid::Gid]) -> io::Result<()> { let (addr, len) = slice(gids); unsafe { ret(syscall_readonly!(__NR_setgroups, len, addr)) } } + +// `sched_getcpu` has special optimizations via the vDSO on some architectures. +#[cfg(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64", + target_arch = "s390x" +))] +pub(crate) use crate::backend::vdso_wrappers::sched_getcpu; + +// `sched_getcpu` on platforms without a vDSO entry for it. +#[cfg(not(any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "riscv64", + target_arch = "powerpc64", + target_arch = "s390x" +)))] +#[inline] +pub(crate) fn sched_getcpu() -> usize { + let mut cpu = MaybeUninit::::uninit(); + unsafe { + let r = ret(syscall!(__NR_getcpu, &mut cpu, zero(), zero())); + debug_assert!(r.is_ok()); + cpu.assume_init() as usize + } +} + +#[inline] +pub(crate) fn sched_getaffinity(pid: Option, cpuset: &mut RawCpuSet) -> io::Result<()> { + unsafe { + // The raw Linux syscall returns the size (in bytes) of the `cpumask_t` + // data type that is used internally by the kernel to represent the CPU + // set bit mask. + let size = ret_usize(syscall!( + __NR_sched_getaffinity, + c_int(Pid::as_raw(pid)), + size_of::(), + by_mut(&mut cpuset.bits) + ))?; + let bytes = as_mut_ptr(cpuset).cast::(); + let rest = bytes.wrapping_add(size); + // Zero every byte in the cpuset not set by the kernel. + rest.write_bytes(0, core::mem::size_of::() - size); + Ok(()) + } +} + +#[inline] +pub(crate) fn sched_setaffinity(pid: Option, cpuset: &RawCpuSet) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_sched_setaffinity, + c_int(Pid::as_raw(pid)), + size_of::(), + slice_just_addr(&cpuset.bits) + )) + } +} + +#[inline] +pub(crate) fn sched_yield() { + unsafe { + // See the documentation for [`crate::thread::sched_yield`] for why + // errors are ignored. + syscall_readonly!(__NR_sched_yield).decode_void(); + } +} + +#[inline] +pub(crate) fn membarrier_query() -> MembarrierQuery { + unsafe { + match ret_c_uint(syscall!( + __NR_membarrier, + c_int(membarrier_cmd::MEMBARRIER_CMD_QUERY as _), + c_uint(0) + )) { + Ok(query) => MembarrierQuery::from_bits_retain(query), + Err(_) => MembarrierQuery::empty(), + } + } +} + +#[inline] +pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { + unsafe { ret(syscall!(__NR_membarrier, cmd, c_uint(0))) } +} + +#[inline] +pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { + unsafe { + ret(syscall!( + __NR_membarrier, + cmd, + c_uint(membarrier_cmd_flag::MEMBARRIER_CMD_FLAG_CPU as _), + cpu + )) + } +} diff --git a/src/backend/linux_raw/thread/types.rs b/src/backend/linux_raw/thread/types.rs new file mode 100644 index 000000000..e08df2c39 --- /dev/null +++ b/src/backend/linux_raw/thread/types.rs @@ -0,0 +1,61 @@ +use linux_raw_sys::general::membarrier_cmd; + +/// A command for use with [`membarrier`] and [`membarrier_cpu`]. +/// +/// For `MEMBARRIER_CMD_QUERY`, see [`membarrier_query`]. +/// +/// [`membarrier`]: crate::process::membarrier +/// [`membarrier_cpu`]: crate::process::membarrier_cpu +/// [`membarrier_query`]: crate::process::membarrier_query +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +#[repr(u32)] +pub enum MembarrierCommand { + /// `MEMBARRIER_CMD_GLOBAL` + #[doc(alias = "Shared")] + #[doc(alias = "MEMBARRIER_CMD_SHARED")] + Global = membarrier_cmd::MEMBARRIER_CMD_GLOBAL as _, + /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` + GlobalExpedited = membarrier_cmd::MEMBARRIER_CMD_GLOBAL_EXPEDITED as _, + /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` + RegisterGlobalExpedited = membarrier_cmd::MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED as _, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` + PrivateExpedited = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED as _, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` + RegisterPrivateExpedited = membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED as _, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` + PrivateExpeditedSyncCore = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE as _, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` + RegisterPrivateExpeditedSyncCore = + membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE as _, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) + PrivateExpeditedRseq = membarrier_cmd::MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ as _, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) + RegisterPrivateExpeditedRseq = + membarrier_cmd::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ as _, +} + +/// A CPU identifier as a raw integer. +pub type RawCpuid = u32; + +#[repr(C)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub(crate) struct RawCpuSet { + #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] + pub(crate) bits: [u32; 32], + #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86_64"))))] + pub(crate) bits: [u64; 16], +} + +#[inline] +pub(crate) fn raw_cpu_set_new() -> RawCpuSet { + #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] + { + RawCpuSet { bits: [0; 32] } + } + #[cfg(not(all(target_pointer_width = "32", not(target_arch = "x86_64"))))] + { + RawCpuSet { bits: [0; 16] } + } +} + +pub(crate) const CPU_SETSIZE: usize = 8 * core::mem::size_of::(); diff --git a/src/process/id.rs b/src/process/id.rs index 16f16b126..af4dbde7d 100644 --- a/src/process/id.rs +++ b/src/process/id.rs @@ -10,37 +10,10 @@ use crate::{backend, io}; #[cfg(feature = "alloc")] use alloc::vec::Vec; -#[cfg(linux_kernel)] -use backend::process::types::RawCpuid; pub use crate::pid::{Pid, RawPid}; pub use crate::ugid::{Gid, RawGid, RawUid, Uid}; -/// A Linux CPU ID. -#[cfg(linux_kernel)] -#[repr(transparent)] -#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] -pub struct Cpuid(RawCpuid); - -#[cfg(linux_kernel)] -impl Cpuid { - /// Converts a `RawCpuid` into a `Cpuid`. - /// - /// # Safety - /// - /// `raw` must be the value of a valid Linux CPU ID. - #[inline] - pub const unsafe fn from_raw(raw: RawCpuid) -> Self { - Self(raw) - } - - /// Converts a `Cpuid` into a `RawCpuid`. - #[inline] - pub const fn as_raw(self) -> RawCpuid { - self.0 - } -} - /// `getuid()`—Returns the process' real user ID. /// /// # References diff --git a/src/process/mod.rs b/src/process/mod.rs index 5d69e023f..e04bafee9 100644 --- a/src/process/mod.rs +++ b/src/process/mod.rs @@ -11,8 +11,6 @@ mod id; mod ioctl; #[cfg(not(any(target_os = "espidf", target_os = "wasi")))] mod kill; -#[cfg(linux_kernel)] -mod membarrier; #[cfg(target_os = "linux")] mod pidfd; #[cfg(target_os = "linux")] @@ -34,9 +32,6 @@ mod procctl; target_os = "wasi" )))] mod rlimit; -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -mod sched; -mod sched_yield; #[cfg(not(target_os = "wasi"))] // WASI doesn't have umask. mod umask; #[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] @@ -53,8 +48,6 @@ pub use id::*; pub use ioctl::*; #[cfg(not(any(target_os = "espidf", target_os = "wasi")))] pub use kill::*; -#[cfg(linux_kernel)] -pub use membarrier::*; #[cfg(target_os = "linux")] pub use pidfd::*; #[cfg(target_os = "linux")] @@ -75,9 +68,6 @@ pub use procctl::*; target_os = "wasi" )))] pub use rlimit::*; -#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] -pub use sched::*; -pub use sched_yield::sched_yield; #[cfg(not(target_os = "wasi"))] pub use umask::*; #[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] diff --git a/src/thread/id.rs b/src/thread/id.rs index 4cb50a0c1..d68bac5e9 100644 --- a/src/thread/id.rs +++ b/src/thread/id.rs @@ -1,8 +1,43 @@ +//! CPU and thread identifiers. +//! +//! # Safety +//! +//! The `Cpuid`, type can be constructed from raw integers, which is marked +//! unsafe because actual OS's assign special meaning to some integer values. + +#![allow(unsafe_code)] use crate::{backend, io}; +#[cfg(linux_kernel)] +use backend::thread::types::RawCpuid; pub use crate::pid::{Pid, RawPid}; pub use crate::ugid::{Gid, RawGid, RawUid, Uid}; +/// A Linux CPU ID. +#[cfg(linux_kernel)] +#[repr(transparent)] +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] +pub struct Cpuid(RawCpuid); + +#[cfg(linux_kernel)] +impl Cpuid { + /// Converts a `RawCpuid` into a `Cpuid`. + /// + /// # Safety + /// + /// `raw` must be the value of a valid Linux CPU ID. + #[inline] + pub const unsafe fn from_raw(raw: RawCpuid) -> Self { + Self(raw) + } + + /// Converts a `Cpuid` into a `RawCpuid`. + #[inline] + pub const fn as_raw(self) -> RawCpuid { + self.0 + } +} + /// `gettid()`—Returns the thread ID. /// /// This returns the OS thread ID, which is not necessarily the same as the diff --git a/src/process/membarrier.rs b/src/thread/membarrier.rs similarity index 93% rename from src/process/membarrier.rs rename to src/thread/membarrier.rs index 26be07dd9..b3e6508e5 100644 --- a/src/process/membarrier.rs +++ b/src/thread/membarrier.rs @@ -1,9 +1,9 @@ //! The Linux `membarrier` syscall. -use crate::process::Cpuid; +use crate::thread::Cpuid; use crate::{backend, io}; -pub use backend::process::types::MembarrierCommand; +pub use backend::thread::types::MembarrierCommand; #[cfg(linux_kernel)] bitflags::bitflags! { @@ -65,7 +65,7 @@ impl MembarrierQuery { #[inline] #[doc(alias = "MEMBARRIER_CMD_QUERY")] pub fn membarrier_query() -> MembarrierQuery { - backend::process::syscalls::membarrier_query() + backend::thread::syscalls::membarrier_query() } /// `membarrier(cmd, 0, 0)`—Perform a memory barrier. @@ -76,7 +76,7 @@ pub fn membarrier_query() -> MembarrierQuery { /// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html #[inline] pub fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { - backend::process::syscalls::membarrier(cmd) + backend::thread::syscalls::membarrier(cmd) } /// `membarrier(cmd, MEMBARRIER_CMD_FLAG_CPU, cpu)`—Perform a memory barrier @@ -88,5 +88,5 @@ pub fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { /// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html #[inline] pub fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { - backend::process::syscalls::membarrier_cpu(cmd, cpu) + backend::thread::syscalls::membarrier_cpu(cmd, cpu) } diff --git a/src/thread/mod.rs b/src/thread/mod.rs index 20fc5df99..a6a102e34 100644 --- a/src/thread/mod.rs +++ b/src/thread/mod.rs @@ -9,7 +9,12 @@ mod id; #[cfg(linux_kernel)] mod libcap; #[cfg(linux_kernel)] +mod membarrier; +#[cfg(linux_kernel)] mod prctl; +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +mod sched; +mod sched_yield; #[cfg(linux_kernel)] mod setns; @@ -20,13 +25,15 @@ pub use crate::thread::futex::{ #[cfg(not(target_os = "redox"))] pub use clock::*; #[cfg(linux_kernel)] -pub use id::{ - gettid, set_thread_gid, set_thread_groups, set_thread_res_gid, set_thread_res_uid, - set_thread_uid, Gid, Pid, RawGid, RawPid, RawUid, Uid, -}; +pub use id::*; #[cfg(linux_kernel)] pub use libcap::{capabilities, set_capabilities, CapabilityFlags, CapabilitySets}; #[cfg(linux_kernel)] +pub use membarrier::*; +#[cfg(linux_kernel)] pub use prctl::*; +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +pub use sched::*; +pub use sched_yield::sched_yield; #[cfg(linux_kernel)] pub use setns::*; diff --git a/src/process/sched.rs b/src/thread/sched.rs similarity index 78% rename from src/process/sched.rs rename to src/thread/sched.rs index f9614e8a0..09186a76c 100644 --- a/src/process/sched.rs +++ b/src/thread/sched.rs @@ -1,4 +1,4 @@ -use crate::process::Pid; +use crate::pid::Pid; use crate::{backend, io}; use core::{fmt, hash}; @@ -11,23 +11,23 @@ use core::{fmt, hash}; /// - [Linux] /// /// [Linux]: https://man7.org/linux/man-pages/man3/CPU_SET.3.html -/// [`sched_setaffinity`]: crate::process::sched_setaffinity -/// [`sched_getaffinity`]: crate::process::sched_getaffinity +/// [`sched_setaffinity`]: crate::thread::sched_setaffinity +/// [`sched_getaffinity`]: crate::thread::sched_getaffinity #[repr(C)] #[derive(Clone, Copy)] pub struct CpuSet { - cpu_set: backend::process::types::RawCpuSet, + cpu_set: backend::thread::types::RawCpuSet, } impl CpuSet { /// The maximum number of CPU in `CpuSet`. - pub const MAX_CPU: usize = backend::process::types::CPU_SETSIZE; + pub const MAX_CPU: usize = backend::thread::types::CPU_SETSIZE; /// Create a new and empty `CpuSet`. #[inline] pub fn new() -> Self { Self { - cpu_set: backend::process::types::raw_cpu_set_new(), + cpu_set: backend::thread::types::raw_cpu_set_new(), } } @@ -36,7 +36,7 @@ impl CpuSet { /// `field` is the CPU id to test. #[inline] pub fn is_set(&self, field: usize) -> bool { - backend::process::cpu_set::CPU_ISSET(field, &self.cpu_set) + backend::thread::cpu_set::CPU_ISSET(field, &self.cpu_set) } /// Add a CPU to `CpuSet`. @@ -44,7 +44,7 @@ impl CpuSet { /// `field` is the CPU id to add. #[inline] pub fn set(&mut self, field: usize) { - backend::process::cpu_set::CPU_SET(field, &mut self.cpu_set) + backend::thread::cpu_set::CPU_SET(field, &mut self.cpu_set) } /// Remove a CPU from `CpuSet`. @@ -52,20 +52,20 @@ impl CpuSet { /// `field` is the CPU id to remove. #[inline] pub fn unset(&mut self, field: usize) { - backend::process::cpu_set::CPU_CLR(field, &mut self.cpu_set) + backend::thread::cpu_set::CPU_CLR(field, &mut self.cpu_set) } /// Count the number of CPUs set in the `CpuSet`. #[cfg(linux_kernel)] #[inline] pub fn count(&self) -> u32 { - backend::process::cpu_set::CPU_COUNT(&self.cpu_set) + backend::thread::cpu_set::CPU_COUNT(&self.cpu_set) } /// Zeroes the `CpuSet`. #[inline] pub fn clear(&mut self) { - backend::process::cpu_set::CPU_ZERO(&mut self.cpu_set) + backend::thread::cpu_set::CPU_ZERO(&mut self.cpu_set) } } @@ -107,7 +107,7 @@ impl Eq for CpuSet {} impl PartialEq for CpuSet { fn eq(&self, other: &Self) -> bool { - backend::process::cpu_set::CPU_EQUAL(&self.cpu_set, &other.cpu_set) + backend::thread::cpu_set::CPU_EQUAL(&self.cpu_set, &other.cpu_set) } } @@ -125,7 +125,7 @@ impl PartialEq for CpuSet { /// [Linux]: https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html #[inline] pub fn sched_setaffinity(pid: Option, cpuset: &CpuSet) -> io::Result<()> { - backend::process::syscalls::sched_setaffinity(pid, &cpuset.cpu_set) + backend::thread::syscalls::sched_setaffinity(pid, &cpuset.cpu_set) } /// `sched_getaffinity(pid)`—Get a thread's CPU affinity mask. @@ -142,7 +142,7 @@ pub fn sched_setaffinity(pid: Option, cpuset: &CpuSet) -> io::Result<()> { #[inline] pub fn sched_getaffinity(pid: Option) -> io::Result { let mut cpuset = CpuSet::new(); - backend::process::syscalls::sched_getaffinity(pid, &mut cpuset.cpu_set).and(Ok(cpuset)) + backend::thread::syscalls::sched_getaffinity(pid, &mut cpuset.cpu_set).and(Ok(cpuset)) } /// `sched_getcpu()`—Get the CPU that the current thread is currently on. @@ -157,5 +157,5 @@ pub fn sched_getaffinity(pid: Option) -> io::Result { #[cfg(any(linux_kernel, target_os = "dragonfly"))] #[inline] pub fn sched_getcpu() -> usize { - backend::process::syscalls::sched_getcpu() + backend::thread::syscalls::sched_getcpu() } diff --git a/src/process/sched_yield.rs b/src/thread/sched_yield.rs similarity index 89% rename from src/process/sched_yield.rs rename to src/thread/sched_yield.rs index 97b1d99a2..e630a95c0 100644 --- a/src/process/sched_yield.rs +++ b/src/thread/sched_yield.rs @@ -12,5 +12,5 @@ use crate::backend; /// [Linux]: https://man7.org/linux/man-pages/man2/sched_yield.2.html #[inline] pub fn sched_yield() { - backend::process::syscalls::sched_yield() + backend::thread::syscalls::sched_yield() } diff --git a/tests/process/main.rs b/tests/process/main.rs index 22b09a8b0..61b1eae3b 100644 --- a/tests/process/main.rs +++ b/tests/process/main.rs @@ -4,11 +4,8 @@ #![cfg(not(windows))] #![cfg_attr(core_c_str, feature(core_c_str))] -mod cpu_set; #[cfg(not(target_os = "wasi"))] // WASI doesn't have get[gpu]id. mod id; -#[cfg(linux_kernel)] -mod membarrier; #[cfg(target_os = "linux")] mod pidfd; #[cfg(linux_kernel)] @@ -19,7 +16,6 @@ mod priority; mod procctl; #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] mod rlimit; -mod sched; #[cfg(not(target_os = "wasi"))] // WASI doesn't have umask. mod umask; #[cfg(not(any(target_os = "espidf", target_os = "wasi")))] // WASI doesn't have waitpid. diff --git a/tests/process/cpu_set.rs b/tests/thread/cpu_set.rs similarity index 60% rename from tests/process/cpu_set.rs rename to tests/thread/cpu_set.rs index 0c70cddd0..e994cdcc4 100644 --- a/tests/process/cpu_set.rs +++ b/tests/thread/cpu_set.rs @@ -1,10 +1,10 @@ #[cfg(linux_kernel)] #[test] fn test_cpu_set() { - let set = rustix::process::sched_getaffinity(None).unwrap(); + let set = rustix::thread::sched_getaffinity(None).unwrap(); let mut count = 0; - for i in 0..rustix::process::CpuSet::MAX_CPU { + for i in 0..rustix::thread::CpuSet::MAX_CPU { if set.is_set(i) { count += 1; } diff --git a/tests/thread/main.rs b/tests/thread/main.rs index bdd02dc6c..9d9d2b6d5 100644 --- a/tests/thread/main.rs +++ b/tests/thread/main.rs @@ -5,6 +5,7 @@ #[cfg(not(target_os = "redox"))] mod clocks; +mod cpu_set; #[cfg(linux_kernel)] mod futex; #[cfg(linux_kernel)] @@ -12,6 +13,9 @@ mod id; #[cfg(linux_kernel)] mod libcap; #[cfg(linux_kernel)] +mod membarrier; +#[cfg(linux_kernel)] mod prctl; +mod sched; #[cfg(linux_kernel)] mod setns; diff --git a/tests/process/membarrier.rs b/tests/thread/membarrier.rs similarity index 91% rename from tests/process/membarrier.rs rename to tests/thread/membarrier.rs index 4ed705d16..7d40bc736 100644 --- a/tests/process/membarrier.rs +++ b/tests/thread/membarrier.rs @@ -1,6 +1,6 @@ #[test] fn test_membarrier() { - use rustix::process::{membarrier, membarrier_query, MembarrierCommand, MembarrierQuery}; + use rustix::thread::{membarrier, membarrier_query, MembarrierCommand, MembarrierQuery}; let query: MembarrierQuery = membarrier_query(); diff --git a/tests/process/sched.rs b/tests/thread/sched.rs similarity index 57% rename from tests/process/sched.rs rename to tests/thread/sched.rs index 1aacc8e42..2dc32c5f3 100644 --- a/tests/process/sched.rs +++ b/tests/thread/sched.rs @@ -1,4 +1,4 @@ -use rustix::process::sched_yield; +use rustix::thread::sched_yield; #[test] fn test_sched_yield() { @@ -9,6 +9,6 @@ fn test_sched_yield() { #[cfg(any(linux_kernel, target_os = "dragonfly"))] #[test] fn test_sched_getcpu() { - let n = rustix::process::sched_getcpu(); - assert!(n < rustix::process::CpuSet::MAX_CPU); + let n = rustix::thread::sched_getcpu(); + assert!(n < rustix::thread::CpuSet::MAX_CPU); } From 26f7b1b37be6e903b5dcefb8be4266d64f5df729 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Jan 2025 10:57:27 -0800 Subject: [PATCH 2/4] Fix compilation on FreeBSD. --- src/backend/libc/thread/syscalls.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/libc/thread/syscalls.rs b/src/backend/libc/thread/syscalls.rs index 1ac43fb39..9ac228bfb 100644 --- a/src/backend/libc/thread/syscalls.rs +++ b/src/backend/libc/thread/syscalls.rs @@ -5,6 +5,8 @@ use super::types::RawCpuSet; use crate::backend::c; use crate::backend::conv::ret; use crate::io; +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +use crate::pid::Pid; #[cfg(not(any( apple, freebsdlike, @@ -36,7 +38,6 @@ use core::sync::atomic::AtomicU32; use { crate::backend::conv::{borrowed_fd, ret_c_int, ret_u32, ret_usize}, crate::fd::BorrowedFd, - crate::pid::Pid, crate::thread::futex, crate::utils::as_mut_ptr, }; From 126ea06c66e217cdf1bb61728f53bc17ab0f2f69 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Jan 2025 11:00:50 -0800 Subject: [PATCH 3/4] Fix warnings. --- src/backend/linux_raw/process/syscalls.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/backend/linux_raw/process/syscalls.rs b/src/backend/linux_raw/process/syscalls.rs index f9607338f..eeb463b58 100644 --- a/src/backend/linux_raw/process/syscalls.rs +++ b/src/backend/linux_raw/process/syscalls.rs @@ -10,7 +10,7 @@ use crate::backend::c; use crate::backend::conv::slice_mut; use crate::backend::conv::{ by_mut, by_ref, c_int, c_uint, negative_pid, pass_usize, raw_fd, ret, ret_c_int, - ret_c_int_infallible, ret_infallible, ret_owned_fd, ret_usize, zero, + ret_c_int_infallible, ret_infallible, ret_owned_fd, zero, }; use crate::fd::{AsRawFd, BorrowedFd, OwnedFd, RawFd}; #[cfg(feature = "fs")] @@ -28,7 +28,10 @@ use linux_raw_sys::general::{rlimit64, PRIO_PGRP, PRIO_PROCESS, PRIO_USER, RLIM6 #[cfg(feature = "fs")] use {crate::backend::conv::ret_c_uint_infallible, crate::fs::Mode}; #[cfg(feature = "alloc")] -use {crate::backend::conv::slice_just_addr_mut, crate::process::Gid}; +use { + crate::backend::conv::{ret_usize, slice_just_addr_mut}, + crate::process::Gid, +}; #[cfg(feature = "fs")] #[inline] From 31101a0a5a11a146b2c5835897a43613d112f424 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 13 Jan 2025 11:12:21 -0800 Subject: [PATCH 4/4] Fix a warning. --- src/backend/libc/process/types.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/backend/libc/process/types.rs b/src/backend/libc/process/types.rs index b0428c2a1..576f06982 100644 --- a/src/backend/libc/process/types.rs +++ b/src/backend/libc/process/types.rs @@ -1,4 +1,10 @@ -#[cfg(not(any(target_os = "espidf", target_os = "vita")))] +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] use crate::backend::c; /// A resource value for use with [`getrlimit`], [`setrlimit`], and