top: tolerate loss of smp cpus, improve CPU_t management

Prior to this patch, top was able to handle any hotplugged
cpus *added* to the system in two distinct ways.

 1) Newly added cpus would be detected by sysinfo_refresh
    calling the library's cpuinfo function, which occurs
    at most every 5 minutes.

 2) The user could force a refresh using either the
    <Enter> or <Space> keys.

Unfortunately, the *loss* of a cpu would produce an early
exit due to a /proc/stat read failure.  Such a failure
can be produced in the following way:
  sudo echo 0 > /sys/devices/system/cpu/cpu??/online

This commit allows top to tolerate the loss of cpus.
It also provides for more efficient CPU_t management,
especially for massively parallel cpu environments.

Note: Changes to the cpu compliment can produce a single
cycle distortion of cpu percentages.  Such distortion is
most visible when each cpu is being displayed.  It can
be eliminated with a forced refresh via <Enter>/<Space>.
This commit is contained in:
Jim Warner
2012-02-01 00:00:00 -06:00
committed by Craig Small
parent d7c986cd30
commit f348575edc
2 changed files with 61 additions and 65 deletions

View File

@ -51,9 +51,6 @@
*** hotplug_acclimated ***
( hopefully libproc will also be supportive of our efforts ) */
/* And there are still some of these lurking here and there...
FIXME - blah, blah... */
/* For introducing inaugural cgroup support, thanks to:
Jan Gorig <jgorig@redhat.com> - April, 2011 */
@ -207,19 +204,22 @@ typedef struct HST_t {
} HST_t;
#endif
/* This structure stores a frame's cpu tics used in history
calculations. It exists primarily for SMP support but serves
/* These 2 structures store a frame's cpu tics used in history
calculations. They exist primarily for SMP support but serve
all environments. */
typedef struct CPU_t {
typedef struct CT_t {
/* other kernels: u == user/us, n == nice/ni, s == system/sy, i == idle/id
2.5.41 kernel: w == IO-wait/wa (io wait time)
2.6.0 kernel: x == hi (hardware irq time), y == si (software irq time)
2.6.11 kernel: z == st (virtual steal time) */
TIC_t u, n, s, i, w, x, y, z; // as represented in /proc/stat
TIC_t u_sav, s_sav, n_sav, i_sav, w_sav, x_sav, y_sav, z_sav; // in the order of our display
unsigned id; // the CPU ID number
} CPU_t;
TIC_t u, n, s, i, w, x, y, z; // as represented in /proc/stat
} CT_t;
typedef struct CPU_t {
CT_t cur; // current frame's cpu tics
CT_t sav; // prior frame's cpu tics
int id; // the cpu id number (0 - nn)
} CPU_t;
/* /////////////////////////////////////////////////////////////// */
/* Special Section: multiple windows/field groups --------------- */