mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-11 13:40:19 +08:00
143 lines
4.3 KiB
Rust
143 lines
4.3 KiB
Rust
// Runtime sampling is shared by standalone load tools and integration tests.
|
|
use std::time::{Instant, SystemTime, UNIX_EPOCH};
|
|
|
|
use serde::Serialize;
|
|
use sysinfo::{get_current_pid, Pid, ProcessesToUpdate, System};
|
|
|
|
#[derive(Debug, Clone, Copy, Serialize, PartialEq, Eq)]
|
|
pub struct BenchmarkRuntimeSnapshot {
|
|
pub sampled_at_unix_secs: u64,
|
|
pub elapsed_ms: u64,
|
|
pub system_cpu_usage_basis_points: u64,
|
|
pub process_cpu_usage_basis_points: u64,
|
|
pub memory_total_bytes: u64,
|
|
pub memory_used_bytes: u64,
|
|
pub memory_available_bytes: u64,
|
|
pub memory_used_basis_points: u64,
|
|
pub process_memory_bytes: u64,
|
|
pub process_virtual_memory_bytes: u64,
|
|
pub process_memory_basis_points: u64,
|
|
pub fd_open_count: u64,
|
|
pub fd_limit: u64,
|
|
}
|
|
|
|
pub struct BenchmarkRuntimeSampler {
|
|
started_at: Instant,
|
|
system: System,
|
|
current_pid: Option<Pid>,
|
|
}
|
|
|
|
impl BenchmarkRuntimeSampler {
|
|
pub fn new() -> Self {
|
|
let mut system = System::new_all();
|
|
let current_pid = get_current_pid().ok();
|
|
if let Some(pid) = current_pid {
|
|
system.refresh_processes(ProcessesToUpdate::Some(&[pid]), true);
|
|
}
|
|
system.refresh_cpu_usage();
|
|
system.refresh_memory();
|
|
Self {
|
|
started_at: Instant::now(),
|
|
system,
|
|
current_pid,
|
|
}
|
|
}
|
|
|
|
pub fn snapshot(&mut self) -> BenchmarkRuntimeSnapshot {
|
|
self.system.refresh_cpu_usage();
|
|
self.system.refresh_memory();
|
|
if let Some(pid) = self.current_pid {
|
|
self.system
|
|
.refresh_processes(ProcessesToUpdate::Some(&[pid]), true);
|
|
}
|
|
|
|
let memory_total_bytes = self.system.total_memory();
|
|
let memory_used_bytes = self.system.used_memory();
|
|
let memory_available_bytes = self.system.available_memory();
|
|
let (process_cpu_usage_basis_points, process_memory_bytes, process_virtual_memory_bytes) =
|
|
self.current_pid
|
|
.and_then(|pid| self.system.process(pid))
|
|
.map(|process| {
|
|
(
|
|
percent_to_basis_points(process.cpu_usage() as f64),
|
|
process.memory(),
|
|
process.virtual_memory(),
|
|
)
|
|
})
|
|
.unwrap_or((0, 0, 0));
|
|
|
|
BenchmarkRuntimeSnapshot {
|
|
sampled_at_unix_secs: current_unix_secs(),
|
|
elapsed_ms: self.started_at.elapsed().as_millis() as u64,
|
|
system_cpu_usage_basis_points: percent_to_basis_points(
|
|
self.system.global_cpu_usage() as f64
|
|
),
|
|
process_cpu_usage_basis_points,
|
|
memory_total_bytes,
|
|
memory_used_bytes,
|
|
memory_available_bytes,
|
|
memory_used_basis_points: ratio_to_basis_points(memory_used_bytes, memory_total_bytes),
|
|
process_memory_bytes,
|
|
process_virtual_memory_bytes,
|
|
process_memory_basis_points: ratio_to_basis_points(
|
|
process_memory_bytes,
|
|
memory_total_bytes,
|
|
),
|
|
fd_open_count: open_file_descriptors().unwrap_or(0),
|
|
fd_limit: file_descriptor_limit(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for BenchmarkRuntimeSampler {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
fn current_unix_secs() -> u64 {
|
|
SystemTime::now()
|
|
.duration_since(UNIX_EPOCH)
|
|
.map(|duration| duration.as_secs())
|
|
.unwrap_or(0)
|
|
}
|
|
|
|
fn percent_to_basis_points(value: f64) -> u64 {
|
|
if !value.is_finite() || value.is_sign_negative() {
|
|
0
|
|
} else {
|
|
(value * 100.0).round().clamp(0.0, u64::MAX as f64) as u64
|
|
}
|
|
}
|
|
|
|
fn ratio_to_basis_points(value: u64, total: u64) -> u64 {
|
|
value.saturating_mul(10_000).checked_div(total).unwrap_or(0)
|
|
}
|
|
|
|
fn open_file_descriptors() -> Option<u64> {
|
|
#[cfg(unix)]
|
|
{
|
|
for dir in ["/proc/self/fd", "/dev/fd"] {
|
|
if let Ok(entries) = std::fs::read_dir(dir) {
|
|
return Some(entries.count() as u64);
|
|
}
|
|
}
|
|
}
|
|
None
|
|
}
|
|
|
|
fn file_descriptor_limit() -> u64 {
|
|
#[cfg(unix)]
|
|
{
|
|
let mut limit = libc::rlimit {
|
|
rlim_cur: 0,
|
|
rlim_max: 0,
|
|
};
|
|
let result = unsafe { libc::getrlimit(libc::RLIMIT_NOFILE, &mut limit) };
|
|
if result == 0 {
|
|
return limit.rlim_cur;
|
|
}
|
|
}
|
|
0
|
|
}
|