diff options
Diffstat (limited to 'usr.bin/top/machine.c')
-rw-r--r-- | usr.bin/top/machine.c | 180 |
1 files changed, 87 insertions, 93 deletions
diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c index 4c55682..02dc847 100644 --- a/usr.bin/top/machine.c +++ b/usr.bin/top/machine.c @@ -239,19 +239,48 @@ static const char *format_nice(const struct kinfo_proc *pp); static void getsysctl(const char *name, void *ptr, size_t len); static int swapmode(int *retavail, int *retfree); +void +toggle_pcpustats(struct statics *statics) +{ + + if (ncpus == 1) + return; + + /* Adjust display based on ncpus */ + if (pcpu_stats) { + y_mem += ncpus - 1; /* 3 */ + y_swap += ncpus - 1; /* 4 */ + y_idlecursor += ncpus - 1; /* 5 */ + y_message += ncpus - 1; /* 5 */ + y_header += ncpus - 1; /* 6 */ + y_procs += ncpus - 1; /* 7 */ + Header_lines += ncpus - 1; /* 7 */ + statics->ncpus = ncpus; + } else { + y_mem = 3; + y_swap = 4; + y_idlecursor = 5; + y_message = 5; + y_header = 6; + y_procs = 7; + Header_lines = 7; + statics->ncpus = 1; + } +} + int machine_init(struct statics *statics, char do_unames) { - int pagesize; - size_t modelen; + int i, j, empty, pagesize; + size_t size; struct passwd *pw; - modelen = sizeof(smpmode); - if ((sysctlbyname("machdep.smp_active", &smpmode, &modelen, + size = sizeof(smpmode); + if ((sysctlbyname("machdep.smp_active", &smpmode, &size, NULL, 0) != 0 && - sysctlbyname("kern.smp.active", &smpmode, &modelen, + sysctlbyname("kern.smp.active", &smpmode, &size, NULL, 0) != 0) || - modelen != sizeof(smpmode)) + size != sizeof(smpmode)) smpmode = 0; if (do_unames) { @@ -299,51 +328,37 @@ machine_init(struct statics *statics, char do_unames) statics->order_names = ordernames; #endif - /* Adjust display based on ncpus */ - if (pcpu_stats) { - int i, j, empty; - size_t size; - - cpumask = 0; - ncpus = 0; - GETSYSCTL("kern.smp.maxcpus", maxcpu); - size = sizeof(long) * maxcpu * CPUSTATES; - times = malloc(size); - if (times == NULL) - err(1, "malloc %zd bytes", size); - if (sysctlbyname("kern.cp_times", times, &size, NULL, 0) == -1) - err(1, "sysctlbyname kern.cp_times"); - pcpu_cp_time = calloc(1, size); - maxid = (size / CPUSTATES / sizeof(long)) - 1; - for (i = 0; i <= maxid; i++) { - empty = 1; - for (j = 0; empty && j < CPUSTATES; j++) { - if (times[i * CPUSTATES + j] != 0) - empty = 0; - } - if (!empty) { - cpumask |= (1ul << i); - ncpus++; - } + /* Allocate state for per-CPU stats. */ + cpumask = 0; + ncpus = 0; + GETSYSCTL("kern.smp.maxcpus", maxcpu); + size = sizeof(long) * maxcpu * CPUSTATES; + times = malloc(size); + if (times == NULL) + err(1, "malloc %zd bytes", size); + if (sysctlbyname("kern.cp_times", times, &size, NULL, 0) == -1) + err(1, "sysctlbyname kern.cp_times"); + pcpu_cp_time = calloc(1, size); + maxid = (size / CPUSTATES / sizeof(long)) - 1; + for (i = 0; i <= maxid; i++) { + empty = 1; + for (j = 0; empty && j < CPUSTATES; j++) { + if (times[i * CPUSTATES + j] != 0) + empty = 0; } - - if (ncpus > 1) { - y_mem += ncpus - 1; /* 3 */ - y_swap += ncpus - 1; /* 4 */ - y_idlecursor += ncpus - 1; /* 5 */ - y_message += ncpus - 1; /* 5 */ - y_header += ncpus - 1; /* 6 */ - y_procs += ncpus - 1; /* 7 */ - Header_lines += ncpus - 1; /* 7 */ + if (!empty) { + cpumask |= (1ul << i); + ncpus++; } - size = sizeof(long) * ncpus * CPUSTATES; - pcpu_cp_old = calloc(1, size); - pcpu_cp_diff = calloc(1, size); - pcpu_cpu_states = calloc(1, size); - statics->ncpus = ncpus; - } else { - statics->ncpus = 1; } + size = sizeof(long) * ncpus * CPUSTATES; + pcpu_cp_old = calloc(1, size); + pcpu_cp_diff = calloc(1, size); + pcpu_cpu_states = calloc(1, size); + statics->ncpus = 1; + + if (pcpu_stats) + toggle_pcpustats(statics); /* all done! */ return (0); @@ -398,14 +413,11 @@ get_system_info(struct system_info *si) int i, j; size_t size; - /* get the cp_time array */ - if (pcpu_stats) { - size = (maxid + 1) * CPUSTATES * sizeof(long); - if (sysctlbyname("kern.cp_times", pcpu_cp_time, &size, NULL, 0) == -1) - err(1, "sysctlbyname kern.cp_times"); - } else { - GETSYSCTL("kern.cp_time", cp_time); - } + /* get the CPU stats */ + size = (maxid + 1) * CPUSTATES * sizeof(long); + if (sysctlbyname("kern.cp_times", pcpu_cp_time, &size, NULL, 0) == -1) + err(1, "sysctlbyname kern.cp_times"); + GETSYSCTL("kern.cp_time", cp_time); GETSYSCTL("vm.loadavg", sysload); GETSYSCTL("kern.lastpid", lastpid); @@ -413,21 +425,17 @@ get_system_info(struct system_info *si) for (i = 0; i < 3; i++) si->load_avg[i] = (double)sysload.ldavg[i] / sysload.fscale; - if (pcpu_stats) { - for (i = j = 0; i <= maxid; i++) { - if ((cpumask & (1ul << i)) == 0) - continue; - /* convert cp_time counts to percentages */ - percentages(CPUSTATES, &pcpu_cpu_states[j * CPUSTATES], - &pcpu_cp_time[j * CPUSTATES], - &pcpu_cp_old[j * CPUSTATES], - &pcpu_cp_diff[j * CPUSTATES]); - j++; - } - } else { - /* convert cp_time counts to percentages */ - percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff); + /* convert cp_time counts to percentages */ + for (i = j = 0; i <= maxid; i++) { + if ((cpumask & (1ul << i)) == 0) + continue; + percentages(CPUSTATES, &pcpu_cpu_states[j * CPUSTATES], + &pcpu_cp_time[j * CPUSTATES], + &pcpu_cp_old[j * CPUSTATES], + &pcpu_cp_diff[j * CPUSTATES]); + j++; } + percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff); /* sum memory & swap statistics */ { @@ -616,7 +624,6 @@ get_process_info(struct system_info *si, struct process_select *sel, int active_procs; struct kinfo_proc **prefp; struct kinfo_proc *pp; - struct kinfo_proc *prev_pp = NULL; /* these are copied out of sel for speed */ int show_idle; @@ -649,7 +656,8 @@ get_process_info(struct system_info *si, struct process_select *sel, } previous_proc_count = nproc; - pbase = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nproc); + pbase = kvm_getprocs(kd, sel->thread ? KERN_PROC_ALL : KERN_PROC_PROC, + 0, &nproc); if (nproc > onproc) pref = realloc(pref, sizeof(*pref) * (onproc = nproc)); if (pref == NULL || pbase == NULL) { @@ -701,17 +709,16 @@ get_process_info(struct system_info *si, struct process_select *sel, /* skip zombies */ continue; + if (!show_kidle && pp->ki_tdflags & TDF_IDLETD) + /* skip kernel idle process */ + continue; + if (displaymode == DISP_CPU && !show_idle && (pp->ki_pctcpu == 0 || pp->ki_stat == SSTOP || pp->ki_stat == SIDL)) /* skip idle or non-running processes */ continue; - if (displaymode == DISP_CPU && !show_kidle && - pp->ki_tdflags & TDF_IDLETD) - /* skip kernel idle process */ - continue; - if (displaymode == DISP_IO && !show_idle && p_io == 0) /* skip processes that aren't doing I/O */ continue; @@ -720,21 +727,8 @@ get_process_info(struct system_info *si, struct process_select *sel, /* skip proc. that don't belong to the selected UID */ continue; - /* - * 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; - prev_pp->ki_runtime += pp->ki_runtime; - } + *prefp++ = pp; + active_procs++; } /* if requested, sort the "interesting" processes */ @@ -849,7 +843,7 @@ format_next_process(caddr_t handle, char *(*get_userid)(int), int flags) (args = kvm_getargv(kd, pp, cmdlengthdelta)) == NULL || !(*args)) { if (ps.thread && pp->ki_flag & P_HADTHREADS && - pp->ki_ocomm[0]) { + pp->ki_ocomm[0]) { snprintf(cmdbuf, cmdlengthdelta, "{%s}", pp->ki_ocomm); } else { |