summaryrefslogtreecommitdiffstats
path: root/usr.bin/top
diff options
context:
space:
mode:
authorgreen <green@FreeBSD.org>2004-06-06 19:59:06 +0000
committergreen <green@FreeBSD.org>2004-06-06 19:59:06 +0000
commit5c9b04429a84b964e9619870accf1c4b6209412a (patch)
tree41662172a1cde1d24eb2e5a7ad7becc2140530b9 /usr.bin/top
parenteead69e718d0d157cfa225811cc0c07966cce730 (diff)
downloadFreeBSD-src-5c9b04429a84b964e9619870accf1c4b6209412a.zip
FreeBSD-src-5c9b04429a84b964e9619870accf1c4b6209412a.tar.gz
Do not use KERN_PROC_PROC with kvm_getproc(3); instead, if only process
(and not thread) scope is to be displayed, use KERN_PROC_ALL and accrue CPU% ourselves, as the kernel makes no attempt to do so. Of course, this doesn't make most stats any less bogus when displaying threaded processes, but at least the CPU time is added up and not just always 0.00%. There are still issues with SCHED_ULE in top(1) that cause other processes to display 0.00% CPU when they in fact have used more.
Diffstat (limited to 'usr.bin/top')
-rw-r--r--usr.bin/top/machine.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c
index c998081..dbf68f0 100644
--- a/usr.bin/top/machine.c
+++ b/usr.bin/top/machine.c
@@ -405,6 +405,7 @@ int (*compare)();
register int active_procs;
register struct kinfo_proc **prefp;
register struct kinfo_proc *pp;
+ struct kinfo_proc *prev_pp = NULL;
/* these are copied out of sel for speed */
int show_idle;
@@ -414,8 +415,7 @@ int (*compare)();
int show_command;
- pbase = kvm_getprocs(kd, sel->thread ? KERN_PROC_ALL : KERN_PROC_PROC,
- 0, &nproc);
+ pbase = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc);
if (nproc > onproc)
pref = (struct kinfo_proc **) realloc(pref, sizeof(struct kinfo_proc *)
* (onproc = nproc));
@@ -457,8 +457,21 @@ int (*compare)();
(pp->ki_stat == SRUN)) &&
(!show_uid || pp->ki_ruid == (uid_t)sel->uid))
{
- *prefp++ = pp;
- active_procs++;
+ /*
+ * When not showing threads, take the first thread
+ * for output and add the fields that we can from
+ * the rest of the process's threads rather than
+ * using the system's mostly-broken KERN_PROC_PROC.
+ */
+ if (sel->thread || prev_pp == NULL ||
+ prev_pp->ki_pid != pp->ki_pid)
+ {
+ *prefp++ = pp;
+ active_procs++;
+ prev_pp = pp;
+ } else {
+ prev_pp->ki_pctcpu += pp->ki_pctcpu;
+ }
}
}
}
OpenPOWER on IntegriCloud