+2017-04-30 Bruno Haible <bruno@clisp.org>
+
+ gettimeofday: Provide higher resolution on native Windows.
+ * lib/gettimeofday.c: Don't include <sys/timeb.h>.
+ (GetSystemTimePreciseAsFileTimeFuncType): New variable.
+ (initialize): Initialize it.
+ (gettimeofday) [WINDOWS_NATIVE]: Use it, and convert from FILETIME to
+ 'struct timeval'. Don't use _ftime().
+ * m4/gettimeofday.m4 (gl_PREREQ_GETTIMEOFDAY): Don't test for
+ <sys/timeb.h> and _ftime.
+
2017-04-30 Bruno Haible <bruno@clisp.org>
Document the problem with the Cygwin environment variable TZ.
#include <time.h>
-#if HAVE_SYS_TIMEB_H
-# include <sys/timeb.h>
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# define WINDOWS_NATIVE
+# include <windows.h>
#endif
#if GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME
tzset ();
*localtime_buffer_addr = save;
}
+
+#endif
+
+#ifdef WINDOWS_NATIVE
+
+/* GetSystemTimePreciseAsFileTime was introduced only in Windows 8. */
+typedef void (WINAPI * GetSystemTimePreciseAsFileTimeFuncType) (FILETIME *lpTime);
+static GetSystemTimePreciseAsFileTimeFuncType GetSystemTimePreciseAsFileTimeFunc = NULL;
+static BOOL initialized = FALSE;
+
+static void
+initialize (void)
+{
+ HMODULE kernel32 = LoadLibrary ("kernel32.dll");
+ if (kernel32 != NULL)
+ {
+ GetSystemTimePreciseAsFileTimeFunc =
+ (GetSystemTimePreciseAsFileTimeFuncType) GetProcAddress (kernel32, "GetSystemTimePreciseAsFileTime");
+ }
+ initialized = TRUE;
+}
+
#endif
/* This is a wrapper for gettimeofday. It is used only on systems
#else
-# if HAVE__FTIME
-
- struct _timeb timebuf;
- _ftime (&timebuf);
- tv->tv_sec = timebuf.time;
- tv->tv_usec = timebuf.millitm * 1000;
+# 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>. */
+ FILETIME current_time;
+
+ if (!initialized)
+ initialize ();
+ if (GetSystemTimePreciseAsFileTimeFunc != NULL)
+ GetSystemTimePreciseAsFileTimeFunc (¤t_time);
+ else
+ GetSystemTimeAsFileTime (¤t_time);
+
+ /* Convert from FILETIME to 'struct timeval'. */
+ /* FILETIME: <https://msdn.microsoft.com/en-us/library/ms724284.aspx> */
+ ULONGLONG since_1601 =
+ ((ULONGLONG) current_time.dwHighDateTime << 32)
+ | (ULONGLONG) current_time.dwLowDateTime;
+ /* Between 1601-01-01 and 1970-01-01 there were 280 normal years and 89 leap
+ years, in total 134774 days. */
+ ULONGLONG since_1970 =
+ since_1601 - (ULONGLONG) 134774 * (ULONGLONG) 86400 * (ULONGLONG) 10000000;
+ ULONGLONG microseconds_since_1970 = since_1970 / (ULONGLONG) 10;
+ tv->tv_sec = microseconds_since_1970 / (ULONGLONG) 1000000;
+ tv->tv_usec = microseconds_since_1970 % (ULONGLONG) 1000000;
# else
-# serial 21
+# serial 22
# Copyright (C) 2001-2003, 2005, 2007, 2009-2017 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
])
# Prerequisites of lib/gettimeofday.c.
-AC_DEFUN([gl_PREREQ_GETTIMEOFDAY], [
- AC_CHECK_HEADERS([sys/timeb.h])
- AC_CHECK_FUNCS([_ftime])
-])
+AC_DEFUN([gl_PREREQ_GETTIMEOFDAY], [:])