top: fixup logic for Nehalem cpu 'idle' threshold

Due to a poorly constructed temporary fprintf
used during development, an earlier commit went
a little too far in its computations.  The net
result was the code looked nice but actually
accomplished nothing.

It is the /proc/stat line 1 (summary line)
whose tics must be used in establishing the
threshold boundary.  And that calculation
need be performed just once per frame.

This commit ensures one threshold calculation
per delay interval no matter how many cpus
are ultimately displayed.

It also corrects scalability by factoring in
the total number of online processors.

Reference:
commit 9e7dd43ab7
This commit is contained in:
Jim Warner 2012-02-08 23:59:59 -06:00 committed by Craig Small
parent 9349100dd3
commit ce1410a51a
2 changed files with 17 additions and 5 deletions

View File

@ -1826,6 +1826,12 @@ static CPU_t *cpus_refresh (CPU_t *cpus) {
cpus[Cpu_faux_tot].cur.tot = cpus[Cpu_faux_tot].cur.u + cpus[Cpu_faux_tot].cur.s
+ cpus[Cpu_faux_tot].cur.n + cpus[Cpu_faux_tot].cur.i + cpus[Cpu_faux_tot].cur.w
+ cpus[Cpu_faux_tot].cur.x + cpus[Cpu_faux_tot].cur.y + cpus[Cpu_faux_tot].cur.z;
/* if a Nehalem type cpu has been turned off completely, and thus registers
very few total tics, we'll force it to be treated as idle when that total
falls below a % of those expected -- other cpus will register their full
number of expected tics as 'idle' and thus won't be effected */
cpus[Cpu_faux_tot].edge =
((cpus[Cpu_faux_tot].cur.tot - cpus[Cpu_faux_tot].sav.tot) / smp_num_cpus) / (100 / TICS_EDGE);
// now value each separate cpu's tics, maybe
for (i = 0; i < Cpu_faux_tot && i < Screen_rows; i++) {
@ -1844,9 +1850,9 @@ static CPU_t *cpus_refresh (CPU_t *cpus) {
memmove(&cpus[i], &cpus[Cpu_faux_tot], sizeof(CPU_t));
break; // tolerate cpus taken offline
}
cpus[i].cur.tot = cpus[i].cur.u + cpus[i].cur.s
+ cpus[i].cur.n + cpus[i].cur.i + cpus[i].cur.w
+ cpus[i].cur.x + cpus[i].cur.y + cpus[i].cur.z;
cpus[i].edge = cpus[Cpu_faux_tot].edge;
// this is for symmetry only, it's not currently required
cpus[i].cur.tot = cpus[Cpu_faux_tot].cur.tot;
#ifdef PRETEND4CPUS
cpus[i].id = i;
#endif
@ -3338,7 +3344,7 @@ static void summaryhlp (CPU_t *cpu, const char *pfx) {
#ifdef CPU_ZEROTICS
if (1 > tot_frme) tot_frme = 1;
#else
if (tot_frme < (cpu->cur.tot - cpu->sav.tot) / 10)
if (tot_frme < cpu->edge)
tot_frme = u_frme = s_frme = n_frme = i_frme = w_frme = x_frme = y_frme = z_frme = 0;
if (1 > tot_frme) i_frme = tot_frme = 1;
#endif

View File

@ -129,6 +129,11 @@
-- used at startup and for task/thread mode transitions */
#define PROC_XTRA -1
/* This is the % used in establishing the tics threshold below
which a cpu is treated as 'idle' rather than displaying
misleading state percentages */
#define TICS_EDGE 20
/* ##### Enum's and Typedef's ############################################ */
@ -214,12 +219,13 @@ typedef struct CT_t {
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
SIC_t tot; // total of above
SIC_t tot; // total from /proc/stat line 1
} CT_t;
typedef struct CPU_t {
CT_t cur; // current frame's cpu tics
CT_t sav; // prior frame's cpu tics
SIC_t edge; // tics adjustment threshold boundary
int id; // the cpu id number (0 - nn)
} CPU_t;