diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 9d6d90e..5eaa2cf 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -3,12 +3,12 @@ windows_subsystem = "windows" )] -use sysinfo::System; +use sysinfo::{System, Pid}; use std::sync::Mutex; use std::process::Command; use tauri::State; use serde::{Serialize, Deserialize}; -use std::collections::{HashMap, HashSet}; +use std::collections::HashMap; use chrono::{DateTime, Utc}; use std::fs; use rayon::prelude::*; @@ -119,27 +119,18 @@ fn get_pss(pid: u32) -> Option { // --- Commands --- -fn get_all_descendants(target_pid: u32, sys: &System) -> HashSet { - let mut descendants = HashSet::new(); - let mut stack = vec![target_pid]; - - let mut child_map: HashMap> = HashMap::new(); - for (pid, process) in sys.processes() { - if let Some(parent) = process.parent() { - child_map.entry(parent.as_u32()).or_default().push(pid.as_u32()); +fn is_syspulse_recursive(pid: u32, self_pid: u32, sys: &System) -> bool { + if pid == self_pid { return true; } + let mut current = sys.process(Pid::from_u32(pid)); + while let Some(proc) = current { + if let Some(ppid) = proc.parent() { + if ppid.as_u32() == self_pid { return true; } + current = sys.process(ppid); + } else { + break; } } - - while let Some(pid) = stack.pop() { - if let Some(children) = child_map.get(&pid) { - for &child in children { - if descendants.insert(child) { - stack.push(child); - } - } - } - } - descendants + false } #[tauri::command] @@ -159,34 +150,29 @@ fn get_system_stats( let total_memory = sys.total_memory(); let used_memory = sys.used_memory(); - let syspulse_set = get_all_descendants(self_pid, &sys); + let processes: Vec = sys.processes().iter() + .par_bridge() + .filter_map(|(pid, p)| { + let rss = p.memory(); + if rss == 0 { return None; } - let raw_processes: Vec<_> = sys.processes().iter() - .map(|(pid, p)| ( - pid.as_u32(), - p.parent().map(|pp| pp.as_u32()), - p.name().to_string_lossy().to_string(), - p.cpu_usage(), - p.memory(), - format!("{:?}", p.status()), - p.user_id().map(|u| u.to_string()) - )) - .collect(); + let pid_u32 = pid.as_u32(); + let memory = if rss > 10 * 1024 * 1024 { + get_pss(pid_u32).unwrap_or(rss) + } else { + rss + }; - let processes: Vec = raw_processes.into_par_iter() - .map(|(pid, parent_pid, name, cpu, rss, status, uid)| { - let is_syspulse = pid == self_pid || syspulse_set.contains(&pid); - let memory = get_pss(pid).unwrap_or(rss); - ProcessStats { - pid, - parent_pid, - name, - cpu_usage: cpu, + Some(ProcessStats { + pid: pid_u32, + parent_pid: p.parent().map(|pp| pp.as_u32()), + name: p.name().to_string_lossy().to_string(), + cpu_usage: p.cpu_usage(), memory, - status, - user_id: uid, - is_syspulse, - } + status: format!("{:?}", p.status()), + user_id: p.user_id().map(|u| u.to_string()), + is_syspulse: is_syspulse_recursive(pid_u32, self_pid, &sys), + }) }).collect(); if profiling.is_active { @@ -204,17 +190,15 @@ fn get_system_stats( 0 }; - let mut display_processes = if minimal && !profiling.is_active { + let display_processes = if minimal && !profiling.is_active { Vec::new() } else { - processes.clone() + let mut p = processes.clone(); + p.sort_by(|a, b| b.cpu_usage.partial_cmp(&a.cpu_usage).unwrap_or(std::cmp::Ordering::Equal)); + p.truncate(50); + p }; - if !minimal { - display_processes.sort_by(|a, b| b.cpu_usage.partial_cmp(&a.cpu_usage).unwrap_or(std::cmp::Ordering::Equal)); - display_processes.truncate(50); - } - SystemStats { cpu_usage, total_memory, @@ -250,7 +234,6 @@ fn stop_profiling(state: State) -> Report { let end = Utc::now(); let duration = (end - start).num_seconds(); - // 1. Generate Session Timeline let timeline: Vec = profiling.snapshots.iter().map(|s| { let avg_cpu = s.cpu_usage.iter().sum::() / s.cpu_usage.len() as f32; TimelinePoint { @@ -260,7 +243,6 @@ fn stop_profiling(state: State) -> Report { } }).collect(); - // 2. Aggregate RAW stats per PID struct PidStats { name: String, history: Vec, @@ -297,7 +279,6 @@ fn stop_profiling(state: State) -> Report { } } - // 3. Convert to nodes let mut nodes: HashMap = pid_map.into_iter().map(|(pid, stats)| { let total_cpu: f32 = stats.history.iter().map(|h| h.cpu_usage).sum(); let total_mem: f32 = stats.history.iter().map(|h| h.memory_mb).sum(); @@ -323,7 +304,6 @@ fn stop_profiling(state: State) -> Report { }) }).collect(); - // 4. Build Tree let mut child_to_parent = HashMap::new(); for snapshot in &profiling.snapshots { for proc in &snapshot.processes {