From 368d76456bba0368457c8068937a2ba4ea81033e Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 18 Jan 2008 01:43:14 +0000 Subject: Add a -P flag to display per-cpu cpu usage stats. --- usr.bin/top/machine.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 5 deletions(-) (limited to 'usr.bin/top') diff --git a/usr.bin/top/machine.c b/usr.bin/top/machine.c index d6fa14c..5e7579b 100644 --- a/usr.bin/top/machine.c +++ b/usr.bin/top/machine.c @@ -51,6 +51,7 @@ #include "machine.h" #include "screen.h" #include "utils.h" +#include "layout.h" #define GETSYSCTL(name, var) getsysctl(name, &(var), sizeof(var)) #define SMPUNAMELEN 13 @@ -220,6 +221,17 @@ char *ordernames[] = { }; #endif +/* Per-cpu time states */ +static int maxcpu; +static int maxid; +static int ncpus; +static u_long cpumask; +static long *times; +static long *pcpu_cp_time; +static long *pcpu_cp_old; +static long *pcpu_cp_diff; +static int *pcpu_cpu_states; + static int compare_jid(const void *a, const void *b); static int compare_pid(const void *a, const void *b); static const char *format_nice(const struct kinfo_proc *pp); @@ -286,6 +298,56 @@ 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"); + 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++; + } + } + + 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 */ + } + size = sizeof(long) * ncpus * CPUSTATES; + pcpu_cp_time = malloc(size); + pcpu_cp_old = malloc(size); + pcpu_cp_diff = malloc(size); + pcpu_cpu_states = malloc(size); + bzero(pcpu_cp_time, size); + bzero(pcpu_cp_old, size); + bzero(pcpu_cp_diff, size); + bzero(pcpu_cpu_states, size); + statics->ncpus = ncpus; + } else { + statics->ncpus = 1; + } + /* all done! */ return (0); } @@ -327,6 +389,7 @@ static int swappgsin = -1; static int swappgsout = -1; extern struct timeval timeout; + void get_system_info(struct system_info *si) { @@ -335,10 +398,17 @@ get_system_info(struct system_info *si) int mib[2]; struct timeval boottime; size_t bt_size; - int i; + int i, j; + size_t size; /* get the cp_time array */ - GETSYSCTL("kern.cp_time", cp_time); + 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); + } GETSYSCTL("vm.loadavg", sysload); GETSYSCTL("kern.lastpid", lastpid); @@ -346,8 +416,20 @@ get_system_info(struct system_info *si) for (i = 0; i < 3; i++) si->load_avg[i] = (double)sysload.ldavg[i] / sysload.fscale; - /* convert cp_time counts to percentages */ - total = percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff); + if (pcpu_stats) { + for (i = j = 0; i <= maxid; i++, j++) { + 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]); + } + } else { + /* convert cp_time counts to percentages */ + percentages(CPUSTATES, cpu_states, cp_time, cp_old, cp_diff); + } /* sum memory & swap statistics */ { @@ -401,7 +483,15 @@ get_system_info(struct system_info *si) } /* set arrays and strings */ - si->cpustates = cpu_states; + if (pcpu_stats) { + si->cpustates = pcpu_cpu_states; + si->cpumask = cpumask; + si->ncpus = ncpus; + } else { + si->cpustates = cpu_states; + si->cpumask = 1; + si->ncpus = 1; + } si->memory = memory_stats; si->swap = swap_stats; -- cgit v1.1