unibar/src/bar_modules/bar_module_cpu.rs
Mahesh Asolkar 79e1a5956e
Clear data before new bar display iteration
This makes sure that data displayed is always fresh
2025-06-07 21:19:02 -07:00

168 lines
4.9 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use std::fs::File;
use std::io::{self, BufRead, BufReader};
use std::thread;
use std::time::Duration;
use crate::common;
use crate::bar_modules;
#[derive(Debug, Default, Clone)]
struct CpuTimes {
user: u64,
nice: u64,
system: u64,
idle: u64,
iowait: u64,
irq: u64,
softirq: u64,
steal: u64,
guest: u64,
guest_nice: u64,
}
impl CpuTimes {
pub fn new() -> Self {
CpuTimes {
user: 0,
nice: 0,
system: 0,
idle: 0,
iowait: 0,
irq: 0,
softirq: 0,
steal: 0,
guest: 0,
guest_nice: 0
}
}
fn total(&self) -> u64 {
self.user
+ self.nice
+ self.system
+ self.idle
+ self.iowait
+ self.irq
+ self.softirq
+ self.steal
+ self.guest
+ self.guest_nice
}
fn idle(&self) -> u64 {
self.idle + self.iowait
}
}
#[derive(Clone)]
pub struct UnibarModuleCpu {
opts: common::AppOptions,
cpu_times_sample_1: CpuTimes,
cpu_times_sample_2: CpuTimes,
}
impl UnibarModuleCpu {
// --------------------
pub fn new(o :common::AppOptions) -> Self {
UnibarModuleCpu {
opts: o,
cpu_times_sample_1: CpuTimes::new(),
cpu_times_sample_2: CpuTimes::new(),
}
}
// --------------------
// cpu 242109 7 60985 6538626 8344 39138 9647 0 0 0
// * user time spent in user mode
// * nice time spent processing nice processes in user mode
// * system time spent executing kernel code
// * idle time spent idle
// * iowait time spent waiting for I/O
// * irq time spent servicing interrupts
// * softirq time spent servicing software interrupts
// * steal time stolen from a virtual machine
// * guest time spent running a virtual CPU for a guest operating system
// * guest_nice time spent running a virtual CPU for a “niced” guest operating system
fn read_cpu_times(&self) -> io::Result<CpuTimes> {
let file = File::open("/proc/stat")?;
let reader = BufReader::new(file);
for line in reader.lines() {
let line = line?;
if line.starts_with("cpu ") {
let fields: Vec<u64> = line.split_whitespace().skip(1).map(|s| s.parse().unwrap_or(0)).collect();
if fields.len() >= 8 {
return Ok(CpuTimes {
user: fields[0],
nice: fields[1],
system: fields[2],
idle: fields[3],
iowait: fields[4],
irq: fields[5],
softirq: fields[6],
steal: fields[7],
guest: if fields.len() > 8 { fields[8] } else { 0 },
guest_nice: if fields.len() > 9 { fields[9] } else { 0 },
});
}
}
}
Err(io::Error::new(io::ErrorKind::InvalidData, "Could not find cpu line in /proc/stat"))
}
}
impl bar_modules::BarModuleActions for UnibarModuleCpu {
// --------------------
fn clear(&mut self) {
self.cpu_times_sample_1 = CpuTimes::new();
self.cpu_times_sample_2 = CpuTimes::new();
}
// --------------------
fn generate_data(&mut self) {
self.cpu_times_sample_1 = self.read_cpu_times().expect("Trouble getting CPU times sample 1");
thread::sleep(Duration::from_millis(500));
self.cpu_times_sample_2 = self.read_cpu_times().expect("Trouble getting CPU times sample 2");
if self.opts.debug {
println!("-----> CPU times sample 1 - {:#?}", self.cpu_times_sample_1);
println!("-----> CPU times sample 2 - {:#?}", self.cpu_times_sample_2);
}
}
// --------------------
fn get_content(&self) -> String {
let sample_1_total = self.cpu_times_sample_1.total();
let sample_2_total = self.cpu_times_sample_2.total();
let sample_1_idle = self.cpu_times_sample_1.idle();
let sample_2_idle = self.cpu_times_sample_2.idle();
let total_diff = sample_2_total - sample_1_total;
let idle_diff = sample_2_idle - sample_1_idle;
if total_diff > 0 {
let cpu_usage = (1.0 - (idle_diff as f64 / total_diff as f64)) * 100.0;
return format!("{}%", cpu_usage.ceil() as i32);
} else {
return format!("CPU?");
}
}
// --------------------
fn get_icon(&self) -> String {
return "💻".to_string();
}
}
impl bar_modules::BarModuleDebug for UnibarModuleCpu {
// --------------------
fn post_debug(&self) {
}
}