summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2014-06-20 19:54:23 +0000
committerjhb <jhb@FreeBSD.org>2014-06-20 19:54:23 +0000
commit8629e7f8c81f716abfe9bc2faf6076382c4a74bf (patch)
tree856559cd5933b2981232abb55d2e9ca2e3835662 /usr.bin
parent16f87e69c815ecd96692abb518ed701106883bb0 (diff)
downloadFreeBSD-src-8629e7f8c81f716abfe9bc2faf6076382c4a74bf.zip
FreeBSD-src-8629e7f8c81f716abfe9bc2faf6076382c4a74bf.tar.gz
Cap the percent CPU of individual threads at 100% to fix some of the
more obvious imprecision in the previous top changes. Specifically, top uses a delta of clock_gettime() calls right after invoking the kern.proc sysctl to fetch the process/thread list to compute the time delta between the fetches. However, the kern.proc sysctl handler does not run in constant time. It can spin on locks, be preempted by an interrupt handler, etc. As a result, the time between the gathering of stats for individual processes or threads between subsequent kern.proc handlers can vary. If a "slow" kern.proc run is followed by a "fast" kern.proc run, then the threads/processes at the start of the "slow" run will have a longer time delta than the threads/processes at the end. If the clock_gettime() time delta is not itself skewed by preemption, then the delta may be too short for a given thread/process resulting in a higher percent CPU than actual. However, there is no good way to calculate the exact amount of overage, nor to know which threads to subtract the overage from. Instead, just punt and fix the definitely-wrong case of an individual thread having more than 100% CPU. Discussed with: zonk
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/top/machine.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c
index 92f6c24..de57b94 100644
--- a/usr.bin/top/machine.c
+++ b/usr.bin/top/machine.c
@@ -850,6 +850,8 @@ get_process_info(struct system_info *si, struct process_select *sel,
continue;
PCTCPU(pp) = proc_calc_pctcpu(pp);
+ if (sel->thread && PCTCPU(pp) > 1.0)
+ PCTCPU(pp) = 1.0;
if (displaymode == DISP_CPU && !show_idle &&
(!proc_used_cpu(pp) ||
pp->ki_stat == SSTOP || pp->ki_stat == SIDL))
OpenPOWER on IntegriCloud