#[cfg(target_os = "linux")]
pub fn set_idle_cpu() -> std::io::Result<()> {
let mut param: libc::sched_param = unsafe { std::mem::zeroed() };
param.sched_priority = 0;
let rc = unsafe { libc::sched_setscheduler(0, libc::SCHED_IDLE, ¶m) };
if rc == -1 {
Err(std::io::Error::last_os_error())
} else {
Ok(())
}
}
#[cfg(target_os = "linux")]
pub fn set_idle_io() -> std::io::Result<()> {
const IOPRIO_WHO_PROCESS: libc::c_int = 1;
const IOPRIO_CLASS_IDLE: libc::c_int = 3;
const IOPRIO_CLASS_SHIFT: libc::c_int = 13;
let prio: libc::c_int = IOPRIO_CLASS_IDLE << IOPRIO_CLASS_SHIFT;
let rc = unsafe {
libc::syscall(libc::SYS_ioprio_set, IOPRIO_WHO_PROCESS, 0, prio)
};
if rc == -1 {
Err(std::io::Error::last_os_error())
} else {
Ok(())
}
}
#[cfg(target_os = "linux")]
pub fn lower_nice() -> std::io::Result<()> {
let rc = unsafe { libc::setpriority(libc::PRIO_PROCESS, 0, 19) };
if rc == -1 {
Err(std::io::Error::last_os_error())
} else {
Ok(())
}
}
#[cfg(all(test, target_os = "linux"))]
mod tests {
use super::*;
#[test]
fn set_idle_cpu_succeeds_and_restores() {
let orig = unsafe { libc::sched_getscheduler(0) };
assert!(set_idle_cpu().is_ok());
let mut param: libc::sched_param = unsafe { std::mem::zeroed() };
param.sched_priority = 0;
unsafe { libc::sched_setscheduler(0, orig.max(0), ¶m) };
}
#[test]
fn set_idle_io_succeeds_and_restores() {
const IOPRIO_WHO_PROCESS: libc::c_int = 1;
let orig = unsafe {
libc::syscall(libc::SYS_ioprio_get, IOPRIO_WHO_PROCESS, 0)
};
assert!(set_idle_io().is_ok());
if orig >= 0 {
unsafe {
libc::syscall(
libc::SYS_ioprio_set,
IOPRIO_WHO_PROCESS,
0,
orig as libc::c_int,
);
}
}
}
}