bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gettimeofday: increase precision on mingw


From: Bruno Haible
Subject: gettimeofday: increase precision on mingw
Date: Thu, 11 May 2017 21:45:44 +0200
User-agent: KMail/5.1.3 (Linux/4.4.0-75-generic; KDE/5.18.0; x86_64; ; )

Comparison of the two gettimeofday implementations on native Windows:

  * The mingw one, based on GetSystemTimeAsFileTime, produces values
    that jump by 15.627 milliseconds on average:
                         delta
      1494528421.290102
      1494528421.305729  15627
      1494528421.321355  15626
      1494528421.337009  15654
      1494528421.352608  15599
      1494528421.368235  15627
      1494528421.383861  15626
      1494528421.399492  15631
      1494528421.415118  15626

  * The gnulib one, based on GetSystemTimePreciseAsFileTime, produces
    values that jump by 1 or 2 microseconds on average.

(I measured this on Windows 10.) So, it's an improvement to use the
gnulib implementation even though the mingw one is strictly POSIX compliant.


2017-05-11 Bruno Haible  <address@hidden>

        gettimeofday: Increase precision on mingw.
        * m4/gettimeofday.m4 (gl_FUNC_GETTIMEOFDAY): Require AC_CANONICAL_HOST.
        Set REPLACE_GETTIMEOFDAY to 1 on mingw.
        * lib/gettimeofday.c (gettimeofday): On native Windows, use the
        GetSystemTimePreciseAsFileTime based implementation always.
        * doc/posix-functions/gettimeofday.texi: Mention precision problem on
        mingw.

diff --git a/doc/posix-functions/gettimeofday.texi 
b/doc/posix-functions/gettimeofday.texi
index 6fe62a6..758cc9d 100644
--- a/doc/posix-functions/gettimeofday.texi
+++ b/doc/posix-functions/gettimeofday.texi
@@ -10,7 +10,7 @@ Portability problems fixed by Gnulib:
 @itemize
 @item
 This function is missing on some platforms:
-mingw, MSVC 9.
+MSVC 9.
 @item
 This function is declared with a nonstandard function prototype (only one
 argument, or ``...'' after the first argument) on some platforms.
@@ -27,6 +27,9 @@ appropriate type for use in avoiding a compiler warning if 
assigning
 On some platforms, @code{gettimeofday} clobbers the buffer in which
 @code{localtime} returns its result:
 Mac OS X 10.0.
