Mercurial > gnulib
changeset 38514:869cbe085e12
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.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 30 Apr 2017 12:15:08 +0200 |
parents | 922850c36342 |
children | 20e94b6fcdaa |
files | ChangeLog lib/gettimeofday.c m4/gettimeofday.m4 |
diffstat | 3 files changed, 66 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Sun Apr 30 11:38:25 2017 +0200 +++ b/ChangeLog Sun Apr 30 12:15:08 2017 +0200 @@ -1,3 +1,14 @@ +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.
--- a/lib/gettimeofday.c Sun Apr 30 11:38:25 2017 +0200 +++ b/lib/gettimeofday.c Sun Apr 30 12:15:08 2017 +0200 @@ -24,8 +24,9 @@ #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 @@ -92,6 +93,28 @@ 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 @@ -130,12 +153,35 @@ #else -# if HAVE__FTIME +# 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; - struct _timeb timebuf; - _ftime (&timebuf); - tv->tv_sec = timebuf.time; - tv->tv_usec = timebuf.millitm * 1000; + 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
--- a/m4/gettimeofday.m4 Sun Apr 30 11:38:25 2017 +0200 +++ b/m4/gettimeofday.m4 Sun Apr 30 12:15:08 2017 +0200 @@ -1,4 +1,4 @@ -# 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 @@ -132,7 +132,4 @@ ]) # 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], [:])