On Sat, Oct 12, 2019 at 05:38:13PM -0500, Scott Cheloha wrote: > Also, just count how many spaces we need to print ncpuonline, > then use that when printing the individual CPU lines. Yup, here's a minimal diff that does that without additional buffers and globals but a single local static padding; it's definition looks lengthy but that's what makes it nicely obvious (imho).
Only downside compared to your diff is that we still assume machines to have less than 1000 cores, that is keep combined stats at fixed "%-3d", but that seems fairly acceptable to me. Overall, this keeps the combined line unchanged; the per CPU lines merely omits " states" and pads spaces after the double colon: On an amd64 X230: 4 CPUs: 2.4% user, 0.0% nice, 0.6% sys, 0.0% spin, 0.0% intr, 97.0% idle CPU0: 2.7% user, 0.0% nice, 2.0% sys, 1.4% spin, 0.2% intr, 93.6% idle CPU3: 3.2% user, 0.0% nice, 2.7% sys, 1.2% spin, 0.0% intr, 92.9% idle On an sparc64 T5240: 32 CPUs: 0.1% user, 0.0% nice, 0.2% sys, 0.0% spin, 0.0% intr, 99.7% idle CPU00: 0.0% user, 0.0% nice, 0.0% sys, 0.6% spin, 0.2% intr, 99.2% idle CPU31: 0.0% user, 0.0% nice, 0.0% sys, 0.0% spin, 0.0% intr, 100% idle Single core machines are no longer specially accounted, but here the per CPU lines only changes from "CPU:" to "CPU0:": VMM: 1 CPUs: 0.0% user, 0.0% nice, 0.0% sys, 0.0% spin, 100% intr, 0.0% idle CPU0: 0.0% user, 0.0% nice, 0.0% sys, 0.0% spin, 100% intr, 0.0% idle Feedback? Objections? OK? Index: display.c =================================================================== RCS file: /cvs/src/usr.bin/top/display.c,v retrieving revision 1.60 diff -u -p -r1.60 display.c --- display.c 8 Oct 2019 07:26:59 -0000 1.60 +++ display.c 12 Oct 2019 23:56:14 -0000 @@ -72,7 +72,7 @@ FILE *debug; static int display_width = MAX_COLS; -static char *cpustates_tag(int); +static void cpustates_tag(int); static int string_count(char **); static void summary_format(char *, size_t, int *, char **); static int readlinedumb(char *, int); @@ -334,45 +334,24 @@ i_procstates(int total, int *states, int */ /* cpustates_tag() calculates the correct tag to use to label the line */ - -static char * +static void cpustates_tag(int cpu) { if (screen_length > 3 || !smart_terminal) { - static char *tag; - static int cpulen, old_width; + static int cpulen, padding; int i; - if (cpulen == 0 && ncpu > 1) { + if (cpulen == 0) { /* compute length of the cpu string */ for (i = ncpu; i > 0; cpulen++, i /= 10) continue; + /* difference between per cpu and combined lines */ + padding = strlen("xxx CPUs: ") - + (strlen("CPU") + cpulen + strlen(": ")); } - - if (old_width == screen_width) { - if (ncpu > 1) { - /* just store the cpu number in the tag */ - i = tag[3 + cpulen]; - snprintf(tag + 3, cpulen + 1, "%.*d", cpulen, cpu); - tag[3 + cpulen] = i; - } - } else { - /* - * use a long tag if it will fit, otherwise use short one. - */ - free(tag); - if (cpustate_total_length + 10 + cpulen >= screen_width) - i = asprintf(&tag, "CPU%.*d: ", cpulen, cpu); - else - i = asprintf(&tag, "CPU%.*d states: ", cpulen, cpu); - if (i == -1) - tag = NULL; - else - old_width = screen_width; - } - return (tag); + printwp("CPU%0*d: %*s", cpulen, cpu, padding, ""); } else - return ("\0"); + addstrp(""); } void @@ -438,7 +417,7 @@ i_cpustates(int64_t *ostates, int *onlin if (screen_length > 2 + cpu_line || !smart_terminal) { move(2 + cpu_line, 0); clrtoeol(); - addstrp(cpustates_tag(cpu)); + cpustates_tag(cpu); while ((thisname = *names++) != NULL) { if (*thisname != '\0') {