Simplify gettimeofday for Windows.

Previously we bothered to forward-declare struct timezone, following man
pages on typical systems, but POSIX actually says the argument (which we
ignore anyway) is void *.  Drop a line.

While here, add an assertion that nobody actually uses the tzp argument.

Previously we did extra work to select between Windows APIs needed on
older releases, but now we can just use the higher resolution function
directly.

Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CA%2BhUKGKwRpvGfcfq2qNVAQS2Wg1B9eA9QRhAmVSyJt1zsCN2sQ%40mail.gmail.com
This commit is contained in:
Thomas Munro 2022-08-07 12:35:11 +12:00
parent 5c7121bcf8
commit 24c3ce8f1c
2 changed files with 14 additions and 58 deletions

View File

@ -179,11 +179,10 @@
#define SIGUSR1 30
#define SIGUSR2 31
/* MinW has gettimeofday(), but MSVC doesn't */
/* MinGW has gettimeofday(), but MSVC doesn't */
#ifdef _MSC_VER
struct timezone;
/* Last parameter not used */
extern int gettimeofday(struct timeval *tp, struct timezone *tzp);
extern int gettimeofday(struct timeval *tp, void *tzp);
#endif
/* for setitimer in backend/port/win32/timer.c */

View File

@ -28,6 +28,8 @@
#include "c.h"
#include <sysinfoapi.h>
#include <sys/time.h>
/* FILETIME of Jan 1 1970 00:00:00, the PostgreSQL epoch */
@ -40,59 +42,6 @@ static const unsigned __int64 epoch = UINT64CONST(116444736000000000);
#define FILETIME_UNITS_PER_SEC 10000000L
#define FILETIME_UNITS_PER_USEC 10
/*
* Both GetSystemTimeAsFileTime and GetSystemTimePreciseAsFileTime share a
* signature, so we can just store a pointer to whichever we find. This
* is the pointer's type.
*/
typedef VOID(WINAPI * PgGetSystemTimeFn) (LPFILETIME);
/* One-time initializer function, must match that signature. */
static void WINAPI init_gettimeofday(LPFILETIME lpSystemTimeAsFileTime);
/* Storage for the function we pick at runtime */
static PgGetSystemTimeFn pg_get_system_time = &init_gettimeofday;
/*
* One time initializer. Determine whether GetSystemTimePreciseAsFileTime
* is available and if so, plan to use it; if not, fall back to
* GetSystemTimeAsFileTime.
*/
static void WINAPI
init_gettimeofday(LPFILETIME lpSystemTimeAsFileTime)
{
/*
* Because it's guaranteed that kernel32.dll will be linked into our
* address space already, we don't need to LoadLibrary it and worry about
* closing it afterwards, so we're not using Pg's dlopen/dlsym() wrapper.
*
* We'll just look up the address of GetSystemTimePreciseAsFileTime if
* present.
*
* While we could look up the Windows version and skip this on Windows
* versions below Windows 8 / Windows Server 2012 there isn't much point,
* and determining the windows version is its self somewhat Windows
* version and development SDK specific...
*/
pg_get_system_time = (PgGetSystemTimeFn) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),
"GetSystemTimePreciseAsFileTime");
if (pg_get_system_time == NULL)
{
/*
* The expected error from GetLastError() is ERROR_PROC_NOT_FOUND, if
* the function isn't present. No other error should occur.
*
* We can't report an error here because this might be running in
* frontend code; and even if we're in the backend, it's too early to
* elog(...) if we get some unexpected error. Also, it's not a
* serious problem, so just silently fall back to
* GetSystemTimeAsFileTime irrespective of why the failure occurred.
*/
pg_get_system_time = &GetSystemTimeAsFileTime;
}
(*pg_get_system_time) (lpSystemTimeAsFileTime);
}
/*
* timezone information is stored outside the kernel so tzp isn't used anymore.
@ -101,12 +50,20 @@ init_gettimeofday(LPFILETIME lpSystemTimeAsFileTime)
* elapsed_time().
*/
int
gettimeofday(struct timeval *tp, struct timezone *tzp)
gettimeofday(struct timeval *tp, void *tzp)
{
FILETIME file_time;
ULARGE_INTEGER ularge;
(*pg_get_system_time) (&file_time);
/*
* POSIX declines to define what tzp points to, saying "If tzp is not a
* null pointer, the behavior is unspecified". Let's take this
* opportunity to verify that noplace in Postgres tries to use any
* unportable behavior.
*/
Assert(tzp == NULL);
GetSystemTimePreciseAsFileTime(&file_time);
ularge.LowPart = file_time.dwLowDateTime;
ularge.HighPart = file_time.dwHighDateTime;