Skip to content

Commit 4601952

Browse files
folkertdevRalfJung
authored andcommitted
sched_setaffinity: test cpusetsize == 0
1 parent 9a0e671 commit 4601952

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

src/tools/miri/src/shims/unix/foreign_items.rs

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

src/tools/miri/tests/pass-dep/libc/libc-affinity.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,24 @@ fn get_small_cpu_mask() {
105105
}
106106
}
107107

108+
fn set_small_cpu_mask() {
109+
let mut cpuset: cpu_set_t = unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
110+
111+
let err = unsafe { sched_getaffinity(PID, size_of::<cpu_set_t>(), &mut cpuset) };
112+
assert_eq!(err, 0);
113+
114+
// setting a mask of size 0 is invalid
115+
let err = unsafe { sched_setaffinity(PID, 0, &cpuset) };
116+
assert_eq!(err, -1);
117+
assert_eq!(std::io::Error::last_os_error().kind(), std::io::ErrorKind::InvalidInput);
118+
119+
// any other number of bytes (at least up to `size_of<cpu_set_t>()` will work
120+
for i in 1..24 {
121+
let err = unsafe { sched_setaffinity(PID, i, &cpuset) };
122+
assert_eq!(err, 0, "fail for {i}");
123+
}
124+
}
125+
108126
fn set_custom_cpu_mask() {
109127
let cpu_count = std::thread::available_parallelism().unwrap().get();
110128

@@ -189,6 +207,7 @@ fn main() {
189207
configure_unavailable_cpu();
190208
large_set();
191209
get_small_cpu_mask();
210+
set_small_cpu_mask();
192211
set_custom_cpu_mask();
193212
parent_child();
194213
}

0 commit comments

Comments
 (0)