From 28740f1e38306c44b45e1ccdf16de76d38240fa8 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 24 Sep 2026 20:58:32 +0100 Subject: [PATCH] std::thread::available_parallelism: FreeBSD CPU affinity buffer increase Use a larger buffer to handle larger CPU mask in kernel >= 14.0 std sets the FreeBSD ABI level to 12, cpuset_t is 256 bits large while more recent kernels propose 1024 support. --- library/std/src/sys/thread/unix.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/thread/unix.rs b/library/std/src/sys/thread/unix.rs index 11fe569f8e0a9..e7de5281cf6c4 100644 --- a/library/std/src/sys/thread/unix.rs +++ b/library/std/src/sys/thread/unix.rs @@ -181,12 +181,29 @@ pub fn available_parallelism() -> io::Result> { { #[cfg(not(target_os = "freebsd"))] type Cpuset = libc::cpu_set_t; + // FreeBSD >= 13.2 having smaller mask will just leave the remaining bits to zero, + // 1024 here to match FreeBSD >= 14.x CPU_MAXSIZE + // while ABI gate is still freebsd 12 (CPU_SETSIZE is 256). #[cfg(target_os = "freebsd")] - type Cpuset = libc::cpuset_t; + const CPU_MAXSIZE: usize = 1024; + #[cfg(target_os = "freebsd")] + type Cpuset = [libc::c_long; CPU_MAXSIZE / libc::c_long::BITS as usize]; let mut set: Cpuset = unsafe { mem::zeroed() }; unsafe { - if libc::sched_getaffinity(0, size_of::(), &mut set) == 0 { + #[cfg(not(target_os = "freebsd"))] + let affinity = libc::sched_getaffinity(0, size_of::(), &mut set); + #[cfg(target_os = "freebsd")] + let affinity = libc::sched_getaffinity( + 0, + size_of::(), + set.as_mut_ptr().cast::(), + ); + + if affinity == 0 { + #[cfg(not(target_os = "freebsd"))] let count = libc::CPU_COUNT(&set) as usize; + #[cfg(target_os = "freebsd")] + let count: usize = set.iter().map(|s| s.count_ones() as usize).sum(); let count = count.min(quota); // According to sched_getaffinity's API it should always be non-zero, but