diff options
author | sfan5 <sfan5@live.de> | 2023-10-17 22:33:10 +0200 |
---|---|---|
committer | sfan5 <sfan5@live.de> | 2023-10-20 21:30:51 +0200 |
commit | 66c3110a856f11c1fc68044e6ef426991911aa25 (patch) | |
tree | 32f83dbc5b0134e93f94649e8c3716fb716b2959 /osdep/win32 | |
parent | 9f147496b50e1d281b61e9659401d0abdfc97d3f (diff) | |
download | mpv-66c3110a856f11c1fc68044e6ef426991911aa25.tar.bz2 mpv-66c3110a856f11c1fc68044e6ef426991911aa25.tar.xz |
win32/pthread: implement clock_gettime for high-res timer purposes
Also apply some fixes to pthread_cond_timedwait while we're at it.
Note that by using GetSystemTimePreciseAsFileTime here we lose support
for Windows 7. This is considered acceptable.
Diffstat (limited to 'osdep/win32')
-rw-r--r-- | osdep/win32/include/pthread.h | 8 | ||||
-rw-r--r-- | osdep/win32/pthread.c | 32 |
2 files changed, 31 insertions, 9 deletions
diff --git a/osdep/win32/include/pthread.h b/osdep/win32/include/pthread.h index e92c471f5f..76af00a514 100644 --- a/osdep/win32/include/pthread.h +++ b/osdep/win32/include/pthread.h @@ -20,7 +20,7 @@ #include <sys/types.h> -#define _POSIX_TIMERS 0 +#define _POSIX_TIMERS 200809L // Note: all pthread functions are mangled to make static linking easier. #define pthread_once m_pthread_once @@ -35,6 +35,7 @@ #define pthread_detach m_pthread_detach #define pthread_create m_pthread_create #define pthread_set_name_np m_pthread_set_name_np +#define clock_gettime m_clock_gettime #define pthread_once_t INIT_ONCE #define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT @@ -76,6 +77,11 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex); #define pthread_cond_broadcast(cond) WakeAllConditionVariable(cond) #define pthread_cond_signal(cond) WakeConditionVariable(cond) +#define clockid_t int +#define CLOCK_REALTIME 1 + +int clock_gettime(clockid_t clockid, struct timespec *tp); + int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime); diff --git a/osdep/win32/pthread.c b/osdep/win32/pthread.c index a178d72253..9bc7f0057d 100644 --- a/osdep/win32/pthread.c +++ b/osdep/win32/pthread.c @@ -76,6 +76,23 @@ int pthread_mutex_unlock(pthread_mutex_t *mutex) return 0; } +int clock_gettime(clockid_t clockid, struct timespec *tp) +{ + if (clockid != CLOCK_REALTIME) { + errno = EINVAL; + return -1; + } + union { + FILETIME ft; + ULARGE_INTEGER i; + } r; + GetSystemTimePreciseAsFileTime(&r.ft); + r.i.QuadPart -= UINT64_C(116444736000000000); // MS epoch -> Unix epoch + tp->tv_sec = r.i.QuadPart / UINT64_C(10000000); + tp->tv_nsec = (r.i.QuadPart % UINT64_C(10000000)) * 100; + return 0; +} + static int cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, DWORD ms) @@ -95,16 +112,15 @@ int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, const struct timespec *restrict abstime) { - // mpv uses mingw's gettimeofday() as time source too. - struct timeval tv; - gettimeofday(&tv, NULL); + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); DWORD timeout_ms = 0; - if (abstime->tv_sec >= INT64_MAX / 10000) { + if (abstime->tv_sec >= INT64_MAX / 1000) { // overflow timeout_ms = INFINITE; - } else if (abstime->tv_sec >= tv.tv_sec) { - long long msec = (abstime->tv_sec - tv.tv_sec) * 1000LL + - abstime->tv_nsec / 1000LL / 1000LL - tv.tv_usec / 1000LL; - if (msec > INT_MAX) { + } else if (abstime->tv_sec >= ts.tv_sec) { + int64_t msec = (abstime->tv_sec - ts.tv_sec) * INT64_C(1000) + + (abstime->tv_nsec - ts.tv_nsec) / INT64_C(10000000); + if (msec > ULONG_MAX) { timeout_ms = INFINITE; } else if (msec > 0) { timeout_ms = msec; |