From owner-freebsd-current@FreeBSD.ORG Fri Jul 8 19:11:45 2011 Return-Path: Delivered-To: current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 333761065675; Fri, 8 Jul 2011 19:11:45 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from cyrus.watson.org (cyrus.watson.org [65.122.17.42]) by mx1.freebsd.org (Postfix) with ESMTP id D163B8FC1C; Fri, 8 Jul 2011 19:11:44 +0000 (UTC) Received: from bigwig.baldwin.cx (66.111.2.69.static.nyinternet.net [66.111.2.69]) by cyrus.watson.org (Postfix) with ESMTPSA id 6D93546B29; Fri, 8 Jul 2011 15:11:44 -0400 (EDT) Received: from jhbbsd.localnet (unknown [209.249.190.124]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id 031488A02C; Fri, 8 Jul 2011 15:11:44 -0400 (EDT) From: John Baldwin To: current@freebsd.org Date: Fri, 8 Jul 2011 15:11:43 -0400 User-Agent: KMail/1.13.5 (FreeBSD/8.2-CBSD-20110617; KDE/4.5.5; amd64; ; ) MIME-Version: 1.0 Content-Type: Text/Plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Message-Id: <201107081511.43417.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.6 (bigwig.baldwin.cx); Fri, 08 Jul 2011 15:11:44 -0400 (EDT) Cc: edwin@freebsd.org Subject: [PATCH] Make top -P an interactive toggle X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Jul 2011 19:11:45 -0000 This patch lets you use 'P' while top is running to toggle between per-CPU and global CPU stats. Index: contrib/top/top.c =================================================================== --- contrib/top/top.c (revision 223873) +++ contrib/top/top.c (working copy) @@ -196,9 +196,9 @@ fd_set readfds; #ifdef ORDER - static char command_chars[] = "\f qh?en#sdkriIutHmSCajzo"; + static char command_chars[] = "\f qh?en#sdkriIutHmSCajzPo"; #else - static char command_chars[] = "\f qh?en#sdkriIutHmSCajz"; + static char command_chars[] = "\f qh?en#sdkriIutHmSCajzP"; #endif /* these defines enumerate the "strchr"s of the commands in command_chars */ #define CMD_redraw 0 @@ -225,8 +225,9 @@ #define CMD_showargs 20 #define CMD_jidtog 21 #define CMD_kidletog 22 +#define CMD_pcputog 23 #ifdef ORDER -#define CMD_order 23 +#define CMD_order 24 #endif /* set the buffer for stdout */ @@ -411,7 +412,7 @@ break; case 'P': - pcpu_stats = Yes; + pcpu_stats = !pcpu_stats; break; case 'z': @@ -1088,6 +1089,12 @@ ps.kidle ? "D" : "Not d"); putchar('\r'); break; + case CMD_pcputog: + pcpu_stats = !pcpu_stats; + toggle_pcpustats(&statics); + max_topn = display_updatecpus(&statics); + reset_display(); + break; default: new_message(MT_standout, " BAD CASE IN SWITCH!"); putchar('\r'); Index: contrib/top/display.c =================================================================== --- contrib/top/display.c (revision 223873) +++ contrib/top/display.c (working copy) @@ -151,16 +151,14 @@ return(smart_terminal ? lines : Largest); } -int display_init(statics) +int display_updatecpus(statics) struct statics *statics; { register int lines; - register char **pp; - register int *ip; register int i; - + /* call resize to do the dirty work */ lines = display_resize(); num_cpus = statics->ncpus; @@ -170,6 +168,21 @@ for (i = num_cpus; i > 9; i /= 10) cpustates_column++; + return(lines); +} + +int display_init(statics) + +struct statics *statics; + +{ + register int lines; + register char **pp; + register int *ip; + register int i; + + lines = display_updatecpus(statics); + /* only do the rest if we need to */ if (lines > -1) { Index: contrib/top/top.X =================================================================== --- contrib/top/top.X (revision 223873) +++ contrib/top/top.X (working copy) @@ -205,6 +205,7 @@ .BR \-H , .BR \-I , .BR \-j , +.BR \-P , .BR \-S , .BR \-t , .BR \-u , @@ -314,6 +315,9 @@ .IR jail (8) ID. .TP +.B P +Toggle the display of per-CPU statistics. +.TP .B t Toggle the display of the .I top Index: usr.bin/top/machine.c =================================================================== --- usr.bin/top/machine.c (revision 223873) +++ usr.bin/top/machine.c (working copy) @@ -239,19 +239,48 @@ 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,52 +328,38 @@ 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 @@ 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 @@ 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 */ { -- John Baldwin