Toggling between combined and per CPU statistics always causes the state values to jump left or right; to make matters worse, if the window is wider than 80 columns, per CPU lines start with "CPUx states:" instead of "CPUx:". Examples of all three cases:
4 CPUs: 0.3% user, 0.0% nice, 0.6% sys, 0.3% spin, 0.3% intr, 98.5% idle CPU0: 0.0% user, 0.0% nice, 0.9% sys, 0.0% spin, 0.9% intr, 98.2% idle CPU1: 1.7% user, 0.0% nice, 1.7% sys, 0.0% spin, 0.0% intr, 96.5% idle CPU2: 0.0% user, 0.0% nice, 0.0% sys, 0.0% spin, 0.0% intr, 100% idle CPU3: 0.0% user, 0.0% nice, 0.0% sys, 0.0% spin, 0.0% intr, 100% idle CPU0 states: 0.0% user, 0.0% nice, 0.0% sys, 0.0% spin, 1.6% intr, 98.4% idle CPU1 states: 0.4% user, 0.0% nice, 0.4% sys, 0.2% spin, 0.0% intr, 99.0% idle CPU2 states: 1.8% user, 0.0% nice, 0.0% sys, 0.0% spin, 0.0% intr, 98.2% idle CPU3 states: 0.0% user, 0.0% nice, 0.2% sys, 0.0% spin, 0.0% intr, 99.8% idle Such jumps are needlessly stressing the (read: my) eye; looking at the code does even more so and I fail to see any gain in such complicated logic. Diff below makes per CPU statistic lines be as wide as the combined one and no longer print "states" on wide windows: 4 CPUs: 0.7% user, 0.0% nice, 0.0% sys, 0.0% spin, 0.0% intr, 99.3% idle CPU 0: 0.0% user, 0.0% nice, 0.0% sys, 0.0% spin, 0.0% intr, 100% idle CPU 1: 0.0% user, 0.0% nice, 0.0% sys, 0.0% spin, 0.0% intr, 100% idle CPU 2: 0.0% user, 0.0% nice, 2.2% sys, 0.0% spin, 0.0% intr, 97.8% idle CPU 3: 0.0% user, 0.0% nice, 0.0% sys, 0.0% spin, 0.0% intr, 100% idle This way cpustates_tag(), which produces the text up to the double colon, can simply print to the curses window itself immediately instead of returning a dynamically allocated string back to the only caller format_next_process(), which merely prints it to the curses window without any handling in between. 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 09:53:57 -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); @@ -335,44 +335,16 @@ 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; - int i; - - if (cpulen == 0 && ncpu > 1) { - /* compute length of the cpu string */ - for (i = ncpu; i > 0; cpulen++, i /= 10) - continue; - } - - 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); + if (ncpu > 1) + printwp("CPU %3d: ", cpu); + else + addstrp("CPU : "); } else - return ("\0"); + addstrp("\0"); } void @@ -438,7 +410,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') {