summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwangqr <wangqr@wangqr.tk>2017-09-01 21:27:24 +0800
committerwangqr <wangqr@wangqr.tk>2017-09-01 21:34:05 +0800
commit584a9bceab948590dabd189d234a86e6bf4ec3f4 (patch)
treef5f812cbaa9e074075a60709df1fe201c8f66625
parent9487bda33016c2b8efa8429256c410a2de184baa (diff)
Find roots when constructing process tree, fix #587
-rw-r--r--ProcessList.c54
1 files changed, 38 insertions, 16 deletions
diff --git a/ProcessList.c b/ProcessList.c
index a49b4f12..19311cab 100644
--- a/ProcessList.c
+++ b/ProcessList.c
@@ -213,23 +213,45 @@ void ProcessList_sort(ProcessList* this) {
// Restore settings
this->settings->sortKey = sortKey;
this->settings->direction = direction;
- // Take PID 1 as root and add to the new listing
int vsize = Vector_size(this->processes);
- Process* init = (Process*) (Vector_take(this->processes, 0));
- if (!init) return;
- // This assertion crashes on hardened kernels.
- // I wonder how well tree view works on those systems.
- // assert(init->pid == 1);
- init->indent = 0;
- Vector_add(this->processes2, init);
- // Recursively empty list
- ProcessList_buildTree(this, init->pid, 0, 0, direction, true);
- // Add leftovers
- while (Vector_size(this->processes)) {
- Process* p = (Process*) (Vector_take(this->processes, 0));
- p->indent = 0;
- Vector_add(this->processes2, p);
- ProcessList_buildTree(this, p->pid, 0, 0, direction, p->showChildren);
+ // Find all processes whose parent is not visible
+ int size;
+ while ((size = Vector_size(this->processes))) {
+ int i;
+ for (i = 0; i < size; i++) {
+ Process* process = (Process*)(Vector_get(this->processes, i));
+ // Immediately consume not shown processes
+ if (!process->show) {
+ process = (Process*)(Vector_take(this->processes, i));
+ process->indent = 0;
+ Vector_add(this->processes2, process);
+ ProcessList_buildTree(this, process->pid, 0, 0, direction, false);
+ break;
+ }
+ pid_t ppid = process->tgid == process->pid ? process->ppid : process->tgid;
+ // Bisect the process vector to find parent
+ int l = 0, r = size;
+ while (l < r) {
+ int c = (l + r) / 2;
+ pid_t pid = ((Process*)(Vector_get(this->processes, c)))->pid;
+ if (ppid == pid)
+ break;
+ else if (ppid < pid)
+ r = c;
+ else
+ l = c + 1;
+ }
+ // If parent not found, then construct the tree with this root
+ if (l >= r) {
+ process = (Process*)(Vector_take(this->processes, i));
+ process->indent = 0;
+ Vector_add(this->processes2, process);
+ ProcessList_buildTree(this, process->pid, 0, 0, direction, process->showChildren);
+ break;
+ }
+ }
+ // There should be no loop in the process tree
+ assert(i < size);
}
assert(Vector_size(this->processes2) == vsize); (void)vsize;
assert(Vector_size(this->processes) == 0);

© 2014-2024 Faster IT GmbH | imprint | privacy policy