lscpu
: Read CPU count from sysfs
, add freq_boost status to output
This commit is contained in:
@ -7,7 +7,6 @@ use clap::{crate_version, Arg, ArgAction, Command};
|
||||
use regex::RegexBuilder;
|
||||
use serde::Serialize;
|
||||
use std::{cmp, fs};
|
||||
use sysinfo::System;
|
||||
use uucore::{error::UResult, format_usage, help_about, help_usage};
|
||||
|
||||
mod options {
|
||||
@ -72,8 +71,6 @@ struct OutputOptions {
|
||||
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
let matches: clap::ArgMatches = uu_app().try_get_matches_from(args)?;
|
||||
|
||||
let system = System::new_all();
|
||||
|
||||
let output_opts = OutputOptions {
|
||||
_hex: matches.get_flag(options::HEX),
|
||||
json: matches.get_flag(options::JSON),
|
||||
@ -91,18 +88,16 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
arch_info.add_child(CpuInfo::new("Address sizes", &addr_sizes, None))
|
||||
}
|
||||
|
||||
if let Ok(byte_order) = fs::read_to_string("/sys/kernel/cpu_byteorder") {
|
||||
match byte_order.trim() {
|
||||
"big" => arch_info.add_child(CpuInfo::new("Byte Order", "Big Endian", None)),
|
||||
"little" => arch_info.add_child(CpuInfo::new("Byte Order", "Little Endian", None)),
|
||||
_ => eprintln!("Unrecognised Byte Order: {}", byte_order),
|
||||
}
|
||||
if let Some(byte_order) = sysfs::read_cpu_byte_order() {
|
||||
arch_info.add_child(CpuInfo::new("Byte Order", byte_order, None));
|
||||
}
|
||||
|
||||
let cpu_topology = sysfs::read_cpu_topology();
|
||||
|
||||
cpu_infos.push(arch_info);
|
||||
cpu_infos.push(CpuInfo::new(
|
||||
"CPU(s)",
|
||||
&format!("{}", system.cpus().len()),
|
||||
&format!("{}", cpu_topology.cpus.len()),
|
||||
None,
|
||||
));
|
||||
|
||||
@ -123,6 +118,15 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
model_name_info.add_child(CpuInfo::new("Model", &model, None));
|
||||
}
|
||||
|
||||
if let Some(freq_boost_enabled) = sysfs::read_freq_boost_state() {
|
||||
let s = if freq_boost_enabled {
|
||||
"enabled"
|
||||
} else {
|
||||
"disabled"
|
||||
};
|
||||
model_name_info.add_child(CpuInfo::new("Frequency boost", s, None));
|
||||
}
|
||||
|
||||
vendor_info.add_child(model_name_info);
|
||||
}
|
||||
cpu_infos.push(vendor_info);
|
||||
@ -211,6 +215,8 @@ fn find_cpuinfo_value(contents: &str, key: &str) -> Option<String> {
|
||||
value
|
||||
}
|
||||
|
||||
// TODO: This is non-exhaustive and assumes that compile-time arch is the same as runtime
|
||||
// This is not always guaranteed to be the case, ie. you can run a x86 binary on a x86_64 machine
|
||||
fn get_architecture() -> String {
|
||||
if cfg!(target_arch = "x86") {
|
||||
"x86".to_string()
|
||||
|
@ -5,6 +5,60 @@ pub struct CpuVulnerability {
|
||||
pub mitigation: String,
|
||||
}
|
||||
|
||||
pub struct CpuTopology {
|
||||
pub cpus: Vec<Cpu>,
|
||||
}
|
||||
|
||||
pub struct Cpu {
|
||||
_index: usize,
|
||||
_caches: Vec<CpuCache>,
|
||||
}
|
||||
|
||||
pub struct CpuCache {
|
||||
_index: usize,
|
||||
_typ: String,
|
||||
_level: String,
|
||||
_size: String,
|
||||
}
|
||||
|
||||
// TODO: This should go through each CPU in sysfs and calculate things such as cache sizes and physical topology
|
||||
// For now it just returns a list of CPUs which are enabled
|
||||
pub fn read_cpu_topology() -> CpuTopology {
|
||||
let mut out: Vec<Cpu> = vec![];
|
||||
|
||||
// NOTE: All examples I could find was where this file contains a CPU index range in the form of `<start>-<end>`
|
||||
// Theoretically, there might be a situation where some cores are disabled, so that `enabled` cannot be represented
|
||||
// as a continuous range. For now we just assume it's always `X-Y` and use those as our bounds to read CPU information
|
||||
let enabled_cpus = match fs::read_to_string("/sys/devices/system/cpu/enabled") {
|
||||
Ok(content) => {
|
||||
let parts: Vec<_> = content
|
||||
.trim()
|
||||
.split("-")
|
||||
.flat_map(|part| part.parse::<usize>())
|
||||
.collect();
|
||||
assert_eq!(parts.len(), 2);
|
||||
(parts[0], parts[1])
|
||||
}
|
||||
Err(e) => panic!("Could not read sysfs: {}", e),
|
||||
};
|
||||
|
||||
for cpu_index in enabled_cpus.0..(enabled_cpus.1 + 1) {
|
||||
out.push(Cpu {
|
||||
_index: cpu_index,
|
||||
_caches: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
CpuTopology { cpus: out }
|
||||
}
|
||||
|
||||
pub fn read_freq_boost_state() -> Option<bool> {
|
||||
match fs::read_to_string("/sys/devices/system/cpu/cpufreq/boost") {
|
||||
Ok(content) => Some(content.trim() == "1"),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_cpu_vulnerabilities() -> Vec<CpuVulnerability> {
|
||||
let mut out: Vec<CpuVulnerability> = vec![];
|
||||
|
||||
@ -31,3 +85,14 @@ pub fn read_cpu_vulnerabilities() -> Vec<CpuVulnerability> {
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
pub fn read_cpu_byte_order() -> Option<&'static str> {
|
||||
if let Ok(byte_order) = fs::read_to_string("/sys/kernel/cpu_byteorder") {
|
||||
match byte_order.trim() {
|
||||
"big" => return Some("Big Endian"),
|
||||
"little" => return Some("Little Endian"),
|
||||
_ => eprintln!("Unrecognised Byte Order: {}", byte_order),
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
Reference in New Issue
Block a user