1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
#![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<f64> {
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::<u64>()
.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<f64> {
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::<u64>()
.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<String> {
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<Vec<(usize, String)>> {
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)
}
|