summaryrefslogtreecommitdiff
path: root/ifpps.c
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2013-07-13 14:46:21 +0200
committerTobias Klauser <tklauser@distanz.ch>2013-07-13 14:46:21 +0200
commit22ed65468335a3d803b74db2d4ee39344a4543cc (patch)
tree856fa337b11d2d1f4d40e303a1574f92f8e84f14 /ifpps.c
parentdd123b0fb6af4909aa30940a8dc34661e8b1c420 (diff)
ifpps: Correct calculation of median values for CPU load
ifpps always reported the same values for median as for average in the CPU load fields (usr, sys, idle, iowait). This is of course incorrect. The bug was due to 3 sub-problems: - Summing up long double values (m_cpu_*) in an uint64_t (all) - Not using %Lf (for long double) in mvwprintw() - Explicitely use floating point division in MEDIAN_EVEN Fix the bug by summing up in a separate accumulator of type long double, use the correct format string for long double and divide by 2.0 in MEDIAN_EVEN to force the result to be (long) double. Reported-by: Daniel Borkmann <dborkman@redhat.com> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Diffstat (limited to 'ifpps.c')
-rw-r--r--ifpps.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/ifpps.c b/ifpps.c
index 77dfa6e..05e3459 100644
--- a/ifpps.c
+++ b/ifpps.c
@@ -802,7 +802,7 @@ static void screen_percpu_states_one(WINDOW *screen, const struct ifstat *rel,
}
#define MEDIAN_EVEN(member) do { \
- m_##member = (rel->member[i] + rel->member[j]) / 2; \
+ m_##member = (rel->member[i] + rel->member[j]) / 2.0; \
} while (0)
#define MEDIAN_ODD(member) do { \
@@ -848,6 +848,7 @@ static void screen_percpu_states(WINDOW *screen, const struct ifstat *rel,
if (show_median) {
long double m_cpu_user, m_cpu_nice, m_cpu_sys, m_cpu_idle, m_cpu_iow;
+ long double m_all;
i = cpu_hits[cpus / 2].idx;
if (cpus % 2 == 0) {
@@ -868,16 +869,16 @@ static void screen_percpu_states(WINDOW *screen, const struct ifstat *rel,
MEDIAN_ODD(cpu_iow);
}
- all = m_cpu_user + m_cpu_sys + m_cpu_nice + m_cpu_idle + m_cpu_iow;
+ m_all = m_cpu_user + m_cpu_sys + m_cpu_nice + m_cpu_idle + m_cpu_iow;
mvwprintw(screen, (*voff)++, 2,
- "med:%*s%14.1lf%% "
- "%9.1lf%% "
- "%10.1lf%% "
- "%11.1lf%%", max_padd, "",
- 100.0 * (m_cpu_user + m_cpu_nice) / all,
- 100.0 * m_cpu_sys / all,
- 100.0 * m_cpu_idle /all,
- 100.0 * m_cpu_iow / all);
+ "med:%*s%14.1Lf%% "
+ "%9.1Lf%% "
+ "%10.1Lf%% "
+ "%11.1Lf%%", max_padd, "",
+ 100.0 * (m_cpu_user + m_cpu_nice) / m_all,
+ 100.0 * m_cpu_sys / m_all,
+ 100.0 * m_cpu_idle /m_all,
+ 100.0 * m_cpu_iow / m_all);
}
}