1use crate::{is_realtime, Result};
2use core::fmt;
3use std::convert::Infallible;
4use std::str::FromStr;
5
6#[allow(clippy::module_name_repetitions)]
22#[derive(Default)]
23pub struct SystemConfig(rtsc::system::linux::SystemConfig);
24
25impl SystemConfig {
26 #[must_use]
28 pub fn new() -> Self {
29 Self::default()
30 }
31 pub fn set<V: fmt::Display>(mut self, key: &'static str, value: V) -> Self {
33 if is_realtime() {
34 self.0 = self.0.set(key, value);
35 }
36 self
37 }
38 pub fn apply(self) -> Result<rtsc::system::linux::SystemConfigGuard> {
40 if is_realtime() {
41 return self.0.apply().map_err(Into::into);
42 }
43 Ok(rtsc::system::linux::SystemConfigGuard::default())
44 }
45}
46
47pub struct CpuGovernor(#[allow(dead_code)] rtsc::system::linux::CpuGovernor);
50
51impl CpuGovernor {
52 pub fn performance<I>(performance_cpus: I) -> Result<CpuGovernor>
57 where
58 I: IntoIterator<Item = usize>,
59 {
60 if is_realtime() {
61 let inner = rtsc::system::linux::CpuGovernor::performance(performance_cpus)?;
62 Ok(Self(inner))
63 } else {
64 Ok(Self(rtsc::system::linux::CpuGovernor::default()))
65 }
66 }
67}
68
69#[derive(Debug, Copy, Clone, Eq, PartialEq)]
71pub enum StateVariant {
72 Initializing,
74 Starting,
76 Running,
78 Degraded,
80 Maintenance,
82 Stopping,
84 Other,
86}
87
88impl fmt::Display for StateVariant {
89 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
90 match *self {
91 StateVariant::Initializing => write!(f, "initializing"),
92 StateVariant::Starting => write!(f, "starting"),
93 StateVariant::Running => write!(f, "running"),
94 StateVariant::Degraded => write!(f, "degraded"),
95 StateVariant::Maintenance => write!(f, "maintenance"),
96 StateVariant::Stopping => write!(f, "stopping"),
97 StateVariant::Other => write!(f, "other"),
98 }
99 }
100}
101
102impl FromStr for StateVariant {
103 type Err = Infallible;
104
105 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
106 Ok(match s {
107 "initializing" => StateVariant::Initializing,
108 "starting" => StateVariant::Starting,
109 "running" => StateVariant::Running,
110 "degraded" => StateVariant::Degraded,
111 "maintenance" => StateVariant::Maintenance,
112 "stopping" => StateVariant::Stopping,
113 _ => StateVariant::Other,
114 })
115 }
116}
117
118pub fn state() -> Result<StateVariant> {
121 std::process::Command::new("systemctl")
122 .arg("is-system-running")
123 .output()
124 .map_err(Into::into)
125 .and_then(|output| {
126 let state = std::str::from_utf8(&output.stdout).unwrap_or_default();
127 state.trim().parse().map_err(Into::into)
128 })
129}
130
131pub fn wait_running_state() -> Result<()> {
133 loop {
134 if state()? == StateVariant::Running {
135 break;
136 }
137 std::thread::sleep(std::time::Duration::from_millis(500));
138 }
139 Ok(())
140}
141
142