svn commit: r225619 - in stable/8: contrib/top usr.bin/top

John Baldwin jhb at FreeBSD.org
Fri Sep 16 17:39:40 UTC 2011


Author: jhb
Date: Fri Sep 16 17:39:39 2011
New Revision: 225619
URL: http://svn.freebsd.org/changeset/base/225619

Log:
  MFC 223936,224205:
  Allow per-CPU statistics to be toggled at runtime via the 'P' key.
  While here, make -P a toggle similar to other options such as -I.

Modified:
  stable/8/contrib/top/commands.c
  stable/8/contrib/top/display.c
  stable/8/contrib/top/top.X
  stable/8/contrib/top/top.c
  stable/8/usr.bin/top/machine.c
Directory Properties:
  stable/8/contrib/top/   (props changed)
  stable/8/contrib/top/install-sh   (props changed)
  stable/8/usr.bin/top/   (props changed)

Modified: stable/8/contrib/top/commands.c
==============================================================================
--- stable/8/contrib/top/commands.c	Fri Sep 16 14:04:14 2011	(r225618)
+++ stable/8/contrib/top/commands.c	Fri Sep 16 17:39:39 2011	(r225619)
@@ -88,6 +88,7 @@ o       - specify sort order (vcsw, ivcs
 	    stdout);
 #endif
 	fputs("\
+P       - toggle the displaying of per-CPU statistics\n\
 r       - renice a process\n\
 s       - change number of seconds to delay between updates\n\
 S       - toggle the displaying of system processes\n\

Modified: stable/8/contrib/top/display.c
==============================================================================
--- stable/8/contrib/top/display.c	Fri Sep 16 14:04:14 2011	(r225618)
+++ stable/8/contrib/top/display.c	Fri Sep 16 17:39:39 2011	(r225619)
@@ -151,25 +151,50 @@ int display_resize()
     return(smart_terminal ? lines : Largest);
 }
 
-int display_init(statics)
+int display_updatecpus(statics)
 
 struct statics *statics;
 
 {
+    register int *lp;
     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;
+    if (pcpu_stats)
+	num_cpus = statics->ncpus;
+    else
+	num_cpus = 1;
     cpustates_column = 5;	/* CPU: */
     if (num_cpus != 1)
     cpustates_column += 2;	/* CPU 0: */
     for (i = num_cpus; i > 9; i /= 10)
 	cpustates_column++;
 
+    /* fill the "last" array with all -1s, to insure correct updating */
+    lp = lcpustates;
+    i = num_cpustates * num_cpus;
+    while (--i >= 0)
+    {
+	*lp++ = -1;
+    }
+    
+    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)
     {
@@ -184,7 +209,7 @@ struct statics *statics;
 	num_swap = string_count(swap_names);
 	lswap = (int *)malloc(num_swap * sizeof(int));
 	num_cpustates = string_count(cpustate_names);
-	lcpustates = (int *)malloc(num_cpustates * sizeof(int) * num_cpus);
+	lcpustates = (int *)malloc(num_cpustates * sizeof(int) * statics->ncpus);
 	cpustate_columns = (int *)malloc(num_cpustates * sizeof(int));
 
 	memory_names = statics->memory_names;

Modified: stable/8/contrib/top/top.X
==============================================================================
--- stable/8/contrib/top/top.X	Fri Sep 16 14:04:14 2011	(r225618)
+++ stable/8/contrib/top/top.X	Fri Sep 16 17:39:39 2011	(r225619)
@@ -205,6 +205,7 @@ The options
 .BR \-H ,
 .BR \-I ,
 .BR \-j ,
+.BR \-P ,
 .BR \-S ,
 .BR \-t ,
 .BR \-u ,
@@ -314,6 +315,9 @@ Toggle the display of
 .IR jail (8)
 ID.
 .TP
+.B P
+Toggle the display of per-CPU statistics.
+.TP
 .B t
 Toggle the display of the
 .I top

Modified: stable/8/contrib/top/top.c
==============================================================================
--- stable/8/contrib/top/top.c	Fri Sep 16 14:04:14 2011	(r225618)
+++ stable/8/contrib/top/top.c	Fri Sep 16 17:39:39 2011	(r225619)
@@ -196,9 +196,9 @@ char *argv[];
     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 @@ char *argv[];
 #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 @@ char *argv[];
 		break;
 
 	      case 'P':
-		pcpu_stats = Yes;
+		pcpu_stats = !pcpu_stats;
 		break;
 
 	      case 'z':
@@ -1088,6 +1089,16 @@ restart:
 				    ps.kidle ? "D" : "Not d");
 				putchar('\r');
 				break;
+			    case CMD_pcputog:
+				pcpu_stats = !pcpu_stats;
+				new_message(MT_standout | MT_delayed,
+				    " Displaying %sCPU statistics.",
+				    pcpu_stats ? "per-" : "global ");
+				toggle_pcpustats();
+				max_topn = display_updatecpus(&statics);
+				reset_display();
+				putchar('\r');
+				break;
 			    default:
 				new_message(MT_standout, " BAD CASE IN SWITCH!");
 				putchar('\r');

Modified: stable/8/usr.bin/top/machine.c
==============================================================================
--- stable/8/usr.bin/top/machine.c	Fri Sep 16 14:04:14 2011	(r225618)
+++ stable/8/usr.bin/top/machine.c	Fri Sep 16 17:39:39 2011	(r225619)
@@ -239,19 +239,46 @@ static const char *format_nice(const str
 static void getsysctl(const char *name, void *ptr, size_t len);
 static int swapmode(int *retavail, int *retfree);
 
+void
+toggle_pcpustats(void)
+{
+
+	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 */
+	} else {
+		y_mem = 3;
+		y_swap = 4;
+		y_idlecursor = 5;
+		y_message = 5;
+		y_header = 6;
+		y_procs = 7;
+		Header_lines = 7;
+	}
+}
+
 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 +326,37 @@ machine_init(struct statics *statics, ch
 	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 = ncpus;
+
+	if (pcpu_stats)
+		toggle_pcpustats();
 
 	/* all done! */
 	return (0);
@@ -398,14 +411,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 +423,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 */
 	{


More information about the svn-src-all mailing list