Files
ember-tune-rs/src/load/mod.rs

75 lines
1.8 KiB
Rust

use anyhow::Result;
use std::process::Child;
use std::time::{Duration, Instant};
use std::thread;
pub trait Workload: Send + Sync {
fn start(&mut self, threads: usize, load_percent: usize) -> Result<()>;
fn stop(&mut self) -> Result<()>;
fn get_throughput(&self) -> Result<f64>;
}
pub struct StressNg {
child: Option<Child>,
}
impl StressNg {
pub fn new() -> Self {
Self { child: None }
}
}
impl Workload for StressNg {
fn start(&mut self, threads: usize, load_percent: usize) -> Result<()> {
self.stop()?;
let child = std::process::Command::new("stress-ng")
.args([
"--cpu", &threads.to_string(),
"--cpu-load", &load_percent.to_string(),
"--quiet"
])
.spawn()?;
self.child = Some(child);
Ok(())
}
fn stop(&mut self) -> Result<()> {
if let Some(mut child) = self.child.take() {
// Try SIGTERM first
#[cfg(unix)]
{
use libc::{kill, SIGTERM};
unsafe { kill(child.id() as i32, SIGTERM); }
}
let start = Instant::now();
let mut exited = false;
while start.elapsed() < Duration::from_secs(2) {
if let Ok(Some(_)) = child.try_wait() {
exited = true;
break;
}
thread::sleep(Duration::from_millis(100));
}
if !exited {
let _ = child.kill();
let _ = child.wait();
}
}
Ok(())
}
fn get_throughput(&self) -> Result<f64> {
Ok(0.0)
}
}
impl Drop for StressNg {
fn drop(&mut self) {
let _ = self.stop();
}
}