summaryrefslogtreecommitdiffstats
path: root/vendor/sysinfo/src/linux
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:59:24 +0000
commit023939b627b7dc93b01471f7d41fb8553ddb4ffa (patch)
tree60fc59477c605c72b0a1051409062ddecc43f877 /vendor/sysinfo/src/linux
parentAdding debian version 1.72.1+dfsg1-1. (diff)
downloadrustc-023939b627b7dc93b01471f7d41fb8553ddb4ffa.tar.xz
rustc-023939b627b7dc93b01471f7d41fb8553ddb4ffa.zip
Merging upstream version 1.73.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/sysinfo/src/linux')
-rw-r--r--vendor/sysinfo/src/linux/component.rs12
-rw-r--r--vendor/sysinfo/src/linux/cpu.rs474
-rw-r--r--vendor/sysinfo/src/linux/disk.rs24
-rw-r--r--vendor/sysinfo/src/linux/network.rs14
-rw-r--r--vendor/sysinfo/src/linux/process.rs173
-rw-r--r--vendor/sysinfo/src/linux/system.rs58
-rw-r--r--vendor/sysinfo/src/linux/utils.rs4
7 files changed, 508 insertions, 251 deletions
diff --git a/vendor/sysinfo/src/linux/component.rs b/vendor/sysinfo/src/linux/component.rs
index 7815103b4..3286829f4 100644
--- a/vendor/sysinfo/src/linux/component.rs
+++ b/vendor/sysinfo/src/linux/component.rs
@@ -31,7 +31,7 @@ pub struct Component {
/// - Read in: `temp[1-*]_input`.
/// - Unit: read as millidegree Celsius converted to Celsius.
temperature: Option<f32>,
- /// Maximum value computed by sysinfo
+ /// Maximum value computed by `sysinfo`.
max: Option<f32>,
/// Max threshold provided by the chip/kernel
/// - Read in:`temp[1-*]_max`
@@ -60,7 +60,7 @@ pub struct Component {
sensor_type: Option<TermalSensorType>,
/// Component Label
///
- /// For formating detail see `Component::label` function docstring.
+ /// For formatting detail see `Component::label` function docstring.
///
/// ## Linux implementation details
///
@@ -89,7 +89,7 @@ pub struct Component {
/// File to read current temperature shall be `temp[1-*]_input`
/// It may be absent but we don't continue if absent.
input_file: Option<PathBuf>,
- /// `temp[1-*]_highest file` to read if disponnible highest value.
+ /// `temp[1-*]_highest file` to read if available highest value.
highest_file: Option<PathBuf>,
}
@@ -132,14 +132,14 @@ fn get_temperature_from_file(file: &Path) -> Option<f32> {
convert_temp_celsius(temp)
}
-/// Takes a raw temperature in mili-celsius and convert it to celsius
+/// Takes a raw temperature in mili-celsius and convert it to celsius.
#[inline]
fn convert_temp_celsius(temp: Option<i32>) -> Option<f32> {
temp.map(|n| (n as f32) / 1000f32)
}
/// Information about thermal sensor. It may be unavailable as it's
-/// kernel module and chip dependant.
+/// kernel module and chip dependent.
enum TermalSensorType {
/// 1: CPU embedded diode
CPUEmbeddedDiode,
@@ -228,7 +228,7 @@ impl Component {
/// - Optional: max threshold value defined in `tempN_max`
/// - Optional: critical threshold value defined in `tempN_crit`
///
- /// Where `N` is a u32 associated to a sensor like `temp1_max`, `temp1_input`.
+ /// Where `N` is a `u32` associated to a sensor like `temp1_max`, `temp1_input`.
///
/// ## Doc to Linux kernel API.
///
diff --git a/vendor/sysinfo/src/linux/cpu.rs b/vendor/sysinfo/src/linux/cpu.rs
index 103f5362a..d99b325c1 100644
--- a/vendor/sysinfo/src/linux/cpu.rs
+++ b/vendor/sysinfo/src/linux/cpu.rs
@@ -5,9 +5,10 @@
use std::collections::HashSet;
use std::fs::File;
use std::io::{BufRead, BufReader, Read};
+use std::time::Instant;
use crate::sys::utils::to_u64;
-use crate::{CpuExt, CpuRefreshKind};
+use crate::{CpuExt, CpuRefreshKind, SystemExt};
macro_rules! to_str {
($e:expr) => {
@@ -24,6 +25,8 @@ pub(crate) struct CpusWrapper {
/// For example when running `refresh_all` or `refresh_specifics`.
need_cpus_update: bool,
got_cpu_frequency: bool,
+ /// This field is needed to prevent updating when not enough time passed since last update.
+ last_update: Option<Instant>,
}
impl CpusWrapper {
@@ -48,6 +51,7 @@ impl CpusWrapper {
cpus: Vec::with_capacity(4),
need_cpus_update: true,
got_cpu_frequency: false,
+ last_update: None,
}
}
@@ -62,90 +66,101 @@ impl CpusWrapper {
}
pub(crate) fn refresh(&mut self, only_update_global_cpu: bool, refresh_kind: CpuRefreshKind) {
- let f = match File::open("/proc/stat") {
- Ok(f) => f,
- Err(_e) => {
- sysinfo_debug!("failed to retrieve CPU information: {:?}", _e);
- return;
- }
- };
- let buf = BufReader::new(f);
+ let need_cpu_usage_update = self
+ .last_update
+ .map(|last_update| last_update.elapsed() > crate::System::MINIMUM_CPU_UPDATE_INTERVAL)
+ .unwrap_or(true);
- self.need_cpus_update = false;
- let mut i: usize = 0;
let first = self.cpus.is_empty();
- let mut it = buf.split(b'\n');
let (vendor_id, brand) = if first {
get_vendor_id_and_brand()
} else {
(String::new(), String::new())
};
- if first || refresh_kind.cpu_usage() {
- if let Some(Ok(line)) = it.next() {
- if &line[..4] != b"cpu " {
+ // If the last CPU usage update is too close (less than `MINIMUM_CPU_UPDATE_INTERVAL`),
+ // we don't want to update CPUs times.
+ if need_cpu_usage_update {
+ self.last_update = Some(Instant::now());
+ let f = match File::open("/proc/stat") {
+ Ok(f) => f,
+ Err(_e) => {
+ sysinfo_debug!("failed to retrieve CPU information: {:?}", _e);
return;
}
- let mut parts = line.split(|x| *x == b' ').filter(|s| !s.is_empty());
- if first {
- self.global_cpu.name = to_str!(parts.next().unwrap_or(&[])).to_owned();
- } else {
- parts.next();
- }
- self.global_cpu.set(
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- );
- }
- if first || !only_update_global_cpu {
- while let Some(Ok(line)) = it.next() {
- if &line[..3] != b"cpu" {
- break;
- }
+ };
+ let buf = BufReader::new(f);
+
+ self.need_cpus_update = false;
+ let mut i: usize = 0;
+ let mut it = buf.split(b'\n');
+ if first || refresh_kind.cpu_usage() {
+ if let Some(Ok(line)) = it.next() {
+ if &line[..4] != b"cpu " {
+ return;
+ }
let mut parts = line.split(|x| *x == b' ').filter(|s| !s.is_empty());
if first {
- self.cpus.push(Cpu::new_with_values(
- to_str!(parts.next().unwrap_or(&[])),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- 0,
- vendor_id.clone(),
- brand.clone(),
- ));
+ self.global_cpu.name = to_str!(parts.next().unwrap_or(&[])).to_owned();
} else {
- parts.next(); // we don't want the name again
- self.cpus[i].set(
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- parts.next().map(to_u64).unwrap_or(0),
- );
+ parts.next();
+ }
+ self.global_cpu.set(
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ );
+ }
+ if first || !only_update_global_cpu {
+ while let Some(Ok(line)) = it.next() {
+ if &line[..3] != b"cpu" {
+ break;
+ }
+
+ let mut parts = line.split(|x| *x == b' ').filter(|s| !s.is_empty());
+ if first {
+ self.cpus.push(Cpu::new_with_values(
+ to_str!(parts.next().unwrap_or(&[])),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ 0,
+ vendor_id.clone(),
+ brand.clone(),
+ ));
+ } else {
+ parts.next(); // we don't want the name again
+ self.cpus[i].set(
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ parts.next().map(to_u64).unwrap_or(0),
+ );
+ }
+
+ i += 1;
}
-
- i += 1;
}
}
}
@@ -219,8 +234,8 @@ pub(crate) struct CpuValues {
irq: u64,
softirq: u64,
steal: u64,
- _guest: u64,
- _guest_nice: u64,
+ guest: u64,
+ guest_nice: u64,
}
impl CpuValues {
@@ -235,44 +250,11 @@ impl CpuValues {
irq: 0,
softirq: 0,
steal: 0,
- _guest: 0,
- _guest_nice: 0,
- }
- }
-
- /// Creates a new instance of `CpuValues` with everything set to the corresponding argument.
- pub fn new_with_values(
- user: u64,
- nice: u64,
- system: u64,
- idle: u64,
- iowait: u64,
- irq: u64,
- softirq: u64,
- steal: u64,
- guest: u64,
- guest_nice: u64,
- ) -> CpuValues {
- CpuValues {
- user,
- nice,
- system,
- idle,
- iowait,
- irq,
- softirq,
- steal,
- _guest: guest,
- _guest_nice: guest_nice,
+ guest: 0,
+ guest_nice: 0,
}
}
- /*pub fn is_zero(&self) -> bool {
- self.user == 0 && self.nice == 0 && self.system == 0 && self.idle == 0 &&
- self.iowait == 0 && self.irq == 0 && self.softirq == 0 && self.steal == 0 &&
- self.guest == 0 && self.guest_nice == 0
- }*/
-
/// Sets the given argument to the corresponding fields.
pub fn set(
&mut self,
@@ -287,16 +269,18 @@ impl CpuValues {
guest: u64,
guest_nice: u64,
) {
- self.user = user;
- self.nice = nice;
+ // `guest` is already accounted in `user`.
+ self.user = user.saturating_sub(guest);
+ // `guest_nice` is already accounted in `nice`.
+ self.nice = nice.saturating_sub(guest_nice);
self.system = system;
self.idle = idle;
self.iowait = iowait;
self.irq = irq;
self.softirq = softirq;
self.steal = steal;
- self._guest = guest;
- self._guest_nice = guest_nice;
+ self.guest = guest;
+ self.guest_nice = guest_nice;
}
/// Returns work time.
@@ -306,16 +290,18 @@ impl CpuValues {
.saturating_add(self.system)
.saturating_add(self.irq)
.saturating_add(self.softirq)
- .saturating_add(self.steal)
}
/// Returns total time.
pub fn total_time(&self) -> u64 {
- // `guest` is already included in `user`
- // `guest_nice` is already included in `nice`
self.work_time()
.saturating_add(self.idle)
.saturating_add(self.iowait)
+ // `steal`, `guest` and `guest_nice` are only used if we want to account the "guest"
+ // into the computation.
+ .saturating_add(self.guest)
+ .saturating_add(self.guest_nice)
+ .saturating_add(self.steal)
}
}
@@ -349,12 +335,14 @@ impl Cpu {
vendor_id: String,
brand: String,
) -> Cpu {
+ let mut new_values = CpuValues::new();
+ new_values.set(
+ user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice,
+ );
Cpu {
name: name.to_owned(),
old_values: CpuValues::new(),
- new_values: CpuValues::new_with_values(
- user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice,
- ),
+ new_values,
cpu_usage: 0f32,
total_time: 0,
old_total_time: 0,
@@ -378,11 +366,11 @@ impl Cpu {
guest_nice: u64,
) {
macro_rules! min {
- ($a:expr, $b:expr) => {
+ ($a:expr, $b:expr, $def:expr) => {
if $a > $b {
($a - $b) as f32
} else {
- 1.
+ $def
}
};
}
@@ -392,8 +380,8 @@ impl Cpu {
);
self.total_time = self.new_values.total_time();
self.old_total_time = self.old_values.total_time();
- self.cpu_usage = min!(self.new_values.work_time(), self.old_values.work_time())
- / min!(self.total_time, self.old_total_time)
+ self.cpu_usage = min!(self.new_values.work_time(), self.old_values.work_time(), 0.)
+ / min!(self.total_time, self.old_total_time, 1.)
* 100.;
if self.cpu_usage > 100. {
self.cpu_usage = 100.; // to prevent the percentage to go above 100%
@@ -427,8 +415,7 @@ impl CpuExt for Cpu {
pub(crate) fn get_cpu_frequency(cpu_core_index: usize) -> u64 {
let mut s = String::new();
if File::open(format!(
- "/sys/devices/system/cpu/cpu{}/cpufreq/scaling_cur_freq",
- cpu_core_index
+ "/sys/devices/system/cpu/cpu{cpu_core_index}/cpufreq/scaling_cur_freq",
))
.and_then(|mut f| f.read_to_string(&mut s))
.is_ok()
@@ -517,6 +504,216 @@ pub(crate) fn get_physical_core_count() -> Option<usize> {
Some(core_ids_and_physical_ids.len())
}
+/// Obtain the implementer of this CPU core.
+///
+/// This has been obtained from util-linux's lscpu implementation, see
+/// https://github.com/util-linux/util-linux/blob/7076703b529d255600631306419cca1b48ab850a/sys-utils/lscpu-arm.c#L240
+///
+/// This list will have to be updated every time a new vendor appears, please keep it synchronized
+/// with util-linux and update the link above with the commit you have used.
+fn get_arm_implementer(implementer: u32) -> Option<&'static str> {
+ Some(match implementer {
+ 0x41 => "ARM",
+ 0x42 => "Broadcom",
+ 0x43 => "Cavium",
+ 0x44 => "DEC",
+ 0x46 => "FUJITSU",
+ 0x48 => "HiSilicon",
+ 0x49 => "Infineon",
+ 0x4d => "Motorola/Freescale",
+ 0x4e => "NVIDIA",
+ 0x50 => "APM",
+ 0x51 => "Qualcomm",
+ 0x53 => "Samsung",
+ 0x56 => "Marvell",
+ 0x61 => "Apple",
+ 0x66 => "Faraday",
+ 0x69 => "Intel",
+ 0x70 => "Phytium",
+ 0xc0 => "Ampere",
+ _ => return None,
+ })
+}
+
+/// Obtain the part of this CPU core.
+///
+/// This has been obtained from util-linux's lscpu implementation, see
+/// https://github.com/util-linux/util-linux/blob/7076703b529d255600631306419cca1b48ab850a/sys-utils/lscpu-arm.c#L34
+///
+/// This list will have to be updated every time a new core appears, please keep it synchronized
+/// with util-linux and update the link above with the commit you have used.
+fn get_arm_part(implementer: u32, part: u32) -> Option<&'static str> {
+ Some(match (implementer, part) {
+ // ARM
+ (0x41, 0x810) => "ARM810",
+ (0x41, 0x920) => "ARM920",
+ (0x41, 0x922) => "ARM922",
+ (0x41, 0x926) => "ARM926",
+ (0x41, 0x940) => "ARM940",
+ (0x41, 0x946) => "ARM946",
+ (0x41, 0x966) => "ARM966",
+ (0x41, 0xa20) => "ARM1020",
+ (0x41, 0xa22) => "ARM1022",
+ (0x41, 0xa26) => "ARM1026",
+ (0x41, 0xb02) => "ARM11 MPCore",
+ (0x41, 0xb36) => "ARM1136",
+ (0x41, 0xb56) => "ARM1156",
+ (0x41, 0xb76) => "ARM1176",
+ (0x41, 0xc05) => "Cortex-A5",
+ (0x41, 0xc07) => "Cortex-A7",
+ (0x41, 0xc08) => "Cortex-A8",
+ (0x41, 0xc09) => "Cortex-A9",
+ (0x41, 0xc0d) => "Cortex-A17", // Originally A12
+ (0x41, 0xc0f) => "Cortex-A15",
+ (0x41, 0xc0e) => "Cortex-A17",
+ (0x41, 0xc14) => "Cortex-R4",
+ (0x41, 0xc15) => "Cortex-R5",
+ (0x41, 0xc17) => "Cortex-R7",
+ (0x41, 0xc18) => "Cortex-R8",
+ (0x41, 0xc20) => "Cortex-M0",
+ (0x41, 0xc21) => "Cortex-M1",
+ (0x41, 0xc23) => "Cortex-M3",
+ (0x41, 0xc24) => "Cortex-M4",
+ (0x41, 0xc27) => "Cortex-M7",
+ (0x41, 0xc60) => "Cortex-M0+",
+ (0x41, 0xd01) => "Cortex-A32",
+ (0x41, 0xd02) => "Cortex-A34",
+ (0x41, 0xd03) => "Cortex-A53",
+ (0x41, 0xd04) => "Cortex-A35",
+ (0x41, 0xd05) => "Cortex-A55",
+ (0x41, 0xd06) => "Cortex-A65",
+ (0x41, 0xd07) => "Cortex-A57",
+ (0x41, 0xd08) => "Cortex-A72",
+ (0x41, 0xd09) => "Cortex-A73",
+ (0x41, 0xd0a) => "Cortex-A75",
+ (0x41, 0xd0b) => "Cortex-A76",
+ (0x41, 0xd0c) => "Neoverse-N1",
+ (0x41, 0xd0d) => "Cortex-A77",
+ (0x41, 0xd0e) => "Cortex-A76AE",
+ (0x41, 0xd13) => "Cortex-R52",
+ (0x41, 0xd20) => "Cortex-M23",
+ (0x41, 0xd21) => "Cortex-M33",
+ (0x41, 0xd40) => "Neoverse-V1",
+ (0x41, 0xd41) => "Cortex-A78",
+ (0x41, 0xd42) => "Cortex-A78AE",
+ (0x41, 0xd43) => "Cortex-A65AE",
+ (0x41, 0xd44) => "Cortex-X1",
+ (0x41, 0xd46) => "Cortex-A510",
+ (0x41, 0xd47) => "Cortex-A710",
+ (0x41, 0xd48) => "Cortex-X2",
+ (0x41, 0xd49) => "Neoverse-N2",
+ (0x41, 0xd4a) => "Neoverse-E1",
+ (0x41, 0xd4b) => "Cortex-A78C",
+ (0x41, 0xd4c) => "Cortex-X1C",
+ (0x41, 0xd4d) => "Cortex-A715",
+ (0x41, 0xd4e) => "Cortex-X3",
+
+ // Broadcom
+ (0x42, 0x00f) => "Brahma-B15",
+ (0x42, 0x100) => "Brahma-B53",
+ (0x42, 0x516) => "ThunderX2",
+
+ // Cavium
+ (0x43, 0x0a0) => "ThunderX",
+ (0x43, 0x0a1) => "ThunderX-88XX",
+ (0x43, 0x0a2) => "ThunderX-81XX",
+ (0x43, 0x0a3) => "ThunderX-83XX",
+ (0x43, 0x0af) => "ThunderX2-99xx",
+
+ // DEC
+ (0x44, 0xa10) => "SA110",
+ (0x44, 0xa11) => "SA1100",
+
+ // Fujitsu
+ (0x46, 0x001) => "A64FX",
+
+ // HiSilicon
+ (0x48, 0xd01) => "Kunpeng-920", // aka tsv110
+
+ // NVIDIA
+ (0x4e, 0x000) => "Denver",
+ (0x4e, 0x003) => "Denver 2",
+ (0x4e, 0x004) => "Carmel",
+
+ // APM
+ (0x50, 0x000) => "X-Gene",
+
+ // Qualcomm
+ (0x51, 0x00f) => "Scorpion",
+ (0x51, 0x02d) => "Scorpion",
+ (0x51, 0x04d) => "Krait",
+ (0x51, 0x06f) => "Krait",
+ (0x51, 0x201) => "Kryo",
+ (0x51, 0x205) => "Kryo",
+ (0x51, 0x211) => "Kryo",
+ (0x51, 0x800) => "Falkor-V1/Kryo",
+ (0x51, 0x801) => "Kryo-V2",
+ (0x51, 0x802) => "Kryo-3XX-Gold",
+ (0x51, 0x803) => "Kryo-3XX-Silver",
+ (0x51, 0x804) => "Kryo-4XX-Gold",
+ (0x51, 0x805) => "Kryo-4XX-Silver",
+ (0x51, 0xc00) => "Falkor",
+ (0x51, 0xc01) => "Saphira",
+
+ // Samsung
+ (0x53, 0x001) => "exynos-m1",
+
+ // Marvell
+ (0x56, 0x131) => "Feroceon-88FR131",
+ (0x56, 0x581) => "PJ4/PJ4b",
+ (0x56, 0x584) => "PJ4B-MP",
+
+ // Apple
+ (0x61, 0x020) => "Icestorm-A14",
+ (0x61, 0x021) => "Firestorm-A14",
+ (0x61, 0x022) => "Icestorm-M1",
+ (0x61, 0x023) => "Firestorm-M1",
+ (0x61, 0x024) => "Icestorm-M1-Pro",
+ (0x61, 0x025) => "Firestorm-M1-Pro",
+ (0x61, 0x028) => "Icestorm-M1-Max",
+ (0x61, 0x029) => "Firestorm-M1-Max",
+ (0x61, 0x030) => "Blizzard-A15",
+ (0x61, 0x031) => "Avalanche-A15",
+ (0x61, 0x032) => "Blizzard-M2",
+ (0x61, 0x033) => "Avalanche-M2",
+
+ // Faraday
+ (0x66, 0x526) => "FA526",
+ (0x66, 0x626) => "FA626",
+
+ // Intel
+ (0x69, 0x200) => "i80200",
+ (0x69, 0x210) => "PXA250A",
+ (0x69, 0x212) => "PXA210A",
+ (0x69, 0x242) => "i80321-400",
+ (0x69, 0x243) => "i80321-600",
+ (0x69, 0x290) => "PXA250B/PXA26x",
+ (0x69, 0x292) => "PXA210B",
+ (0x69, 0x2c2) => "i80321-400-B0",
+ (0x69, 0x2c3) => "i80321-600-B0",
+ (0x69, 0x2d0) => "PXA250C/PXA255/PXA26x",
+ (0x69, 0x2d2) => "PXA210C",
+ (0x69, 0x411) => "PXA27x",
+ (0x69, 0x41c) => "IPX425-533",
+ (0x69, 0x41d) => "IPX425-400",
+ (0x69, 0x41f) => "IPX425-266",
+ (0x69, 0x682) => "PXA32x",
+ (0x69, 0x683) => "PXA930/PXA935",
+ (0x69, 0x688) => "PXA30x",
+ (0x69, 0x689) => "PXA31x",
+ (0x69, 0xb11) => "SA1110",
+ (0x69, 0xc12) => "IPX1200",
+
+ // Phytium
+ (0x70, 0x660) => "FTC660",
+ (0x70, 0x661) => "FTC661",
+ (0x70, 0x662) => "FTC662",
+ (0x70, 0x663) => "FTC663",
+
+ _ => return None,
+ })
+}
+
/// Returns the brand/vendor string for the first CPU (which should be the same for all CPUs).
pub(crate) fn get_vendor_id_and_brand() -> (String, String) {
let mut s = String::new();
@@ -534,20 +731,49 @@ pub(crate) fn get_vendor_id_and_brand() -> (String, String) {
.unwrap_or_default()
}
+ fn get_hex_value(s: &str) -> u32 {
+ s.split(':')
+ .last()
+ .map(|x| x.trim())
+ .filter(|x| x.starts_with("0x"))
+ .map(|x| u32::from_str_radix(&x[2..], 16).unwrap())
+ .unwrap_or_default()
+ }
+
let mut vendor_id = None;
let mut brand = None;
+ let mut implementer = None;
+ let mut part = None;
for it in s.split('\n') {
if it.starts_with("vendor_id\t") {
vendor_id = Some(get_value(it));
} else if it.starts_with("model name\t") {
brand = Some(get_value(it));
+ } else if it.starts_with("CPU implementer\t") {
+ implementer = Some(get_hex_value(it));
+ } else if it.starts_with("CPU part\t") {
+ part = Some(get_hex_value(it));
} else {
continue;
}
- if brand.is_some() && vendor_id.is_some() {
+ if (brand.is_some() && vendor_id.is_some()) || (implementer.is_some() && part.is_some()) {
break;
}
}
+ if let (Some(implementer), Some(part)) = (implementer, part) {
+ vendor_id = get_arm_implementer(implementer).map(String::from);
+ // It's possible to "model name" even with an ARM CPU, so just in case we can't retrieve
+ // the brand from "CPU part", we will then use the value from "model name".
+ //
+ // Example from raspberry pi 3B+:
+ //
+ // ```
+ // model name : ARMv7 Processor rev 4 (v7l)
+ // CPU implementer : 0x41
+ // CPU part : 0xd03
+ // ```
+ brand = get_arm_part(implementer, part).map(String::from).or(brand);
+ }
(vendor_id.unwrap_or_default(), brand.unwrap_or_default())
}
diff --git a/vendor/sysinfo/src/linux/disk.rs b/vendor/sysinfo/src/linux/disk.rs
index 6d7fc083c..23871d57f 100644
--- a/vendor/sysinfo/src/linux/disk.rs
+++ b/vendor/sysinfo/src/linux/disk.rs
@@ -1,7 +1,7 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use crate::sys::utils::{get_all_data, to_cpath};
-use crate::{DiskExt, DiskType};
+use crate::{DiskExt, DiskKind};
use libc::statvfs;
use std::ffi::{OsStr, OsString};
@@ -19,7 +19,7 @@ macro_rules! cast {
#[doc = include_str!("../../md_doc/disk.md")]
#[derive(PartialEq, Eq)]
pub struct Disk {
- type_: DiskType,
+ type_: DiskKind,
device_name: OsString,
file_system: Vec<u8>,
mount_point: PathBuf,
@@ -29,7 +29,7 @@ pub struct Disk {
}
impl DiskExt for Disk {
- fn type_(&self) -> DiskType {
+ fn kind(&self) -> DiskKind {
self.type_
}
@@ -61,7 +61,7 @@ impl DiskExt for Disk {
unsafe {
let mut stat: statvfs = mem::zeroed();
let mount_point_cpath = to_cpath(&self.mount_point);
- if statvfs(mount_point_cpath.as_ptr() as *const _, &mut stat) == 0 {
+ if retry_eintr!(statvfs(mount_point_cpath.as_ptr() as *const _, &mut stat)) == 0 {
let tmp = cast!(stat.f_bsize).saturating_mul(cast!(stat.f_bavail));
self.available_space = cast!(tmp);
true
@@ -84,7 +84,7 @@ fn new_disk(
let mut available = 0;
unsafe {
let mut stat: statvfs = mem::zeroed();
- if statvfs(mount_point_cpath.as_ptr() as *const _, &mut stat) == 0 {
+ if retry_eintr!(statvfs(mount_point_cpath.as_ptr() as *const _, &mut stat)) == 0 {
let bsize = cast!(stat.f_bsize);
let blocks = cast!(stat.f_blocks);
let bavail = cast!(stat.f_bavail);
@@ -111,7 +111,7 @@ fn new_disk(
}
#[allow(clippy::manual_range_contains)]
-fn find_type_for_device_name(device_name: &OsStr) -> DiskType {
+fn find_type_for_device_name(device_name: &OsStr) -> DiskKind {
// The format of devices are as follows:
// - device_name is symbolic link in the case of /dev/mapper/
// and /dev/root, and the target is corresponding device under
@@ -171,13 +171,13 @@ fn find_type_for_device_name(device_name: &OsStr) -> DiskType {
.ok()
{
// The disk is marked as rotational so it's a HDD.
- Some(1) => DiskType::HDD,
+ Some(1) => DiskKind::HDD,
// The disk is marked as non-rotational so it's very likely a SSD.
- Some(0) => DiskType::SSD,
+ Some(0) => DiskKind::SSD,
// Normally it shouldn't happen but welcome to the wonderful world of IT! :D
- Some(x) => DiskType::Unknown(x),
+ Some(x) => DiskKind::Unknown(x),
// The information isn't available...
- None => DiskType::Unknown(-1),
+ None => DiskKind::Unknown(-1),
}
}
@@ -234,7 +234,9 @@ fn get_all_disks_inner(content: &str) -> Vec<Disk> {
"pstore" | // https://www.kernel.org/doc/Documentation/ABI/testing/pstore
"squashfs" | // squashfs is a compressed read-only file system (for snaps)
"rpc_pipefs" | // The pipefs pseudo file system service
- "iso9660" // optical media
+ "iso9660" | // optical media
+ "nfs4" | // calling statvfs on a mounted NFS may hang
+ "nfs" // nfs2 or nfs3
);
!(filtered ||
diff --git a/vendor/sysinfo/src/linux/network.rs b/vendor/sysinfo/src/linux/network.rs
index c8da2bcb3..3b89fdc57 100644
--- a/vendor/sysinfo/src/linux/network.rs
+++ b/vendor/sysinfo/src/linux/network.rs
@@ -1,9 +1,11 @@
// Take a look at the license at the top of the repository in the LICENSE file.
-use std::fs::File;
use std::io::Read;
use std::path::Path;
+use std::{fs::File, u8};
+use crate::common::MacAddr;
+use crate::network::refresh_networks_addresses;
use crate::{NetworkExt, NetworksExt, NetworksIter};
use std::collections::{hash_map, HashMap};
@@ -77,7 +79,7 @@ fn refresh_networks_list_from_sysfs(
// let tx_compressed = read(parent, "tx_compressed", &mut data);
match interfaces.entry(entry) {
hash_map::Entry::Occupied(mut e) => {
- let mut interface = e.get_mut();
+ let interface = e.get_mut();
old_and_new!(interface, rx_bytes, old_rx_bytes);
old_and_new!(interface, tx_bytes, old_tx_bytes);
old_and_new!(interface, rx_packets, old_rx_packets);
@@ -102,6 +104,7 @@ fn refresh_networks_list_from_sysfs(
old_rx_errors: rx_errors,
tx_errors,
old_tx_errors: tx_errors,
+ mac_addr: MacAddr::UNSPECIFIED,
// rx_compressed,
// old_rx_compressed: rx_compressed,
// tx_compressed,
@@ -132,6 +135,7 @@ impl NetworksExt for Networks {
fn refresh_networks_list(&mut self) {
refresh_networks_list_from_sysfs(&mut self.interfaces, Path::new("/sys/class/net/"));
+ refresh_networks_addresses(&mut self.interfaces);
}
}
@@ -157,6 +161,8 @@ pub struct NetworkData {
/// similar to `rx_errors`
tx_errors: u64,
old_tx_errors: u64,
+ /// MAC address
+ pub(crate) mac_addr: MacAddr,
// /// Indicates the number of compressed packets received by this
// /// network device. This value might only be relevant for interfaces
// /// that support packet compression (e.g: PPP).
@@ -263,6 +269,10 @@ impl NetworkExt for NetworkData {
fn total_errors_on_transmitted(&self) -> u64 {
self.tx_errors
}
+
+ fn mac_address(&self) -> MacAddr {
+ self.mac_addr
+ }
}
#[cfg(test)]
diff --git a/vendor/sysinfo/src/linux/process.rs b/vendor/sysinfo/src/linux/process.rs
index d7d61b5bc..55893ce8f 100644
--- a/vendor/sysinfo/src/linux/process.rs
+++ b/vendor/sysinfo/src/linux/process.rs
@@ -5,7 +5,6 @@ use std::collections::HashMap;
use std::fmt;
use std::fs::{self, File};
use std::io::Read;
-use std::mem::MaybeUninit;
use std::path::{Path, PathBuf};
use std::str::FromStr;
@@ -19,26 +18,13 @@ use crate::utils::into_iter;
use crate::{DiskUsage, Gid, Pid, ProcessExt, ProcessRefreshKind, ProcessStatus, Signal, Uid};
#[doc(hidden)]
-impl From<u32> for ProcessStatus {
- fn from(status: u32) -> ProcessStatus {
- match status {
- 1 => ProcessStatus::Idle,
- 2 => ProcessStatus::Run,
- 3 => ProcessStatus::Sleep,
- 4 => ProcessStatus::Stop,
- 5 => ProcessStatus::Zombie,
- x => ProcessStatus::Unknown(x),
- }
- }
-}
-
-#[doc(hidden)]
impl From<char> for ProcessStatus {
fn from(status: char) -> ProcessStatus {
match status {
'R' => ProcessStatus::Run,
'S' => ProcessStatus::Sleep,
- 'D' => ProcessStatus::Idle,
+ 'I' => ProcessStatus::Idle,
+ 'D' => ProcessStatus::UninterruptibleDiskSleep,
'Z' => ProcessStatus::Zombie,
'T' => ProcessStatus::Stop,
't' => ProcessStatus::Tracing,
@@ -64,6 +50,7 @@ impl fmt::Display for ProcessStatus {
ProcessStatus::Wakekill => "Wakekill",
ProcessStatus::Waking => "Waking",
ProcessStatus::Parked => "Parked",
+ ProcessStatus::UninterruptibleDiskSleep => "UninterruptibleDiskSleep",
_ => "Unknown",
})
}
@@ -91,7 +78,9 @@ pub struct Process {
pub(crate) updated: bool,
cpu_usage: f32,
user_id: Option<Uid>,
+ effective_user_id: Option<Uid>,
group_id: Option<Gid>,
+ effective_group_id: Option<Gid>,
pub(crate) status: ProcessStatus,
/// Tasks run by this process.
pub tasks: HashMap<Pid, Process>,
@@ -125,7 +114,9 @@ impl Process {
start_time: 0,
run_time: 0,
user_id: None,
+ effective_user_id: None,
group_id: None,
+ effective_group_id: None,
status: ProcessStatus::Unknown(0),
tasks: if pid.0 == 0 {
HashMap::with_capacity(1000)
@@ -216,15 +207,23 @@ impl ProcessExt for Process {
self.user_id.as_ref()
}
+ fn effective_user_id(&self) -> Option<&Uid> {
+ self.effective_user_id.as_ref()
+ }
+
fn group_id(&self) -> Option<Gid> {
self.group_id
}
+ fn effective_group_id(&self) -> Option<Gid> {
+ self.effective_group_id
+ }
+
fn wait(&self) {
let mut status = 0;
// attempt waiting
unsafe {
- if libc::waitpid(self.pid.0, &mut status, 0) < 0 {
+ if retry_eintr!(libc::waitpid(self.pid.0, &mut status, 0)) < 0 {
// attempt failed (non-child process) so loop until process ends
let duration = std::time::Duration::from_millis(10);
while kill(self.pid.0, 0) == 0 {
@@ -233,6 +232,17 @@ impl ProcessExt for Process {
}
}
}
+
+ fn session_id(&self) -> Option<Pid> {
+ unsafe {
+ let session_id = libc::getsid(self.pid.0);
+ if session_id < 0 {
+ None
+ } else {
+ Some(Pid(session_id))
+ }
+ }
+ }
}
pub(crate) fn compute_cpu_usage(p: &mut Process, total_time: f32, max_value: f32) {
@@ -248,6 +258,17 @@ pub(crate) fn compute_cpu_usage(p: &mut Process, total_time: f32, max_value: f32
/ total_time
* 100.)
.min(max_value);
+
+ for task in p.tasks.values_mut() {
+ compute_cpu_usage(task, total_time, max_value);
+ }
+}
+
+pub(crate) fn unset_updated(p: &mut Process) {
+ p.updated = false;
+ for task in p.tasks.values_mut() {
+ unset_updated(task);
+ }
}
pub(crate) fn set_time(p: &mut Process, utime: u64, stime: u64) {
@@ -327,9 +348,13 @@ fn get_status(p: &mut Process, part: &str) {
}
fn refresh_user_group_ids<P: PathPush>(p: &mut Process, path: &mut P) {
- if let Some((user_id, group_id)) = get_uid_and_gid(path.join("status")) {
+ if let Some(((user_id, effective_user_id), (group_id, effective_group_id))) =
+ get_uid_and_gid(path.join("status"))
+ {
p.user_id = Some(Uid(user_id));
+ p.effective_user_id = Some(Uid(effective_user_id));
p.group_id = Some(Gid(group_id));
+ p.effective_group_id = Some(Gid(effective_group_id));
}
}
@@ -366,35 +391,24 @@ fn retrieve_all_new_process_info(
refresh_user_group_ids(&mut p, &mut tmp);
}
- if proc_list.pid.0 != 0 {
- // If we're getting information for a child, no need to get those info since we
- // already have them...
- p.cmd = proc_list.cmd.clone();
- p.name = proc_list.name.clone();
- p.environ = proc_list.environ.clone();
- p.exe = proc_list.exe.clone();
- p.cwd = proc_list.cwd.clone();
- p.root = proc_list.root.clone();
- } else {
- p.name = name.into();
+ p.name = name.into();
- match tmp.join("exe").read_link() {
- Ok(exe_path) => {
- p.exe = exe_path;
- }
- Err(_) => {
- // Do not use cmd[0] because it is not the same thing.
- // See https://github.com/GuillaumeGomez/sysinfo/issues/697.
- p.exe = PathBuf::new()
- }
+ match tmp.join("exe").read_link() {
+ Ok(exe_path) => {
+ p.exe = exe_path;
+ }
+ Err(_) => {
+ // Do not use cmd[0] because it is not the same thing.
+ // See https://github.com/GuillaumeGomez/sysinfo/issues/697.
+ p.exe = PathBuf::new()
}
-
- p.cmd = copy_from_file(tmp.join("cmdline"));
- p.environ = copy_from_file(tmp.join("environ"));
- p.cwd = realpath(tmp.join("cwd"));
- p.root = realpath(tmp.join("root"));
}
+ p.cmd = copy_from_file(tmp.join("cmdline"));
+ p.environ = copy_from_file(tmp.join("environ"));
+ p.cwd = realpath(tmp.join("cwd"));
+ p.root = realpath(tmp.join("root"));
+
update_time_and_memory(
path,
&mut p,
@@ -420,6 +434,11 @@ pub(crate) fn _get_process_data(
refresh_kind: ProcessRefreshKind,
) -> Result<(Option<Process>, Pid), ()> {
let pid = match path.file_name().and_then(|x| x.to_str()).map(Pid::from_str) {
+ // If `pid` and `nb` are the same, it means the file is linking to itself so we skip it.
+ //
+ // It's because when reading `/proc/[PID]` folder, we then go through the folders inside it.
+ // Then, if we encounter a sub-folder with the same PID as the parent, then it's a link to
+ // the current folder we already did read so no need to do anything.
Some(Ok(nb)) if nb != pid => nb,
_ => return Err(()),
};
@@ -609,10 +628,12 @@ pub(crate) fn refresh_procs(
fn copy_from_file(entry: &Path) -> Vec<String> {
match File::open(entry) {
Ok(mut f) => {
- let mut data = vec![0; 16_384];
+ let mut data = Vec::with_capacity(16_384);
- if let Ok(size) = f.read(&mut data) {
- data.truncate(size);
+ if let Err(_e) = f.read_to_end(&mut data) {
+ sysinfo_debug!("Failed to read file in `copy_from_file`: {:?}", _e);
+ Vec::new()
+ } else {
let mut out = Vec::with_capacity(20);
let mut start = 0;
for (pos, x) in data.iter().enumerate() {
@@ -628,51 +649,47 @@ fn copy_from_file(entry: &Path) -> Vec<String> {
}
}
out
- } else {
- Vec::new()
}
}
- Err(_) => Vec::new(),
- }
-}
-
-fn get_uid_and_gid(file_path: &Path) -> Option<(uid_t, gid_t)> {
- use std::os::unix::ffi::OsStrExt;
-
- unsafe {
- let mut sstat: MaybeUninit<libc::stat> = MaybeUninit::uninit();
-
- let mut file_path: Vec<u8> = file_path.as_os_str().as_bytes().to_vec();
- file_path.push(0);
- if libc::stat(file_path.as_ptr() as *const _, sstat.as_mut_ptr()) == 0 {
- let sstat = sstat.assume_init();
-
- return Some((sstat.st_uid, sstat.st_gid));
+ Err(_e) => {
+ sysinfo_debug!("Failed to open file in `copy_from_file`: {:?}", _e);
+ Vec::new()
}
}
+}
+// Fetch tuples of real and effective UID and GID.
+fn get_uid_and_gid(file_path: &Path) -> Option<((uid_t, uid_t), (gid_t, gid_t))> {
let status_data = get_all_data(file_path, 16_385).ok()?;
// We're only interested in the lines starting with Uid: and Gid:
- // here. From these lines, we're looking at the second entry to get
- // the effective u/gid.
+ // here. From these lines, we're looking at the first and second entries to get
+ // the real u/gid.
- let f = |h: &str, n: &str| -> Option<uid_t> {
+ let f = |h: &str, n: &str| -> (Option<uid_t>, Option<uid_t>) {
if h.starts_with(n) {
- h.split_whitespace().nth(2).unwrap_or("0").parse().ok()
+ let mut ids = h.split_whitespace();
+ let real = ids.nth(1).unwrap_or("0").parse().ok();
+ let effective = ids.next().unwrap_or("0").parse().ok();
+
+ (real, effective)
} else {
- None
+ (None, None)
}
};
let mut uid = None;
+ let mut effective_uid = None;
let mut gid = None;
+ let mut effective_gid = None;
for line in status_data.lines() {
- if let Some(u) = f(line, "Uid:") {
- assert!(uid.is_none());
- uid = Some(u);
- } else if let Some(g) = f(line, "Gid:") {
- assert!(gid.is_none());
- gid = Some(g);
+ if let (Some(real), Some(effective)) = f(line, "Uid:") {
+ debug_assert!(uid.is_none() && effective_uid.is_none());
+ uid = Some(real);
+ effective_uid = Some(effective);
+ } else if let (Some(real), Some(effective)) = f(line, "Gid:") {
+ debug_assert!(gid.is_none() && effective_gid.is_none());
+ gid = Some(real);
+ effective_gid = Some(effective);
} else {
continue;
}
@@ -680,8 +697,10 @@ fn get_uid_and_gid(file_path: &Path) -> Option<(uid_t, gid_t)> {
break;
}
}
- match (uid, gid) {
- (Some(u), Some(g)) => Some((u, g)),
+ match (uid, effective_uid, gid, effective_gid) {
+ (Some(uid), Some(effective_uid), Some(gid), Some(effective_gid)) => {
+ Some(((uid, effective_uid), (gid, effective_gid)))
+ }
_ => None,
}
}
diff --git a/vendor/sysinfo/src/linux/system.rs b/vendor/sysinfo/src/linux/system.rs
index 3c4fce345..bbb6b24c4 100644
--- a/vendor/sysinfo/src/linux/system.rs
+++ b/vendor/sysinfo/src/linux/system.rs
@@ -16,6 +16,7 @@ use std::io::{BufRead, BufReader, Read};
use std::path::Path;
use std::str::FromStr;
use std::sync::{Arc, Mutex};
+use std::time::Duration;
// This whole thing is to prevent having too many files open at once. It could be problematic
// for processes using a lot of files and using sysinfo at the same time.
@@ -28,7 +29,7 @@ pub(crate) static mut REMAINING_FILES: once_cell::sync::Lazy<Arc<Mutex<isize>>>
rlim_max: 0,
};
if libc::getrlimit(libc::RLIMIT_NOFILE, &mut limits) != 0 {
- // Most linux system now defaults to 1024.
+ // Most Linux system now defaults to 1024.
return Arc::new(Mutex::new(1024 / 2));
}
// We save the value in case the update fails.
@@ -55,7 +56,7 @@ pub(crate) fn get_max_nb_fds() -> isize {
rlim_max: 0,
};
if libc::getrlimit(libc::RLIMIT_NOFILE, &mut limits) != 0 {
- // Most linux system now defaults to 1024.
+ // Most Linux system now defaults to 1024.
1024 / 2
} else {
limits.rlim_max as isize / 2
@@ -81,11 +82,8 @@ fn boot_time() -> u64 {
}
}
// Either we didn't find "btime" or "/proc/stat" wasn't available for some reason...
- let mut up = libc::timespec {
- tv_sec: 0,
- tv_nsec: 0,
- };
unsafe {
+ let mut up: libc::timespec = std::mem::zeroed();
if libc::clock_gettime(libc::CLOCK_BOOTTIME, &mut up) == 0 {
up.tv_sec as u64
} else {
@@ -207,7 +205,7 @@ impl System {
if compute_cpu {
compute_cpu_usage(proc_, total_time, max_value);
}
- proc_.updated = false;
+ unset_updated(proc_);
true
});
}
@@ -220,6 +218,7 @@ impl System {
impl SystemExt for System {
const IS_SUPPORTED: bool = true;
const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals();
+ const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200);
fn new_with_specifics(refreshes: RefreshKind) -> System {
let process_list = Process::new(Pid(0));
@@ -311,7 +310,7 @@ impl SystemExt for System {
fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool {
let uptime = self.uptime();
- let found = match _get_process_data(
+ match _get_process_data(
&Path::new("/proc/").join(pid.to_string()),
&mut self.process_list,
Pid(0),
@@ -321,32 +320,33 @@ impl SystemExt for System {
) {
Ok((Some(p), pid)) => {
self.process_list.tasks.insert(pid, p);
- true
}
- Ok(_) => true,
- Err(_) => false,
+ Ok(_) => {}
+ Err(_e) => {
+ sysinfo_debug!("Cannot get information for PID {:?}: {:?}", pid, _e);
+ return false;
+ }
};
- if found {
- if refresh_kind.cpu() {
- self.refresh_cpus(true, CpuRefreshKind::new().with_cpu_usage());
+ if refresh_kind.cpu() {
+ self.refresh_cpus(true, CpuRefreshKind::new().with_cpu_usage());
- if self.cpus.is_empty() {
- sysinfo_debug!("Cannot compute process CPU usage: no cpus found...");
- return found;
- }
- let (new, old) = self.cpus.get_global_raw_times();
- let total_time = (if old >= new { 1 } else { new - old }) as f32;
-
- let max_cpu_usage = self.get_max_process_cpu_usage();
- if let Some(p) = self.process_list.tasks.get_mut(&pid) {
- compute_cpu_usage(p, total_time / self.cpus.len() as f32, max_cpu_usage);
- p.updated = false;
- }
- } else if let Some(p) = self.process_list.tasks.get_mut(&pid) {
- p.updated = false;
+ if self.cpus.is_empty() {
+ eprintln!("Cannot compute process CPU usage: no cpus found...");
+ return true;
+ }
+ let (new, old) = self.cpus.get_global_raw_times();
+ let total_time = (if old >= new { 1 } else { new - old }) as f32;
+ let total_time = total_time / self.cpus.len() as f32;
+
+ let max_cpu_usage = self.get_max_process_cpu_usage();
+ if let Some(p) = self.process_list.tasks.get_mut(&pid) {
+ compute_cpu_usage(p, total_time, max_cpu_usage);
+ unset_updated(p);
}
+ } else if let Some(p) = self.process_list.tasks.get_mut(&pid) {
+ unset_updated(p);
}
- found
+ true
}
fn refresh_disks_list(&mut self) {
diff --git a/vendor/sysinfo/src/linux/utils.rs b/vendor/sysinfo/src/linux/utils.rs
index 60a9aa2b0..486682210 100644
--- a/vendor/sysinfo/src/linux/utils.rs
+++ b/vendor/sysinfo/src/linux/utils.rs
@@ -1,14 +1,14 @@
// Take a look at the license at the top of the repository in the LICENSE file.
use std::fs::File;
-use std::io::{self, Read, Seek, SeekFrom};
+use std::io::{self, Read, Seek};
use std::path::{Path, PathBuf};
use crate::sys::system::REMAINING_FILES;
pub(crate) fn get_all_data_from_file(file: &mut File, size: usize) -> io::Result<String> {
let mut buf = String::with_capacity(size);
- file.seek(SeekFrom::Start(0))?;
+ file.rewind()?;
file.read_to_string(&mut buf)?;
Ok(buf)
}