Author: jhb
Date: Mon Jul 11 16:48:52 2011
New Revision: 223936
URL: http://svn.freebsd.org/changeset/base/223936

Log:
  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.
  
  Reviewed by:  arundel
  MFC after:    1 week

Modified:
  head/contrib/top/commands.c
  head/contrib/top/display.c
  head/contrib/top/top.X
  head/contrib/top/top.c
  head/usr.bin/top/machine.c

Modified: head/contrib/top/commands.c
==============================================================================
--- head/contrib/top/commands.c Mon Jul 11 14:15:27 2011        (r223935)
+++ head/contrib/top/commands.c Mon Jul 11 16:48:52 2011        (r223936)
@@ -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: head/contrib/top/display.c
==============================================================================
--- head/contrib/top/display.c  Mon Jul 11 14:15:27 2011        (r223935)
+++ head/contrib/top/display.c  Mon Jul 11 16:48:52 2011        (r223936)
@@ -151,16 +151,14 @@ int display_resize()
     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 @@ struct statics *statics;
     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)
     {

Modified: head/contrib/top/top.X
==============================================================================
--- head/contrib/top/top.X      Mon Jul 11 14:15:27 2011        (r223935)
+++ head/contrib/top/top.X      Mon Jul 11 16:48:52 2011        (r223936)
@@ -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: head/contrib/top/top.c
==============================================================================
--- head/contrib/top/top.c      Mon Jul 11 14:15:27 2011        (r223935)
+++ head/contrib/top/top.c      Mon Jul 11 16:48:52 2011        (r223936)
@@ -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(&statics);
+                               max_topn = display_updatecpus(&statics);
+                               reset_display();
+                               putchar('\r');
+                               break;
                            default:
                                new_message(MT_standout, " BAD CASE IN 
SWITCH!");
                                putchar('\r');

Modified: head/usr.bin/top/machine.c
==============================================================================
--- head/usr.bin/top/machine.c  Mon Jul 11 14:15:27 2011        (r223935)
+++ head/usr.bin/top/machine.c  Mon Jul 11 16:48:52 2011        (r223936)
@@ -239,19 +239,48 @@ 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(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, 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 = 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 */
        {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to