Use pid as internal id
parent
2cc3d2ccf9
commit
b8170dbe7e
|
@ -14,19 +14,19 @@
|
|||
"itemProperties": {
|
||||
"pid": {
|
||||
"type": "quint32",
|
||||
"roles": [ ["display"] ]
|
||||
"roles": [ ["toolTip"] ]
|
||||
},
|
||||
"name": {
|
||||
"type": "QString",
|
||||
"roles": [ [], ["display"] ]
|
||||
"roles": [ ["display"] ]
|
||||
},
|
||||
"cpuUsage": {
|
||||
"type": "float",
|
||||
"roles": [ [], [], ["display"] ]
|
||||
"roles": [ [], ["display"] ]
|
||||
},
|
||||
"memory": {
|
||||
"type": "quint64",
|
||||
"roles": [ [], [], [], ["display"] ]
|
||||
"roles": [ [], [], ["display"] ]
|
||||
},
|
||||
"uid": {
|
||||
"type": "quint32"
|
||||
|
|
|
@ -7,16 +7,15 @@ use libc::pid_t;
|
|||
use std::{thread, time};
|
||||
|
||||
struct ProcessItem {
|
||||
parent: Option<usize>,
|
||||
row: usize,
|
||||
tasks: Vec<usize>,
|
||||
tasks: Vec<pid_t>,
|
||||
process: Process
|
||||
}
|
||||
|
||||
#[derive (Default)]
|
||||
struct ProcessTree {
|
||||
top: Vec<usize>,
|
||||
processes: Vec<ProcessItem>,
|
||||
top: Vec<pid_t>,
|
||||
processes: HashMap<pid_t, ProcessItem>,
|
||||
cpusum: f32
|
||||
}
|
||||
|
||||
|
@ -27,37 +26,72 @@ pub struct Processes {
|
|||
incoming: Arc<Mutex<Option<ProcessTree>>>
|
||||
}
|
||||
|
||||
fn handle_tasks(tasks: &HashMap<pid_t,Process>,
|
||||
mut processes: &mut Vec<ProcessItem>,
|
||||
parentPos: Option<usize>) -> (Vec<usize>, f32) {
|
||||
let mut t = Vec::new();
|
||||
let mut i = 0;
|
||||
fn check() {
|
||||
fn check_process_hierarchy(parent: Option<pid_t>, processes: &HashMap<pid_t,Process>) {
|
||||
for (pid, process) in processes {
|
||||
assert_eq!(process.pid, *pid);
|
||||
if !parent.is_none() {
|
||||
assert_eq!(process.parent, parent);
|
||||
}
|
||||
check_process_hierarchy(Some(*pid), &process.tasks);
|
||||
}
|
||||
}
|
||||
|
||||
let mut sysinfo = System::new();
|
||||
sysinfo.refresh_processes();
|
||||
check_process_hierarchy(None, sysinfo.get_process_list());
|
||||
}
|
||||
|
||||
fn collect_processes(tasks: &HashMap<pid_t,Process>,
|
||||
mut processes: &mut HashMap<pid_t, ProcessItem>) -> f32 {
|
||||
let mut cpusum = 0.0;
|
||||
for process in tasks.values() {
|
||||
let pos = processes.len();
|
||||
t.push(pos);
|
||||
processes.push(ProcessItem {
|
||||
parent: parentPos,
|
||||
row: i,
|
||||
for (pid, process) in tasks {
|
||||
processes.insert(process.pid, ProcessItem {
|
||||
row: 0,
|
||||
tasks: Vec::new(),
|
||||
process: process.clone()
|
||||
});
|
||||
let (t, s) = handle_tasks(&process.tasks, &mut processes, Some(pos));
|
||||
processes[pos].tasks = t;
|
||||
let s = collect_processes(&process.tasks, &mut processes);
|
||||
cpusum += process.cpu_usage + s;
|
||||
i += 1;
|
||||
}
|
||||
(t, cpusum)
|
||||
cpusum
|
||||
}
|
||||
|
||||
// reconstruct process hierarchy
|
||||
fn handle_tasks(mut processes: &mut HashMap<pid_t, ProcessItem>) -> Vec<pid_t> {
|
||||
let mut top = Vec::new();
|
||||
let pids: Vec<pid_t> = processes.keys().map(|p| *p).collect();
|
||||
for pid in pids {
|
||||
if let Some(parent) = processes[&pid].process.parent {
|
||||
let row = {
|
||||
let p = processes.get_mut(&parent).unwrap();
|
||||
let row = p.tasks.len();
|
||||
p.tasks.push(pid);
|
||||
row
|
||||
};
|
||||
processes.get_mut(&pid).unwrap().row = row;
|
||||
} else {
|
||||
top.push(pid);
|
||||
}
|
||||
}
|
||||
top.sort();
|
||||
top
|
||||
}
|
||||
|
||||
fn sort_tasks(mut processes: &mut HashMap<pid_t, ProcessItem>) {
|
||||
for process in processes.values_mut() {
|
||||
process.tasks.sort();
|
||||
}
|
||||
}
|
||||
|
||||
fn update() -> ProcessTree {
|
||||
check();
|
||||
let mut p = ProcessTree::default();
|
||||
let mut sysinfo = System::new();
|
||||
sysinfo.refresh_processes();
|
||||
let (top, cpusum) = handle_tasks(sysinfo.get_process_list(),
|
||||
&mut p.processes, None);
|
||||
p.top = top;
|
||||
p.cpusum = cpusum;
|
||||
p.cpusum = collect_processes(sysinfo.get_process_list(), &mut p.processes);
|
||||
p.top = handle_tasks(&mut p.processes);
|
||||
sort_tasks(&mut p.processes);
|
||||
p
|
||||
}
|
||||
|
||||
|
@ -72,6 +106,13 @@ fn update_thread(emit: ProcessesEmitter, incoming: Arc<Mutex<Option<ProcessTree>
|
|||
});
|
||||
}
|
||||
|
||||
impl Processes {
|
||||
fn get(&self, item: usize) -> &ProcessItem {
|
||||
let pid = item as pid_t;
|
||||
&self.p.processes[&pid]
|
||||
}
|
||||
}
|
||||
|
||||
impl ProcessesTrait for Processes {
|
||||
fn create(emit: ProcessesEmitter, model: ProcessesUniformTree) -> Processes {
|
||||
let mut p = Processes {
|
||||
|
@ -88,20 +129,20 @@ impl ProcessesTrait for Processes {
|
|||
}
|
||||
fn row_count(&self, item: Option<usize>) -> usize {
|
||||
if let Some(item) = item {
|
||||
self.p.processes[item].tasks.len()
|
||||
self.get(item).tasks.len()
|
||||
} else {
|
||||
self.p.top.len()
|
||||
}
|
||||
}
|
||||
fn index(&self, item: Option<usize>, row: usize) -> usize {
|
||||
if let Some(item) = item {
|
||||
self.p.processes[item].tasks[row]
|
||||
self.get(item).tasks[row] as usize
|
||||
} else {
|
||||
self.p.top[row]
|
||||
self.p.top[row] as usize
|
||||
}
|
||||
}
|
||||
fn parent(&self, item: usize) -> Option<usize> {
|
||||
self.p.processes[item].parent
|
||||
self.get(item).process.parent.map(|pid| pid as usize)
|
||||
}
|
||||
fn can_fetch_more(&self, item: Option<usize>) -> bool {
|
||||
if let Ok(ref incoming) = self.incoming.try_lock() {
|
||||
|
@ -120,28 +161,28 @@ impl ProcessesTrait for Processes {
|
|||
}
|
||||
}
|
||||
fn row(&self, item: usize) -> usize {
|
||||
self.p.processes[item].row
|
||||
self.get(item).row
|
||||
}
|
||||
fn pid(&self, item: usize) -> u32 {
|
||||
self.p.processes[item].process.pid as u32
|
||||
self.get(item).process.pid as u32
|
||||
}
|
||||
fn uid(&self, item: usize) -> u32 {
|
||||
self.p.processes[item].process.uid as u32
|
||||
self.get(item).process.uid as u32
|
||||
}
|
||||
fn cpu_usage(&self, item: usize) -> f32 {
|
||||
self.p.processes[item].process.cpu_usage
|
||||
self.get(item).process.cpu_usage
|
||||
}
|
||||
fn cpu_percentage(&self, item: usize) -> u8 {
|
||||
let cpu = self.p.processes[item].process.cpu_usage / self.p.cpusum;
|
||||
let cpu = self.get(item).process.cpu_usage / self.p.cpusum;
|
||||
(cpu * 100.0) as u8
|
||||
}
|
||||
fn memory(&self, item: usize) -> u64 {
|
||||
self.p.processes[item].process.memory
|
||||
self.get(item).process.memory
|
||||
}
|
||||
fn name(&self, item: usize) -> String {
|
||||
self.p.processes[item].process.name.clone()
|
||||
self.get(item).process.name.clone()
|
||||
}
|
||||
fn cmd(&self, item: usize) -> String {
|
||||
self.p.processes[item].process.cmd.join(" ")
|
||||
self.get(item).process.cmd.join(" ")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,7 +73,7 @@ extern "C" {
|
|||
}
|
||||
int Processes::columnCount(const QModelIndex &) const
|
||||
{
|
||||
return 4;
|
||||
return 3;
|
||||
}
|
||||
|
||||
bool Processes::hasChildren(const QModelIndex &parent) const
|
||||
|
@ -91,7 +91,7 @@ int Processes::rowCount(const QModelIndex &parent) const
|
|||
|
||||
QModelIndex Processes::index(int row, int column, const QModelIndex &parent) const
|
||||
{
|
||||
if (row < 0 || column < 0 || column >= 4) {
|
||||
if (row < 0 || column < 0 || column >= 3) {
|
||||
return QModelIndex();
|
||||
}
|
||||
if (parent.isValid() && parent.column() != 0) {
|
||||
|
@ -156,11 +156,12 @@ QVariant Processes::data(const QModelIndex &index, int role) const
|
|||
case Qt::UserRole + 3:
|
||||
v = processes_data_memory(d, index.internalId());
|
||||
break;
|
||||
case Qt::DisplayRole:
|
||||
case Qt::UserRole + 4:
|
||||
processes_data_name(d, index.internalId(), &s, set_qstring);
|
||||
if (!s.isNull()) v.setValue<QString>(s);
|
||||
break;
|
||||
case Qt::DisplayRole:
|
||||
case Qt::ToolTipRole:
|
||||
case Qt::UserRole + 5:
|
||||
v = processes_data_pid(d, index.internalId());
|
||||
break;
|
||||
|
@ -170,15 +171,6 @@ QVariant Processes::data(const QModelIndex &index, int role) const
|
|||
}
|
||||
break;
|
||||
case 1:
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
case Qt::UserRole + 4:
|
||||
processes_data_name(d, index.internalId(), &s, set_qstring);
|
||||
if (!s.isNull()) v.setValue<QString>(s);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
case Qt::UserRole + 2:
|
||||
|
@ -186,7 +178,7 @@ QVariant Processes::data(const QModelIndex &index, int role) const
|
|||
break;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 2:
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
case Qt::UserRole + 3:
|
||||
|
|
Loading…
Reference in New Issue