From f544bcf1056e0acee483a951408160fa2d39ffdd Mon Sep 17 00:00:00 2001 From: James Ross-Gowan Date: Sat, 4 Jul 2015 19:26:14 +1000 Subject: win32: use QueryPerformanceCounter for timing clock_gettime is implemented in winpthreads, so it's unavailable when mpv is compiled with its internal pthreads implementation. This makes mp_raw_time_us fall back to gettimeofday(), which can cause an assert failure in mp_add_timeout() when the system clock is changed. Use QueryPerformanceCounter instead. The clock_gettime(CLOCK_MONOTONIC) implementation in winpthreads uses QueryPerformanceCounter anyway, so there shouldn't be any change in behaviour. --- osdep/timer-win2.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/osdep/timer-win2.c b/osdep/timer-win2.c index b58379d312..b198395e56 100644 --- a/osdep/timer-win2.c +++ b/osdep/timer-win2.c @@ -23,6 +23,8 @@ #include #include "timer.h" +static LARGE_INTEGER perf_freq; + void mp_sleep_us(int64_t us) { if (us < 0) @@ -35,24 +37,20 @@ void mp_sleep_us(int64_t us) Sleep(us / 1000); } -#if defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0 && defined(CLOCK_MONOTONIC) uint64_t mp_raw_time_us(void) { - struct timespec ts; - if (clock_gettime(CLOCK_MONOTONIC, &ts)) - abort(); - return ts.tv_sec * 1000000LL + ts.tv_nsec / 1000; -} -#else -uint64_t mp_raw_time_us(void) -{ - struct timeval tv; - gettimeofday(&tv,NULL); - return tv.tv_sec * 1000000LL + tv.tv_usec; + LARGE_INTEGER perf_count; + QueryPerformanceCounter(&perf_count); + + // Convert QPC units (1/perf_freq seconds) to microseconds. This will work + // without overflow because the QPC value is guaranteed not to roll-over + // within 100 years, so perf_freq must be less than 2.9*10^9. + return perf_count.QuadPart / perf_freq.QuadPart * 1000000 + + perf_count.QuadPart % perf_freq.QuadPart * 1000000 / perf_freq.QuadPart; } -#endif void mp_raw_time_init(void) { + QueryPerformanceFrequency(&perf_freq); timeBeginPeriod(1); // request 1ms timer resolution } -- cgit v1.2.3