You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
3.1 KiB
Rust

use lazy_static::lazy_static;
#[derive(Copy, Clone, Debug)]
pub struct Cpu {
pub id: usize,
pub package: usize,
pub die: usize,
pub core: usize,
pub layer_0: Option<usize>,
pub layer_1: Option<usize>,
pub layer_2: Option<usize>,
pub layer_3: Option<usize>,
}
lazy_static! {
static ref CPUS: Box<[Cpu]> = get_cpus().into_boxed_slice();
static ref CPU_LIST: CpuList = CpuList { list: &*CPUS };
}
pub fn get_cpus() -> Vec<Cpu> {
if cfg!(target_os = "linux") {
return crate::cpu_list::linux::get_cpus();
} else {
unimplemented!();
}
}
#[derive(Copy, Clone, Debug)]
pub struct CpuList {
list: &'static [Cpu],
}
impl CpuList {
pub fn _get() -> CpuList {
return *CPU_LIST;
}
pub fn _amount() -> usize {
CPU_LIST.len()
}
pub fn _load() -> CpuListOwned {
CpuListOwned { list: get_cpus() }
}
pub fn adjacent(amount: usize) -> Option<&'static [Cpu]> {
CPU_LIST.get_adjacent(amount)
}
pub fn len(&self) -> usize {
self.list.len()
}
pub fn _as_slice(&self) -> &[Cpu] {
self.list
}
pub fn get_adjacent(&self, amount: usize) -> Option<&[Cpu]> {
if self.len() < amount {
None
} else {
Some(&self.list[..amount])
}
}
}
#[derive(Clone, Debug)]
pub struct CpuListOwned {
list: Vec<Cpu>,
}
impl CpuListOwned {}
#[cfg(target_os = "linux")]
mod linux {
use crate::cpu_list::Cpu;
use std::fs::read_to_string;
use std::str::FromStr;
pub fn get_cpus() -> Vec<Cpu> {
let cpu = std::fs::read_dir("/sys/devices/system/cpu")
.expect("Failed to read /sys/devices/system/cpu, no /sys mounted?");
let mut cpus = vec![];
for cpu_dir in cpu {
let cpu_dir = cpu_dir.unwrap();
let file_name = cpu_dir.file_name();
let cpu_name = file_name.to_str().unwrap();
if cpu_name.starts_with("cpu") && cpu_name[3..].chars().all(|x| x.is_ascii_digit()) {
let cpu_id = usize::from_str(&cpu_name[3..]).unwrap();
let topology = cpu_dir.path();
let read_id = |name: &str| -> Option<usize> {
let mut path = topology.clone();
path.push(name);
let id_str = read_to_string(&path).ok()?;
usize::from_str(id_str.trim_end()).ok()
};
cpus.push(Cpu {
id: cpu_id,
package: read_id("topology/physical_package_id").unwrap(),
die: read_id("topology/die_id").unwrap(),
core: read_id("topology/core_id").unwrap(),
layer_0: read_id("cache/index0/id"),
layer_1: read_id("cache/index1/id"),
layer_2: read_id("cache/index2/id"),
layer_3: read_id("cache/index3/id"),
})
}
}
cpus.sort_by_key(|x| {
(
x.package, x.die, x.layer_3, x.layer_2, x.layer_1, x.layer_0, x.core, x.id,
)
});
cpus
}
}