vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Sun Feb 23 17:04:45 2020 +0200| [6a498e510c3901506d6f8416f3414049fee6c30c] | committer: Rémi Denis-Courmont
posix/thread: use the monotonic clock for CV This gets the earlier timed-wait behaviour back on NetBSD and other platforms without futex. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=6a498e510c3901506d6f8416f3414049fee6c30c --- src/posix/wait.c | 58 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/src/posix/wait.c b/src/posix/wait.c index 5c146b61e2..26bce27448 100644 --- a/src/posix/wait.c +++ b/src/posix/wait.c @@ -32,6 +32,8 @@ #include <sys/types.h> #include <pthread.h> +static clockid_t vlc_clock_id = CLOCK_REALTIME; + #define WAIT_BUCKET_INIT \ { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0 } #define WAIT_BUCKET_INIT_2 WAIT_BUCKET_INIT, WAIT_BUCKET_INIT @@ -101,22 +103,29 @@ static int vlc_atomic_timedwait_timespec(void *addr, unsigned value, return ret; } -int vlc_atomic_timedwait(void *addr, unsigned value, vlc_tick_t deadline) +static void vlc_timespec_adjust(clockid_t cid, struct timespec *restrict ts) { - struct timespec ts; - vlc_tick_t delay = deadline - vlc_tick_now(); - lldiv_t d = lldiv((delay >= 0) ? delay : 0, CLOCK_FREQ); + struct timespec now_from, now_to; + lldiv_t d; + + if (vlc_clock_id == cid) + return; - /* TODO: use monotonic clock directly */ - clock_gettime(CLOCK_REALTIME, &ts); - ts.tv_sec += d.quot; - ts.tv_nsec += NS_FROM_VLC_TICK(d.rem); + clock_gettime(cid, &now_from); + clock_gettime(vlc_clock_id, &now_to); - if (ts.tv_nsec >= 1000000000) { - ts.tv_sec++; - ts.tv_nsec -= 1000000000; - } + d = lldiv((ts->tv_sec - now_from.tv_sec + now_to.tv_sec) * 1000000000LL + + ts->tv_nsec - now_from.tv_nsec - now_to.tv_nsec, 1000000000LL); + + ts->tv_sec = d.quot; + ts->tv_nsec = d.rem; +} +int vlc_atomic_timedwait(void *addr, unsigned value, vlc_tick_t deadline) +{ + struct timespec ts = timespec_from_vlc_tick(deadline); + + vlc_timespec_adjust(CLOCK_MONOTONIC, &ts); return vlc_atomic_timedwait_timespec(addr, value, &ts); } @@ -124,6 +133,7 @@ int vlc_atomic_timedwait_daytime(void *addr, unsigned value, time_t deadline) { struct timespec ts = { .tv_sec = deadline, .tv_nsec = 0 }; + vlc_timespec_adjust(CLOCK_REALTIME, &ts); return vlc_atomic_timedwait_timespec(addr, value, &ts); } @@ -141,3 +151,27 @@ void vlc_atomic_notify_all(void *addr) pthread_cond_broadcast(&bucket->wait); pthread_mutex_unlock(&bucket->lock); } + +#ifdef __ELF__ +__attribute__((constructor)) +static void vlc_atomic_clock_select(void) +{ + pthread_condattr_t attr; + + pthread_condattr_init(&attr); + pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); + + for (size_t i = 0; i < ARRAY_SIZE(wait_buckets); i++) + pthread_cond_init(&wait_buckets[i].wait, &attr); + + pthread_condattr_destroy(&attr); + vlc_clock_id = CLOCK_MONOTONIC; +} + +__attribute__((destructor)) +static void vlc_atomic_clock_deselect(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(wait_buckets); i++) + pthread_cond_destroy(&wait_buckets[i].wait); +} +#endif _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
