From 2ee50d030178cede83eb9d0005fbc19f819d30fe Mon Sep 17 00:00:00 2001 From: Graham Inggs Date: Mon, 5 Feb 2018 14:48:51 +0200 Subject: Imported Upstream version 2.1.0 --- ProcessList.c | 62 +++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 17 deletions(-) (limited to 'ProcessList.c') diff --git a/ProcessList.c b/ProcessList.c index a49b4f1..48b2d95 100644 --- a/ProcessList.c +++ b/ProcessList.c @@ -173,7 +173,7 @@ static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int i for (int i = Vector_size(this->processes) - 1; i >= 0; i--) { Process* process = (Process*) (Vector_get(this->processes, i)); - if (process->show && (process->tgid == pid || (process->tgid == process->pid && process->ppid == pid))) { + if (process->show && Process_isChildOf(process, pid)) { process = (Process*) (Vector_take(this->processes, i)); Vector_add(children, process); } @@ -213,23 +213,51 @@ 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; + // If PID corresponds with PPID (e.g. "kernel_task" (PID:0, PPID:0) + // on Mac OS X 10.11.6) cancel bisecting and regard this process as + // root. + if (process->pid == ppid) + r = 0; + 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); -- cgit v1.2.3