aboutsummaryrefslogtreecommitdiffstats
path: root/ProcessList.c
diff options
context:
space:
mode:
authorGraham Inggs <ginggs@debian.org>2018-02-05 14:48:51 +0200
committerGraham Inggs <ginggs@debian.org>2018-02-05 14:48:51 +0200
commit2ee50d030178cede83eb9d0005fbc19f819d30fe (patch)
tree67d75c0a7c47e15bed9d0735ecf12abec4f8157b /ProcessList.c
parent31b71b67011fa52f091df6fe536a11d6d0bfb256 (diff)
downloaddebian_htop-2ee50d030178cede83eb9d0005fbc19f819d30fe.tar.gz
debian_htop-2ee50d030178cede83eb9d0005fbc19f819d30fe.tar.bz2
debian_htop-2ee50d030178cede83eb9d0005fbc19f819d30fe.zip
Imported Upstream version 2.1.0upstream/2.1.0
Diffstat (limited to 'ProcessList.c')
-rw-r--r--ProcessList.c62
1 files changed, 45 insertions, 17 deletions
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);

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