diff options
author | James Ross-Gowan <rossymiles@gmail.com> | 2015-07-04 19:26:14 +1000 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-07-04 15:54:14 +0200 |
commit | f544bcf1056e0acee483a951408160fa2d39ffdd (patch) | |
tree | 1abdb317482b008ead74c083ee0a804bae98ca2e | |
parent | 029da5abce6e1ef6eddf351650fe7d6fe3746f0b (diff) | |
download | mpv-f544bcf1056e0acee483a951408160fa2d39ffdd.tar.bz2 mpv-f544bcf1056e0acee483a951408160fa2d39ffdd.tar.xz |
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.
-rw-r--r-- | osdep/timer-win2.c | 24 |
1 files 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 <stdlib.h> #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 } |