use std::os::unix::ffi::OsStrExt;
use std::fs;
use std::io;
use std::str;
use std::collections::HashSet;
pub fn physical_count() -> io::Result<u64> {
cpuinfo().or_else(|_| topology())
}
fn cpuinfo() -> io::Result<u64> {
let content = fs::read_to_string("/proc/cpuinfo")?;
for line in content.lines() {
if line.starts_with("cpu cores") {
let num = &line[line.len()-1 ..];
if let Ok(num) = num.parse::<u64>() {
return Ok(num)
}
}
}
Ok(0)
}
fn topology() -> io::Result<u64> {
let mut acc = HashSet::<u64>::new();
let dirs = fs::read_dir("/sys/devices/system/cpu/")?;
for dir in dirs {
let dir = dir?;
let path = dir.path();
if let Some(file_name) = path.file_name() {
if file_name.as_bytes().starts_with(b"cpu") {
let core_id = unsafe { str::from_utf8_unchecked(&file_name.as_bytes()[3..]) };
if let Ok(_) = core_id.parse::<u64>() {
let path = path.join("topology/core_id");
let content = fs::read_to_string(path)?;
if let Ok(cpu_id) = content.trim().parse::<u64>() {
acc.insert(cpu_id);
}
}
}
}
}
Ok(acc.len() as u64)
}