From ab23523d7ae2b62d7c633773739e7694a0ce82a2 Mon Sep 17 00:00:00 2001 From: infirit Date: Wed, 17 Dec 2014 16:00:29 +0100 Subject: Fix network totals overflow on 32-bit machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Taken from GSM commit: c7275791a89623ad1edc820a6ef16faae37a18aa From: Chris Kühl Gnome bug: https://bugzilla.gnome.org/show_bug.cgi?id=639212 --- src/load-graph.cpp | 38 +++++++++++++++++++------------------- src/load-graph.h | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/load-graph.cpp b/src/load-graph.cpp index 2ff1716..176b69f 100644 --- a/src/load-graph.cpp +++ b/src/load-graph.cpp @@ -379,16 +379,16 @@ get_memory (LoadGraph *g) } static void -net_scale (LoadGraph *g, unsigned din, unsigned dout) +net_scale (LoadGraph *g, guint64 din, guint64 dout) { g->data[0][0] = 1.0f * din / g->net.max; g->data[0][1] = 1.0f * dout / g->net.max; - unsigned dmax = std::max(din, dout); + guint64 dmax = std::max(din, dout); g->net.values[g->net.cur] = dmax; g->net.cur = (g->net.cur + 1) % LoadGraph::NUM_POINTS; - unsigned new_max; + guint64 new_max; // both way, new_max is the greatest value if (dmax >= g->net.max) new_max = dmax; @@ -400,7 +400,7 @@ net_scale (LoadGraph *g, unsigned din, unsigned dout) // Round network maximum // - const unsigned bak_max(new_max); + const guint64 bak_max(new_max); if (ProcData::get_instance()->config.network_in_bits) { // TODO: fix logic to give a nice scale with bits @@ -410,7 +410,7 @@ net_scale (LoadGraph *g, unsigned din, unsigned dout) new_max = 1.1 * new_max; // make sure max is not 0 to avoid / 0 // default to 125 bytes == 1kbit - new_max = std::max(new_max, 125U); + new_max = std::max(new_max, 125UL); } else { // round up to get some extra space @@ -418,7 +418,7 @@ net_scale (LoadGraph *g, unsigned din, unsigned dout) new_max = 1.1 * new_max; // make sure max is not 0 to avoid / 0 // default to 1 KiB - new_max = std::max(new_max, 1024U); + new_max = std::max(new_max, 1024UL); // decompose new_max = coef10 * 2**(base10 * 10) // where coef10 and base10 are integers and coef10 < 2**10 @@ -426,16 +426,16 @@ net_scale (LoadGraph *g, unsigned din, unsigned dout) // e.g: ceil(100.5 KiB) = 101 KiB = 101 * 2**(1 * 10) // where base10 = 1, coef10 = 101, pow2 = 16 - unsigned pow2 = std::floor(log2(new_max)); - unsigned base10 = pow2 / 10; - unsigned coef10 = std::ceil(new_max / double(1UL << (base10 * 10))); + guint64 pow2 = std::floor(log2(new_max)); + guint64 base10 = pow2 / 10.0; + guint64 coef10 = std::ceil(new_max / double(1UL <<(base10 * 10))); g_assert(new_max <= (coef10 * (1UL << (base10 * 10)))); // then decompose coef10 = x * 10**factor10 // where factor10 is integer and x < 10 // so we new_max has only 1 significant digit - unsigned factor10 = std::pow(10.0, std::floor(std::log10(coef10))); + guint64 factor10 = std::pow(10.0, std::floor(std::log10(coef10))); coef10 = std::ceil(coef10 / double(factor10)) * factor10; // then make coef10 divisible by num_bars @@ -443,12 +443,12 @@ net_scale (LoadGraph *g, unsigned din, unsigned dout) coef10 = coef10 + (g->num_bars() - coef10 % g->num_bars()); g_assert(coef10 % g->num_bars() == 0); - new_max = coef10 * (1UL << (base10 * 10)); - procman_debug("bak %u new_max %u pow2 %u coef10 %u", bak_max, new_max, pow2, coef10); + new_max = coef10 * (1UL << guint64(base10 * 10)); + procman_debug("bak %lu new_max %lu pow2 %lu coef10 %lu", bak_max, new_max, pow2, coef10); } if (bak_max > new_max) { - procman_debug("overflow detected: bak=%u new=%u", bak_max, new_max); + procman_debug("overflow detected: bak=%lu new=%lu", bak_max, new_max); new_max = bak_max; } @@ -457,7 +457,7 @@ net_scale (LoadGraph *g, unsigned din, unsigned dout) if ((0.8 * g->net.max) < new_max && new_max <= g->net.max) return; - const float scale = 1.0f * g->net.max / new_max; + const double scale = 1.0f * g->net.max / new_max; for (size_t i = 0; i < LoadGraph::NUM_POINTS; i++) { if (g->data[i][0] >= 0.0f) { @@ -466,7 +466,7 @@ net_scale (LoadGraph *g, unsigned din, unsigned dout) } } - procman_debug("rescale dmax = %u max = %u new_max = %u", dmax, g->net.max, new_max); + procman_debug("rescale dmax = %lu max = %lu new_max = %lu", dmax, g->net.max, new_max); g->net.max = new_max; @@ -482,7 +482,7 @@ get_net (LoadGraph *g) guint32 i; guint64 in = 0, out = 0; GTimeVal time; - unsigned din, dout; + guint64 din, dout; ifnames = glibtop_get_netlist(&netlist); @@ -521,9 +521,9 @@ get_net (LoadGraph *g) g->net.time.tv_sec != 0) { float dtime; dtime = time.tv_sec - g->net.time.tv_sec + - (float) (time.tv_usec - g->net.time.tv_usec) / G_USEC_PER_SEC; - din = static_cast((in - g->net.last_in) / dtime); - dout = static_cast((out - g->net.last_out) / dtime); + (double) (time.tv_usec - g->net.time.tv_usec) / G_USEC_PER_SEC; + din = static_cast((in - g->net.last_in) / dtime); + dout = static_cast((out - g->net.last_out) / dtime); } else { /* Don't calc anything if new data is less than old (interface removed, counters reset, ...) or if it is the first time */ diff --git a/src/load-graph.h b/src/load-graph.h index 8a99bd4..5164a4c 100644 --- a/src/load-graph.h +++ b/src/load-graph.h @@ -91,7 +91,7 @@ struct LoadGraph { struct { guint64 last_in, last_out; GTimeVal time; - unsigned int max; + guint64 max; unsigned values[NUM_POINTS]; size_t cur; } net; -- cgit v1.2.1