[wing] utils: fix overflow getting monotonic time
- From: Ignacio Casal Quinteiro <icq src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [wing] utils: fix overflow getting monotonic time
- Date: Wed, 24 May 2017 19:06:43 +0000 (UTC)
commit e407244d42b0c2b7610d1f1040ac54fd9ede6149
Author: Ignacio Casal Quinteiro <qignacio amazon com>
Date: Wed May 24 10:24:56 2017 +0200
utils: fix overflow getting monotonic time
time_usec = ticks_since_boot * usec_per_sec / ticks_per_sec
Doing (ticks_since_boot * usec_per_sec) before the division can overflow 64 bits
(ticks_since_boot / ticks_per_sec) and then multiply would not be accurate enough
So for now we calculate (usec_per_sec / ticks_per_sec) and use floating point
wing/wingutils.c | 26 ++++++++++++++------------
1 files changed, 14 insertions(+), 12 deletions(-)
---
diff --git a/wing/wingutils.c b/wing/wingutils.c
index 8700ed7..5282138 100644
--- a/wing/wingutils.c
+++ b/wing/wingutils.c
@@ -74,7 +74,15 @@ wing_get_version_number (gint *major,
return TRUE;
}
-static gint64 monotonic_ticks_per_sec = 0;
+static gdouble monotonic_usec_per_tick = 0;
+
+/* NOTE:
+ * time_usec = ticks_since_boot * usec_per_sec / ticks_per_sec
+ *
+ * Doing (ticks_since_boot * usec_per_sec) before the division can overflow 64 bits
+ * (ticks_since_boot / ticks_per_sec) and then multiply would not be accurate enough.
+ * So for now we calculate (usec_per_sec / ticks_per_sec) and use floating point
+ */
void
wing_init_monotonic_time (void)
@@ -84,31 +92,25 @@ wing_init_monotonic_time (void)
if (!QueryPerformanceFrequency (&freq) || freq.QuadPart == 0)
{
g_warning ("Unable to use QueryPerformanceCounter (%d). Fallback to low resolution timer",
GetLastError ());
- monotonic_ticks_per_sec = 0;
+ monotonic_usec_per_tick = 0;
return;
}
- monotonic_ticks_per_sec = freq.QuadPart;
+ monotonic_usec_per_tick = (gdouble)G_USEC_PER_SEC / freq.QuadPart;
}
gint64
wing_get_monotonic_time (void)
{
- if (G_LIKELY (monotonic_ticks_per_sec != 0))
+ if (G_LIKELY (monotonic_usec_per_tick != 0))
{
LARGE_INTEGER ticks;
if (QueryPerformanceCounter (&ticks))
- {
- gint64 time;
-
- time = ticks.QuadPart * G_USEC_PER_SEC; /* multiply first to avoid loss of precision */
-
- return time / monotonic_ticks_per_sec;
- }
+ return (gint64)(ticks.QuadPart * monotonic_usec_per_tick);
g_warning ("QueryPerformanceCounter Failed (%d). Permanently fallback to low resolution timer",
GetLastError ());
- monotonic_ticks_per_sec = 0;
+ monotonic_usec_per_tick = 0;
}
return g_get_monotonic_time ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]