byteor_ops/
tuning.rs

1//! Scheduler and memory-lock tuning presets.
2
3use crate::error::{platform_err, Result};
4
5/// `mlockall` presets.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub enum MlockallPreset {
8    /// Do not lock mappings into RAM.
9    None,
10    /// Lock current and future mappings into RAM.
11    On,
12}
13
14impl MlockallPreset {
15    /// Parse an `mlockall` preset from a CLI/env string.
16    pub fn parse(s: &str) -> Option<Self> {
17        match s {
18            "none" => Some(Self::None),
19            "on" => Some(Self::On),
20            _ => None,
21        }
22    }
23
24    /// Convert an `mlockall` preset to its stable string form.
25    pub fn as_str(self) -> &'static str {
26        match self {
27            Self::None => "none",
28            Self::On => "on",
29        }
30    }
31}
32
33/// Scheduler tuning presets.
34///
35/// These operate on the *current thread*.
36#[derive(Clone, Copy, Debug, PartialEq, Eq)]
37pub enum SchedPreset {
38    /// Default time-sharing scheduling (`SCHED_OTHER`).
39    Other,
40    /// Real-time FIFO scheduling (`SCHED_FIFO`) with the given priority.
41    Fifo {
42        /// RT priority (typically 1..=99).
43        prio: u8,
44    },
45    /// Real-time round-robin scheduling (`SCHED_RR`) with the given priority.
46    Rr {
47        /// RT priority (typically 1..=99).
48        prio: u8,
49    },
50}
51
52impl SchedPreset {
53    /// Parse a scheduler preset kind from a CLI/env string.
54    pub fn parse_kind(s: &str) -> Option<Self> {
55        match s {
56            "other" => Some(Self::Other),
57            "fifo" => Some(Self::Fifo { prio: 80 }),
58            "rr" => Some(Self::Rr { prio: 80 }),
59            _ => None,
60        }
61    }
62
63    /// Stable kind string for CLI/logging.
64    pub fn kind_str(self) -> &'static str {
65        match self {
66            Self::Other => "other",
67            Self::Fifo { .. } => "fifo",
68            Self::Rr { .. } => "rr",
69        }
70    }
71
72    /// Returns `true` if this preset requests real-time scheduling.
73    pub fn is_realtime(self) -> bool {
74        matches!(self, Self::Fifo { .. } | Self::Rr { .. })
75    }
76
77    /// Return the RT priority if this preset is real-time.
78    pub fn rt_prio(self) -> Option<u8> {
79        match self {
80            Self::Other => None,
81            Self::Fifo { prio } => Some(prio),
82            Self::Rr { prio } => Some(prio),
83        }
84    }
85
86    /// Return a copy of this preset with the given RT priority.
87    pub fn with_rt_prio(self, prio: u8) -> Self {
88        match self {
89            Self::Other => Self::Other,
90            Self::Fifo { .. } => Self::Fifo { prio },
91            Self::Rr { .. } => Self::Rr { prio },
92        }
93    }
94}
95
96/// Apply a scheduler preset to the current thread.
97pub fn apply_sched(preset: SchedPreset) -> Result<()> {
98    #[cfg(target_os = "linux")]
99    {
100        match preset {
101            SchedPreset::Other => {
102                indexbus_platform_ops::linux::sched::set_current_thread_sched_other()
103                    .map_err(|e| platform_err("sched other failed", e))
104            }
105            SchedPreset::Fifo { prio } => {
106                indexbus_platform_ops::linux::sched::set_current_thread_sched_fifo(prio as i32)
107                    .map_err(|e| platform_err("sched fifo failed", e))
108            }
109            SchedPreset::Rr { prio } => {
110                indexbus_platform_ops::linux::sched::set_current_thread_sched_rr(prio as i32)
111                    .map_err(|e| platform_err("sched rr failed", e))
112            }
113        }
114    }
115
116    #[cfg(not(target_os = "linux"))]
117    {
118        let _ = preset;
119        Err(crate::OpsError::Invalid {
120            what: "scheduling presets are only supported on Linux".to_string(),
121        })
122    }
123}
124
125/// Apply an `mlockall` preset to the current process.
126pub fn apply_mlockall(preset: MlockallPreset) -> Result<()> {
127    match preset {
128        MlockallPreset::None => Ok(()),
129        MlockallPreset::On => indexbus_platform_ops::memory::mlockall_current_and_future()
130            .map_err(|e| platform_err("mlockall failed", e)),
131    }
132}