The good news is you just bought a new 32 processor machine.
The bad news is now you can't afford a monitor big enough to run top.
Fortunately, help is on the way. Patch below combines all cpu states into
a single line, for that "classic" top look even on the most impressive of
modern hardware.
Index: display.c
===================================================================
RCS file: /home/tedu/cvs/src/usr.bin/top/display.c,v
retrieving revision 1.33
diff -u -r1.33 display.c
--- display.c 30 Nov 2007 10:39:01 -0000 1.33
+++ display.c 7 Dec 2009 05:42:23 -0000
@@ -87,12 +87,8 @@
static char **cpustate_names;
static char **memory_names;
-static int num_procstates;
static int num_cpustates;
-static int *lprocstates;
-static int64_t **lcpustates;
-
static int *cpustate_columns;
static int cpustate_total_length;
@@ -103,6 +99,7 @@
int y_idlecursor;
int y_procs;
extern int ncpu;
+extern int combine_cpus;
int Header_lines;
int header_status = Yes;
@@ -133,7 +130,7 @@
/* if operating in "dumb" mode, we only need one line */
display_lines = smart_terminal ? screen_length - Header_lines : 1;
- y_idlecursor = y_message = 3 + ncpu;
+ y_idlecursor = y_message = 3 + (combine_cpus ? 1 : ncpu);
if (screen_length <= y_message)
y_idlecursor = y_message = screen_length - 1;
@@ -154,7 +151,8 @@
int
display_init(struct statics * statics)
{
- int display_lines, *ip, i, cpu;
+ int display_lines, *ip, i;
+ int cpu_lines = (combine_cpus ? 1 : ncpu);
char **pp;
if (smart_terminal) {
@@ -169,10 +167,10 @@
standendp = empty;
}
- y_mem = 2 + ncpu;
- y_header = 4 + ncpu;
- y_procs = 5 + ncpu;
- Header_lines = 5 + ncpu;
+ y_mem = 2 + cpu_lines;
+ y_header = 4 + cpu_lines;
+ y_procs = 5 + cpu_lines;
+ Header_lines = 5 + cpu_lines;
/* call resize to do the dirty work */
display_lines = display_resize();
@@ -180,21 +178,9 @@
/* only do the rest if we need to */
/* save pointers and allocate space for names */
procstate_names = statics->procstate_names;
- num_procstates = string_count(procstate_names);
- lprocstates = calloc(num_procstates, sizeof(int));
- if (lprocstates == NULL)
- err(1, NULL);
cpustate_names = statics->cpustate_names;
num_cpustates = string_count(cpustate_names);
- lcpustates = calloc(ncpu, sizeof(int64_t *));
- if (lcpustates == NULL)
- err(1, NULL);
- for (cpu = 0; cpu < ncpu; cpu++) {
- lcpustates[cpu] = calloc(num_cpustates, sizeof(int64_t));
- if (lcpustates[cpu] == NULL)
- err(1, NULL);
- }
cpustate_columns = calloc(num_cpustates, sizeof(int));
if (cpustate_columns == NULL)
@@ -354,20 +340,61 @@
}
return (tag);
} else
- return ('\0');
+ return ("\0");
}
void
i_cpustates(int64_t *ostates)
{
- int i, cpu, value;
+ int i, first, cpu;
+ double value;
int64_t *states;
- char **names = cpustate_names, *thisname;
+ char **names, *thisname;
+
+ if (combine_cpus) {
+ static double *values;
+ if (!values) {
+ values = calloc(num_cpustates, sizeof(*values));
+ if (!values)
+ err(1, NULL);
+ }
+ memset(values, 0, num_cpustates * sizeof(*values));
+ for (cpu = 0; cpu < ncpu; cpu++) {
+ names = cpustate_names;
+ states = ostates + (CPUSTATES * cpu);
+ i = 0;
+ while ((thisname = *names++) != NULL) {
+ if (*thisname != '\0') {
+ /* retrieve the value and remember it */
+ values[i++] += *states++;
+ }
+ }
+ }
+ if (screen_length > 2 || !smart_terminal) {
+ names = cpustate_names;
+ i = 0;
+ first = 0;
+ move(2, 0);
+ clrtoeol();
+ addstrp("All CPUs: ");
+ while ((thisname = *names++) != NULL) {
+ if (*thisname != '\0') {
+ value = values[i++] / ncpu;
+ /* if percentage is >= 1000, print it
as 100% */
+ printwp((value >= 1000 ? "%s%4.0f%% %s"
:
+ "%s%4.1f%% %s"), first++ == 0 ? ""
: ", ",
+ value / 10., thisname);
+ }
+ }
+ putn();
+ }
+ return;
+ }
for (cpu = 0; cpu < ncpu; cpu++) {
/* now walk thru the names and print the line */
names = cpustate_names;
- i = 0;
+ first = 0;
states = ostates + (CPUSTATES * cpu);
if (screen_length > 2 + cpu || !smart_terminal) {
@@ -382,8 +409,8 @@
/* if percentage is >= 1000, print it
as 100% */
printwp((value >= 1000 ? "%s%4.0f%% %s"
:
- "%s%4.1f%% %s"), i++ == 0 ? "" : ",
",
- ((float) value) / 10., thisname);
+ "%s%4.1f%% %s"), first++ == 0 ? ""
: ", ",
+ value / 10., thisname);
}
}
putn();
Index: top.1
===================================================================
RCS file: /home/tedu/cvs/src/usr.bin/top/top.1,v
retrieving revision 1.50
diff -u -r1.50 top.1
--- top.1 17 Nov 2007 09:29:59 -0000 1.50
+++ top.1 7 Dec 2009 05:40:34 -0000
@@ -32,7 +32,7 @@
.Sh SYNOPSIS
.Nm top
.Bk -words
-.Op Fl bCIinqSTu
+.Op Fl bCcIinqSTu
.Op Fl d Ar count
.Op Fl g Ar string
.Op Fl o Ar field
@@ -88,6 +88,8 @@
.It Fl C
Show command line arguments
as well as the process itself.
+.It Fl c
+Combine all CPU lines into a single line.
.It Fl d Ar count
Show only
.Ar count
Index: top.c
===================================================================
RCS file: /home/tedu/cvs/src/usr.bin/top/top.c,v
retrieving revision 1.67
diff -u -r1.67 top.c
--- top.c 18 Jul 2009 06:12:41 -0000 1.67
+++ top.c 7 Dec 2009 05:48:30 -0000
@@ -83,6 +83,7 @@
int old_threads = No;
int show_args = No;
pid_t hlpid = -1;
+int combine_cpus = 0;
#if Default_TOPN == Infinity
char topn_specified = No;
@@ -123,7 +124,7 @@
extern char *__progname;
fprintf(stderr,
- "usage: %s [-bCIinqSTu] [-d count] [-g string] [-o field] "
+ "usage: %s [-bCcIinqSTu] [-d count] [-g string] [-o field] "
"[-p pid] [-s time]\n\t[-U user] [number]\n",
__progname);
}
@@ -134,12 +135,14 @@
char *endp;
int i;
- while ((i = getopt(ac, av, "STICbinqus:d:p:U:o:g:")) != -1) {
+ while ((i = getopt(ac, av, "STICbcinqus:d:p:U:o:g:")) != -1) {
switch (i) {
case 'C':
show_args = Yes;
break;
-
+ case 'c':
+ combine_cpus = 1;
+ break;
case 'u': /* toggle uid/username display */
do_unames = !do_unames;
break;