mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-13 14:26:30 -04:00
Use GetSystemTimeAsFileTime to implement gettimeofday on win32.
It is (in my benchmarks) way faster than _ftime, though the conversion process is not so straightforward. In theory, it can have a better granularity too, though in practice who knows what you're getting.
This commit is contained in:
parent
04ba27ebf2
commit
b8b8aa560c
41
evutil.c
41
evutil.c
@ -364,26 +364,41 @@ evutil_strtoll(const char *s, char **endptr, int base)
|
||||
}
|
||||
|
||||
#ifndef _EVENT_HAVE_GETTIMEOFDAY
|
||||
/* No gettimeofday; this muse be windows. */
|
||||
/* No gettimeofday; this must be windows. */
|
||||
int
|
||||
evutil_gettimeofday(struct timeval *tv, struct timezone *tz)
|
||||
{
|
||||
struct _timeb tb;
|
||||
#ifdef _MSC_VER
|
||||
#define U64_LITERAL(n) n##ui64
|
||||
#else
|
||||
#define U64_LITERAL(n) n##llu
|
||||
#endif
|
||||
|
||||
/* Conversion logic taken from Tor, which in turn took it
|
||||
* from Perl. GetSystemTimeAsFileTime returns its value as
|
||||
* an unaligned (!) 64-bit value containing the number of
|
||||
* 100-nanosecond intervals since 1 January 1601 UTC. */
|
||||
#define EPOCH_BIAS U64_LITERAL(116444736000000000)
|
||||
#define UNITS_PER_SEC U64_LITERAL(10000000)
|
||||
#define USEC_PER_SEC U64_LITERAL(1000000)
|
||||
#define UNITS_PER_USEC U64_LITERAL(10)
|
||||
union {
|
||||
FILETIME ft_ft;
|
||||
ev_uint64_t ft_64;
|
||||
} ft;
|
||||
|
||||
if (tv == NULL)
|
||||
return -1;
|
||||
|
||||
/* XXXX
|
||||
* _ftime is not the greatest interface here; GetSystemTimeAsFileTime
|
||||
* would give us better resolution, whereas something cobbled together
|
||||
* with GetTickCount could maybe give us monotonic behavior.
|
||||
*
|
||||
* Either way, I think this value might be skewed to ignore the
|
||||
* timezone, and just return local time. That's not so good.
|
||||
*/
|
||||
_ftime(&tb);
|
||||
tv->tv_sec = (long) tb.time;
|
||||
tv->tv_usec = ((int) tb.millitm) * 1000;
|
||||
GetSystemTimeAsFileTime(&ft.ft_ft);
|
||||
|
||||
if (EVUTIL_UNLIKELY(ft.ft_64 < EPOCH_BIAS)) {
|
||||
/* Time before the unix epoch. */
|
||||
return -1;
|
||||
}
|
||||
ft.ft_64 -= EPOCH_BIAS;
|
||||
tv->tv_sec = (long) (ft.ft_64 / UNITS_PER_SEC);
|
||||
tv->tv_usec = (long) ((ft.ft_64 / UNITS_PER_USEC) % USEC_PER_SEC);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user