sched_setaffinity: test cpusetsize == 0

This commit is contained in:
Folkert 2024-07-06 12:02:17 +02:00 committed by Ralf Jung
parent 9a0e671cc2
commit 46019523e8
2 changed files with 22 additions and 1 deletions

View file

@ -645,7 +645,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.set_last_error(einval)?;
this.write_scalar(Scalar::from_i32(-1), dest)?;
} else {
// NOTE: cpusetsize might be smaller than `CpuAffinityMask::CPU_MASK_BYTES`
// NOTE: cpusetsize might be smaller than `CpuAffinityMask::CPU_MASK_BYTES`.
// Any unspecified bytes are treated as zero here (none of the CPUs are configured).
// This is not exactly documented, so we assume that this is the behavior in practice.
let bits_slice = this.read_bytes_ptr_strip_provenance(mask, Size::from_bytes(cpusetsize))?;
// This ignores the bytes beyond `CpuAffinityMask::CPU_MASK_BYTES`
let bits_array: [u8; CpuAffinityMask::CPU_MASK_BYTES] =

View file

@ -105,6 +105,24 @@ fn get_small_cpu_mask() {
}
}
fn set_small_cpu_mask() {
let mut cpuset: cpu_set_t = unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
let err = unsafe { sched_getaffinity(PID, size_of::<cpu_set_t>(), &mut cpuset) };
assert_eq!(err, 0);
// setting a mask of size 0 is invalid
let err = unsafe { sched_setaffinity(PID, 0, &cpuset) };
assert_eq!(err, -1);
assert_eq!(std::io::Error::last_os_error().kind(), std::io::ErrorKind::InvalidInput);
// any other number of bytes (at least up to `size_of<cpu_set_t>()` will work
for i in 1..24 {
let err = unsafe { sched_setaffinity(PID, i, &cpuset) };
assert_eq!(err, 0, "fail for {i}");
}
}
fn set_custom_cpu_mask() {
let cpu_count = std::thread::available_parallelism().unwrap().get();
@ -189,6 +207,7 @@ fn main() {
configure_unavailable_cpu();
large_set();
get_small_cpu_mask();
set_small_cpu_mask();
set_custom_cpu_mask();
parent_child();
}