indexbus_platform_ops/linux/
sched.rs

1//! Linux scheduler / realtime policy helpers.
2//!
3//! These helpers are intentionally small and explicit. They operate on the *current thread*.
4//!
5//! References:
6//! - `pthread_setschedparam(3)` / `sched_setscheduler(2)`
7//! - Real-time policies: `SCHED_FIFO`, `SCHED_RR`
8
9use crate::errors::{Error, Result};
10
11fn prio_bounds(policy: i32) -> Result<(i32, i32)> {
12    let min = unsafe { libc::sched_get_priority_min(policy) };
13    if min == -1 {
14        return Err(Error::msg(format!(
15            "sched_get_priority_min(policy={policy}) failed: {}",
16            std::io::Error::last_os_error()
17        )));
18    }
19
20    let max = unsafe { libc::sched_get_priority_max(policy) };
21    if max == -1 {
22        return Err(Error::msg(format!(
23            "sched_get_priority_max(policy={policy}) failed: {}",
24            std::io::Error::last_os_error()
25        )));
26    }
27
28    Ok((min, max))
29}
30
31fn set_current_thread(policy: i32, prio: i32) -> Result<()> {
32    let (min, max) = prio_bounds(policy)?;
33    if prio < min || prio > max {
34        return Err(Error::msg(format!(
35            "invalid realtime priority {prio} for policy={policy} (expected {min}..={max})"
36        )));
37    }
38
39    // pthread_setschedparam affects only the current thread.
40    let param = libc::sched_param {
41        sched_priority: prio,
42    };
43    let rc = unsafe { libc::pthread_setschedparam(libc::pthread_self(), policy, &param) };
44    if rc != 0 {
45        return Err(Error::msg(format!(
46            "pthread_setschedparam(policy={policy}, prio={prio}) failed: {}",
47            std::io::Error::from_raw_os_error(rc)
48        )));
49    }
50
51    Ok(())
52}
53
54/// Set the current thread to the normal time-sharing policy (`SCHED_OTHER`).
55pub fn set_current_thread_sched_other() -> Result<()> {
56    // Per manpages, priority is ignored / must be 0.
57    set_current_thread(libc::SCHED_OTHER, 0)
58}
59
60/// Set the current thread to `SCHED_FIFO` with the given priority.
61pub fn set_current_thread_sched_fifo(prio: i32) -> Result<()> {
62    set_current_thread(libc::SCHED_FIFO, prio)
63}
64
65/// Set the current thread to `SCHED_RR` with the given priority.
66pub fn set_current_thread_sched_rr(prio: i32) -> Result<()> {
67    set_current_thread(libc::SCHED_RR, prio)
68}