gettimeofday: Increase precision on mingw.
authorBruno Haible <bruno@clisp.org>
Thu, 11 May 2017 19:38:28 +0000 (21:38 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 11 May 2017 19:39:06 +0000 (21:39 +0200)
* 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.

ChangeLog
doc/posix-functions/gettimeofday.texi
lib/gettimeofday.c
m4/gettimeofday.m4

index a7f9c88f017596277bd166097bfd745b88f5f89f..0da6a991757c453584adbeac1158e1f42d1f1c73 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2017-05-11 Bruno Haible  <bruno@clisp.org>
+
+       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.
+
 2017-05-11 Bruno Haible  <bruno@clisp.org>
 
        poll: Fix confusion between SOCKETs and FDs on native Windows.
index 6fe62a66b5b7abed2b7c7a4fb611a42a4e12a306..758cc9dcf0b4874ea3797f9c7e23f11ebdffd968 100644 (file)
@@ -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.
+@item
+This function has only a precision of 15.6 milliseconds on some platforms:
+mingw.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index 0d64885026d7f129602635e45eb0363d56d4c95d..14213da462cf6abd13363bbfbd3c8a6408b9a309 100644 (file)
@@ -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
 }
index 34adc64778f43bcc54618ef129fa5e3d3f20f9fe..8ee206eea2455640371aa1af6fb50f2d2a75bb0b 100644 (file)
@@ -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