Repository: GuillaumeGomez/sysinfo (language: rust)

Issue:
System::refresh_processes() doesn't update CPU
### My setup

OS:                  WSL, Ubuntu 24.04 LTS
Architecture:   x86_64
Rust:                1.81.0
Sysinfo:            0.31.4

### Issue 

When I call `System::refresh_processes_specifics(ProcessesToUpdate::Some(&[pid], ProcessRefreshKind::new().with_cpu().with_memory())` the cpu usage of provided process is not updated. Calling `Process::cpu_usage()` always returns the same value.

#### Expected behavious

CPU usage is updated and can be read from `Process` struct.

#### Actuall result

Only memory gets updated, CPU value always stays the same.

What is interesting, when I replaced `ProcessesToUpdate::Some(...)` with `ProcessesToUpdate::All`, all of a sudden it is updating correctly.

### Code to reproduce issue

```rust
use std::{thread, time::Duration};

use sysinfo::{get_current_pid, ProcessRefreshKind, System};


fn main() {
    let mut system = System::new_all();
    loop {
        thread::sleep(Duration::from_secs(1));
        let pid = get_current_pid().unwrap();
        system.refresh_processes_specifics(
            sysinfo::ProcessesToUpdate::Some(&[pid]),
            ProcessRefreshKind::everything()
        );
        let process = system.process(pid).unwrap();

        println!("cpu={}, mem={}", process.cpu_usage(), process.memory());
    }
}
```
![image](https://github.com/user-attachments/assets/adc70ac8-cf57-44f6-8c9e-7401b0238f3f)

`top -p <pid>` returns CPU usage from 0.0 to 0.3, to the value should fluctuate a bit, but it always remains zero.


Discussion / hints:
I even added some shitty fibbonaci function to make sure that CPU is heavily loaded - even when `top` returns 90% CPU utilization, I still get `0` printed to the console :( 

```rust
use std::{thread, time::Duration};

use sysinfo::{get_current_pid, ProcessRefreshKind, System};


fn fib(n: u64) -> u64 {
    if n == 0 || n == 1 {
        return 1;
    }
    return fib(n - 1) + fib(n - 2);
}

fn main() {
    thread::spawn(|| {
        let calculation = fib(100);
        println!("{calculation}");
    });
    let mut system = System::new_all();
    loop {
        thread::sleep(Duration::from_secs(1));
        let pid = get_current_pid().unwrap();
        system.refresh_processes_specifics(
            sysinfo::ProcessesToUpdate::Some(&[pid]),
            ProcessRefreshKind::everything()
        );
        let process = system.process(pid).unwrap();

        println!("cpu={}, mem={}", process.cpu_usage(), process.memory());
    }
}
```
I'll try to take a look in the next days. Could be interesting if you checked what path the code is entering into on your side as I don't have your setup.
Is there a specific reason for this check? In my understanding, `update_procs_cpu` would work in both situations.

https://github.com/GuillaumeGomez/sysinfo/blob/c821de4249a85f566766890345830d4b24a2dcb7/src/unix/linux/system.rs#L279-L282
It's to prevent having the CPU information to be updated too often. However, the check is not great considering that normally it's based on a time diff. Might be worth changing this code.
Intuitively, I believe the fix is to remove the `if` guard, since `update_procs_cpu` iterates on `self.process_list` that only contains the processes we're interested? Although I might be missing something.
That would be problematic. If you update the system time every time you refresh a process, all processes CPU usage will remain at 0%.

Fix patch:
diff --git a/src/unix/linux/cpu.rs b/src/unix/linux/cpu.rs
index dfee6b241..5e8d55d30 100644
--- a/src/unix/linux/cpu.rs
+++ b/src/unix/linux/cpu.rs
@@ -19,11 +19,6 @@ macro_rules! to_str {
 pub(crate) struct CpusWrapper {
     pub(crate) global_cpu: CpuUsage,
     pub(crate) cpus: Vec<Cpu>,
-    /// Field set to `false` in `update_cpus` and to `true` in `refresh_processes_specifics`.
-    ///
-    /// The reason behind this is to avoid calling the `update_cpus` more than necessary.
-    /// 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>,
@@ -34,7 +29,6 @@ impl CpusWrapper {
         Self {
             global_cpu: CpuUsage::default(),
             cpus: Vec::with_capacity(4),
-            need_cpus_update: true,
             got_cpu_frequency: false,
             last_update: None,
         }
@@ -45,9 +39,7 @@ impl CpusWrapper {
         only_update_global_cpu: bool,
         refresh_kind: CpuRefreshKind,
     ) {
-        if self.need_cpus_update {
-            self.refresh(only_update_global_cpu, refresh_kind);
-        }
+        self.refresh(only_update_global_cpu, refresh_kind);
     }
 
     pub(crate) fn refresh(&mut self, only_update_global_cpu: bool, refresh_kind: CpuRefreshKind) {
@@ -76,7 +68,6 @@ impl CpusWrapper {
             };
             let buf = BufReader::new(f);
 
-            self.need_cpus_update = false;
             let mut i: usize = 0;
             let mut it = buf.split(b'\n');
 
@@ -193,10 +184,6 @@ impl CpusWrapper {
     pub(crate) fn is_empty(&self) -> bool {
         self.cpus.is_empty()
     }
-
-    pub(crate) fn set_need_cpus_update(&mut self) {
-        self.need_cpus_update = true;
-    }
 }
 
 /// Struct containing values to compute a CPU usage.
diff --git a/src/unix/linux/system.rs b/src/unix/linux/system.rs
index 33001e095..fbe89e593 100644
--- a/src/unix/linux/system.rs
+++ b/src/unix/linux/system.rs
@@ -276,10 +276,7 @@ impl SystemInner {
             processes_to_update,
             refresh_kind,
         );
-        if matches!(processes_to_update, ProcessesToUpdate::All) {
-            self.update_procs_cpu(refresh_kind);
-            self.cpus.set_need_cpus_update();
-        }
+        self.update_procs_cpu(refresh_kind);
         nb_updated
     }
 


Test patch: