1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-29 07:58:28 +00:00
emacs/lib/gettimeofday.c
Paul Eggert 5d89a9c284 Update from Gnulib
This incorporates:
2020-07-30 work around some Oracle Studio attribute bugs
2020-07-29 fsusage, regex, stat-size: remove Cray support
2020-07-26 inttypes: remove support for AIX 4
2020-07-26 gettimeofday: remove workaround for Mac OS X 10.0
2020-07-26 don't require gl_LOCALTIME_BUFFER_DEFAULTS
2020-07-26 alloca: remove Cray-2 and Cray Y-MP support
2020-07-26 libgmp: remove dependency on havelib
2020-07-26 libgmp: remove HAVE_GMP, LIB_GMP
2020-07-25 multiarch: prepare for x86_64+arm64 universal in macOS 11
2020-07-25 sigprocmask: small autoconf macro improvement
2020-07-25 small autoconf macro improvements
2020-07-24 timespec: remove dependence on ‘verify’
2020-07-24 optimize a few more three-valued comparisons
2020-07-24 fix _GL_CMP parenthesization typo
2020-07-23 optimize three-valued comparison between integers
2020-07-24 doc: update for Mac OS X 10.13
2020-07-23 fchmodat, lchmod: use /proc on Cygwin
2020-07-21 inttypes: fix PRI*PTR and SCN*PTR on 64-bit native Windows
2020-07-12 libgmp: avoid warning when --without-libgmp is used
2020-07-12 libgmp: link to the correct shared library
* lib/mini-gmp-gnulib.c: Ignore -Wsuggest-attribute=malloc only for
* build-aux/config.guess, build-aux/config.sub:
* build-aux/install-sh, doc/misc/texinfo.tex, lib/c-strcasecmp.c:
* lib/c-strncasecmp.c, lib/fchmodat.c, lib/fsusage.c:
* lib/gettimeofday.c, lib/inttypes.in.h, lib/lchmod.c:
* lib/mini-gmp-gnulib.c, lib/nstrftime.c, lib/regex.h, lib/timespec.h:
* m4/alloca.m4, m4/getgroups.m4, m4/gettimeofday.m4:
* m4/gnulib-common.m4, m4/inttypes.m4, m4/libgmp.m4, m4/mktime.m4:
* m4/multiarch.m4:
Copy from Gnulib.
* lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate.
* src/Makefile.in, test/Makefile.in (LIBGMP):
Rename from LIB_GMP for compatibility with Gnulib.
All uses changed.
2020-07-30 14:01:49 -07:00

154 lines
4.7 KiB
C

/* Provide gettimeofday for systems that don't have it or for which it's broken.
Copyright (C) 2001-2003, 2005-2007, 2009-2020 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <https://www.gnu.org/licenses/>. */
/* written by Jim Meyering */
#include <config.h>
/* Specification. */
#include <sys/time.h>
#include <time.h>
#if defined _WIN32 && ! defined __CYGWIN__
# define WINDOWS_NATIVE
# include <windows.h>
#endif
#ifdef WINDOWS_NATIVE
/* Don't assume that UNICODE is not defined. */
# undef LoadLibrary
# define LoadLibrary LoadLibraryA
# if !(_WIN32_WINNT >= _WIN32_WINNT_WIN8)
/* Avoid warnings from gcc -Wcast-function-type. */
# define GetProcAddress \
(void *) GetProcAddress
/* 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;
}
# else
# define GetSystemTimePreciseAsFileTimeFunc GetSystemTimePreciseAsFileTime
# endif
#endif
/* This is a wrapper for gettimeofday. It is used only on systems
that lack this function, or whose implementation of this function
causes problems.
Work around the bug in some systems whereby gettimeofday clobbers
the static buffer that localtime uses for its return value. The
gettimeofday function from Mac OS X 10.0.4 (i.e., Darwin 1.3.7) has
this problem. */
int
gettimeofday (struct timeval *restrict tv, void *restrict tz)
{
#undef gettimeofday
#ifdef WINDOWS_NATIVE
/* On native Windows, there are two ways to get the current time:
GetSystemTimeAsFileTime
<https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime>
or
GetSystemTimePreciseAsFileTime
<https://docs.microsoft.com/en-us/windows/desktop/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime>.
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 !(_WIN32_WINNT >= _WIN32_WINNT_WIN8)
if (!initialized)
initialize ();
# endif
if (GetSystemTimePreciseAsFileTimeFunc != NULL)
GetSystemTimePreciseAsFileTimeFunc (&current_time);
else
GetSystemTimeAsFileTime (&current_time);
/* Convert from FILETIME to 'struct timeval'. */
/* FILETIME: <https://docs.microsoft.com/en-us/windows/desktop/api/minwinbase/ns-minwinbase-filetime> */
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;
return 0;
#else
# if HAVE_GETTIMEOFDAY
# 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
return result;
# else
# if !defined OK_TO_USE_1S_CLOCK
# error "Only 1-second nominal clock resolution found. Is that intended?" \
"If so, compile with the -DOK_TO_USE_1S_CLOCK option."
# endif
tv->tv_sec = time (NULL);
tv->tv_usec = 0;
return 0;
# endif
#endif
}