Rework the dynamic per-CPU stats code a bit. Always set 'statics->ncpus'

to the maximum number of CPUs to ensure that lcpustates[] array is always
allocated to the maximum size.  Previously, if top was started without
per-CPU stats it would allocate a smaller lcpustates[] array.  When
per-CPU stats were then enabled, it would overflow the array and trash
the cpustates_columns[] array causing the CPU stats to be printed in the
wrong locations.

Approved by:	re (kib)
MFC after:	1 week
This commit is contained in:
John Baldwin 2011-07-18 21:15:47 +00:00
parent 834377fe2d
commit fcc3d62fa5
3 changed files with 18 additions and 8 deletions

View File

@ -156,18 +156,30 @@ int display_updatecpus(statics)
struct statics *statics; struct statics *statics;
{ {
register int *lp;
register int lines; register int lines;
register int i; register int i;
/* call resize to do the dirty work */ /* call resize to do the dirty work */
lines = display_resize(); lines = display_resize();
num_cpus = statics->ncpus; if (pcpu_stats)
num_cpus = statics->ncpus;
else
num_cpus = 1;
cpustates_column = 5; /* CPU: */ cpustates_column = 5; /* CPU: */
if (num_cpus != 1) if (num_cpus != 1)
cpustates_column += 2; /* CPU 0: */ cpustates_column += 2; /* CPU 0: */
for (i = num_cpus; i > 9; i /= 10) for (i = num_cpus; i > 9; i /= 10)
cpustates_column++; 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); return(lines);
} }
@ -197,7 +209,7 @@ struct statics *statics;
num_swap = string_count(swap_names); num_swap = string_count(swap_names);
lswap = (int *)malloc(num_swap * sizeof(int)); lswap = (int *)malloc(num_swap * sizeof(int));
num_cpustates = string_count(cpustate_names); 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)); cpustate_columns = (int *)malloc(num_cpustates * sizeof(int));
memory_names = statics->memory_names; memory_names = statics->memory_names;

View File

@ -1094,7 +1094,7 @@ restart:
new_message(MT_standout | MT_delayed, new_message(MT_standout | MT_delayed,
" Displaying %sCPU statistics.", " Displaying %sCPU statistics.",
pcpu_stats ? "per-" : "global "); pcpu_stats ? "per-" : "global ");
toggle_pcpustats(&statics); toggle_pcpustats();
max_topn = display_updatecpus(&statics); max_topn = display_updatecpus(&statics);
reset_display(); reset_display();
putchar('\r'); putchar('\r');

View File

@ -241,7 +241,7 @@ static void getsysctl(const char *name, void *ptr, size_t len);
static int swapmode(int *retavail, int *retfree); static int swapmode(int *retavail, int *retfree);
void void
toggle_pcpustats(struct statics *statics) toggle_pcpustats(void)
{ {
if (ncpus == 1) if (ncpus == 1)
@ -256,7 +256,6 @@ toggle_pcpustats(struct statics *statics)
y_header += ncpus - 1; /* 6 */ y_header += ncpus - 1; /* 6 */
y_procs += ncpus - 1; /* 7 */ y_procs += ncpus - 1; /* 7 */
Header_lines += ncpus - 1; /* 7 */ Header_lines += ncpus - 1; /* 7 */
statics->ncpus = ncpus;
} else { } else {
y_mem = 3; y_mem = 3;
y_swap = 4; y_swap = 4;
@ -265,7 +264,6 @@ toggle_pcpustats(struct statics *statics)
y_header = 6; y_header = 6;
y_procs = 7; y_procs = 7;
Header_lines = 7; Header_lines = 7;
statics->ncpus = 1;
} }
} }
@ -356,10 +354,10 @@ machine_init(struct statics *statics, char do_unames)
pcpu_cp_old = calloc(1, size); pcpu_cp_old = calloc(1, size);
pcpu_cp_diff = calloc(1, size); pcpu_cp_diff = calloc(1, size);
pcpu_cpu_states = calloc(1, size); pcpu_cpu_states = calloc(1, size);
statics->ncpus = 1; statics->ncpus = ncpus;
if (pcpu_stats) if (pcpu_stats)
toggle_pcpustats(statics); toggle_pcpustats();
/* all done! */ /* all done! */
return (0); return (0);