aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/top/machine.c
diff options
context:
space:
mode:
authorBrian Feldman <green@FreeBSD.org>2004-06-06 19:59:06 +0000
committerBrian Feldman <green@FreeBSD.org>2004-06-06 19:59:06 +0000
commitcac4b14c123c5d25f9633d4ca2aa68d03d4ca74b (patch)
tree41662172a1cde1d24eb2e5a7ad7becc2140530b9 /usr.bin/top/machine.c
parent30e2462c717f1ad47f5a9472841378b008851285 (diff)
downloadsrc-cac4b14c123c5d25f9633d4ca2aa68d03d4ca74b.tar.gz
src-cac4b14c123c5d25f9633d4ca2aa68d03d4ca74b.zip
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.
Notes
Notes: svn path=/head/; revision=130163
Diffstat (limited to 'usr.bin/top/machine.c')
-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 c998081cb1ff..dbf68f0ee21c 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;
+ }
}
}
}