提交 51a3b88b authored 作者: Serhij S's avatar Serhij S

kernel config

上级 4d903a1b
...@@ -6,13 +6,14 @@ use libc::cpu_set_t; ...@@ -6,13 +6,14 @@ use libc::cpu_set_t;
use nix::{sys::signal, unistd}; use nix::{sys::signal, unistd};
use serde::{Deserialize, Serialize, Serializer}; use serde::{Deserialize, Serialize, Serializer};
use std::{ use std::{
collections::BTreeSet, collections::{BTreeMap, BTreeSet},
mem, fs, mem,
sync::atomic::{AtomicBool, Ordering}, sync::atomic::{AtomicBool, Ordering},
thread::{self, JoinHandle, Scope, ScopedJoinHandle}, thread::{self, JoinHandle, Scope, ScopedJoinHandle},
time::Duration, time::Duration,
}; };
use sysinfo::{Pid, System}; use sysinfo::{Pid, System};
use tracing::warn;
static REALTIME_MODE: AtomicBool = AtomicBool::new(true); static REALTIME_MODE: AtomicBool = AtomicBool::new(true);
...@@ -22,6 +23,10 @@ pub fn set_simulated() { ...@@ -22,6 +23,10 @@ pub fn set_simulated() {
REALTIME_MODE.store(false, Ordering::Relaxed); REALTIME_MODE.store(false, Ordering::Relaxed);
} }
fn is_simulated() -> bool {
REALTIME_MODE.load(Ordering::Relaxed)
}
/// A thread builder object, similar to [`thread::Builder`] but with real-time capabilities /// A thread builder object, similar to [`thread::Builder`] but with real-time capabilities
/// ///
/// Warning: works on Linux systems only /// Warning: works on Linux systems only
...@@ -464,7 +469,7 @@ fn thread_init_external( ...@@ -464,7 +469,7 @@ fn thread_init_external(
} }
fn apply_thread_params(tid: libc::c_int, params: &RTParams) -> Result<()> { fn apply_thread_params(tid: libc::c_int, params: &RTParams) -> Result<()> {
if !REALTIME_MODE.load(Ordering::Relaxed) { if !is_simulated() {
return Ok(()); return Ok(());
} }
if !params.cpu_ids.is_empty() { if !params.cpu_ids.is_empty() {
...@@ -589,3 +594,59 @@ fn get_child_pids_recursive(pid: Pid, sys: &System, to: &mut BTreeSet<Pid>) { ...@@ -589,3 +594,59 @@ fn get_child_pids_recursive(pid: Pid, sys: &System, to: &mut BTreeSet<Pid>) {
}; };
} }
} }
/// Configure kernel parameters (global) while the process is running. Does nothing in simulated
/// mode
///
/// Example:
///
/// ```rust,no_run
/// use roboplc::thread_rt::KernelConfig;
///
/// let _kernel_config = KernelConfig::new().set("sched_rt_runtime_us", -1)
/// .apply()
/// .expect("Unable to set kernel config");
/// // some code
/// // kernel config is restored at the end of the scope
/// ```
#[derive(Default)]
pub struct KernelConfig {
values: BTreeMap<&'static str, String>,
prev_values: BTreeMap<&'static str, String>,
}
impl KernelConfig {
pub fn new() -> Self {
Self::default()
}
pub fn set<V: fmt::Display>(mut self, key: &'static str, value: V) -> Self {
self.values.insert(key, value.to_string());
self
}
pub fn apply(mut self) -> Result<KernelConfigGuard> {
if is_simulated() {
for (key, value) in &self.values {
let prev_value = fs::read_to_string(format!("/proc/sys/kernel/{}", key))?;
self.prev_values.insert(key, prev_value);
fs::write(format!("/proc/sys/kernel/{}", key), value)?;
}
}
Ok(KernelConfigGuard { config: self })
}
}
pub struct KernelConfigGuard {
config: KernelConfig,
}
impl Drop for KernelConfigGuard {
fn drop(&mut self) {
if is_simulated() {
for (key, value) in &self.config.prev_values {
if let Err(error) = fs::write(format!("/proc/sys/kernel/{}", key), value) {
warn!(key, value, %error, "Failed to restore kernel config");
}
}
}
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论