address@hidden
+This function has only a precision of 15.6 milliseconds on some platforms:
+mingw.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c
index 0d64885..14213da 100644
--- a/lib/gettimeofday.c
+++ b/lib/gettimeofday.c
@@ -64,42 +64,20 @@ int
 gettimeofday (struct timeval *restrict tv, void *restrict tz)
 {
 #undef gettimeofday
-#if HAVE_GETTIMEOFDAY
-# if GETTIMEOFDAY_CLOBBERS_LOCALTIME
-  /* Save and restore the contents of the buffer used for localtime's
-     result around the call to gettimeofday.  */
-  struct tm save = *localtime_buffer_addr;
-# endif
-
-# if defined timeval /* 'struct timeval' overridden by gnulib?  */
-#  undef timeval
-  struct timeval otv;
-  int result = gettimeofday (&otv, (struct timezone *) tz);
-  if (result == 0)
-    {
-      tv->tv_sec = otv.tv_sec;
-      tv->tv_usec = otv.tv_usec;
-    }
-# else
-  int result = gettimeofday (tv, (struct timezone *) tz);
-# endif
-
-# if GETTIMEOFDAY_CLOBBERS_LOCALTIME
-  *localtime_buffer_addr = save;
-# endif
-
-  return result;
-
-#else
-
-# ifdef WINDOWS_NATIVE
+#ifdef WINDOWS_NATIVE
 
   /* On native Windows, there are two ways to get the current time:
      GetSystemTimeAsFileTime
      <https://msdn.microsoft.com/en-us/library/ms724397.aspx>
      or
      GetSystemTimePreciseAsFileTime
-     <https://msdn.microsoft.com/en-us/library/hh706895.aspx>.  */
+     <https://msdn.microsoft.com/en-us/library/hh706895.aspx>.
+     GetSystemTimeAsFileTime produces values that jump by increments of
+     15.627 milliseconds (!) on average.
+     Whereas GetSystemTimePreciseAsFileTime values usually jump by 1 or 2
+     microseconds.
+     More discussion on this topic:
+     <http://www.windowstimestamp.com/description>.  */
   FILETIME current_time;
 
   if (!initialized)
@@ -122,6 +100,36 @@ gettimeofday (struct timeval *restrict tv, void *restrict 
tz)
   tv->tv_sec = microseconds_since_1970 / (ULONGLONG) 1000000;
   tv->tv_usec = microseconds_since_1970 % (ULONGLONG) 1000000;
 
+  return 0;
+
+#else
+
+# if HAVE_GETTIMEOFDAY
+#  if GETTIMEOFDAY_CLOBBERS_LOCALTIME
+  /* Save and restore the contents of the buffer used for localtime's
+     result around the call to gettimeofday.  */
+  struct tm save = *localtime_buffer_addr;
+#  endif
+
+#  if defined timeval /* 'struct timeval' overridden by gnulib?  */
+#   undef timeval
+  struct timeval otv;
+  int result = gettimeofday (&otv, (struct timezone *) tz);
+  if (result == 0)
+    {
+      tv->tv_sec = otv.tv_sec;
+      tv->tv_usec = otv.tv_usec;
+    }
+#  else
+  int result = gettimeofday (tv, (struct timezone *) tz);
+#  endif
+
+#  if GETTIMEOFDAY_CLOBBERS_LOCALTIME
+  *localtime_buffer_addr = save;
+#  endif
+
+  return result;
+
 # else
 
 #  if !defined OK_TO_USE_1S_CLOCK
@@ -131,9 +139,8 @@ gettimeofday (struct timeval *restrict tv, void *restrict 
tz)
   tv->tv_sec = time (NULL);
   tv->tv_usec = 0;
 
-# endif
-
   return 0;
 
+# endif
 #endif
 }
diff --git a/m4/gettimeofday.m4 b/m4/gettimeofday.m4
index 34adc64..8ee206e 100644
--- a/m4/gettimeofday.m4
+++ b/m4/gettimeofday.m4
@@ -1,4 +1,4 @@
-# serial 22
+# serial 23
 
 # Copyright (C) 2001-2003, 2005, 2007, 2009-2017 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -9,9 +9,10 @@ dnl From Jim Meyering.
 
 AC_DEFUN([gl_FUNC_GETTIMEOFDAY],
 [
+  AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS])
   AC_REQUIRE([AC_C_RESTRICT])
+  AC_REQUIRE([AC_CANONICAL_HOST])
   AC_REQUIRE([gl_HEADER_SYS_TIME_H])
-  AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS])
   AC_CHECK_FUNCS_ONCE([gettimeofday])
 
   gl_gettimeofday_timezone=void
@@ -54,6 +55,11 @@ int gettimeofday (struct timeval *restrict, struct timezone 
*restrict);
     if test $REPLACE_STRUCT_TIMEVAL = 1; then
       REPLACE_GETTIMEOFDAY=1
     fi
+    dnl On mingw, the original gettimeofday has only a precision of 15.6
+    dnl milliseconds. So override it.
+    case "$host_os" in
+      mingw*) REPLACE_GETTIMEOFDAY=1 ;;
+    esac
   fi
   AC_DEFINE_UNQUOTED([GETTIMEOFDAY_TIMEZONE], [$gl_gettimeofday_timezone],
     [Define this to 'void' or 'struct timezone' to match the system's




reply via email to

[Prev in Thread] Current Thread [Next in Thread]