#![allow(unused)] use std::fs; use std::io; use std::path::Path; /// Check if RAPL sysfs interface is available pub fn is_rapl_available() -> bool { Path::new("/sys/class/powercap/intel-rapl/intel-rapl:0").exists() } /// Read current package energy counter value in joules pub fn read_package_energy() -> io::Result { let energy_path = "/sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj"; let energy_str = fs::read_to_string(energy_path)?; let energy_uj = energy_str .trim() .parse::() .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; // Convert from microjoules to joules Ok(energy_uj as f64 / 1_000_000.0) } /// Read energy counter for a specific domain (core, uncore, dram) pub fn read_domain_energy(domain_idx: usize) -> io::Result { let domain_path = format!( "/sys/class/powercap/intel-rapl/intel-rapl:0:{}/energy_uj", domain_idx ); if !Path::new(&domain_path).exists() { return Err(io::Error::new( io::ErrorKind::NotFound, format!("Domain {} not available", domain_idx), )); } let energy_str = fs::read_to_string(domain_path)?; let energy_uj = energy_str .trim() .parse::() .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; // Convert from microjoules to joules Ok(energy_uj as f64 / 1_000_000.0) } /// Get domain name pub fn get_domain_name(domain_idx: usize) -> io::Result { let name_path = format!( "/sys/class/powercap/intel-rapl/intel-rapl:0:{}/name", domain_idx ); if !Path::new(&name_path).exists() { return Err(io::Error::new( io::ErrorKind::NotFound, format!("Domain {} not available", domain_idx), )); } let name = fs::read_to_string(name_path)?; Ok(name.trim().to_string()) } /// List all available RAPL domains with their indices pub fn list_domains() -> io::Result> { let base_path = "/sys/class/powercap/intel-rapl/intel-rapl:0"; let mut domains = Vec::new(); // Add package domain (always index 0) let pkg_name_path = format!("{}/name", base_path); let pkg_name = fs::read_to_string(pkg_name_path)?.trim().to_string(); domains.push((0, pkg_name)); // Check for subdomains for i in 0..10 { let domain_path = format!("{}/intel-rapl:0:{}", base_path, i); if Path::new(&domain_path).exists() { let name_path = format!("{}/name", domain_path); if let Ok(name) = fs::read_to_string(name_path) { domains.push((i, name.trim().to_string())); } } else { break; } } Ok(domains) }