Commit 45c2bc08 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Fix vlc_cond_timedwait() without monotonic clock

parent 0c677da7
...@@ -39,7 +39,10 @@ ...@@ -39,7 +39,10 @@
#include <errno.h> #include <errno.h>
#include <time.h> #include <time.h>
#include <pthread.h>
#include <sched.h> #include <sched.h>
#include <sys/time.h> /* gettimeofday() */
#ifdef __linux__ #ifdef __linux__
# include <sys/syscall.h> /* SYS_gettid */ # include <sys/syscall.h> /* SYS_gettid */
#endif #endif
...@@ -49,7 +52,6 @@ ...@@ -49,7 +52,6 @@
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
# include <sys/time.h> /* gettimeofday in vlc_cond_timedwait */
# include <mach/mach_init.h> /* mach_task_self in semaphores */ # include <mach/mach_init.h> /* mach_task_self in semaphores */
# include <sys/sysctl.h> # include <sys/sysctl.h>
#endif #endif
...@@ -81,32 +83,20 @@ ...@@ -81,32 +83,20 @@
#if (_POSIX_TIMERS > 0) #if (_POSIX_TIMERS > 0)
static unsigned vlc_clock_prec; static unsigned vlc_clock_prec;
# if (_POSIX_CLOCK_SELECTION > 0) # if (_POSIX_MONOTONIC_CLOCK > 0)
/* POSIX clock selection is needed so that vlc_cond_timewait() is consistent
* with mdate() and mwait(). Otherwise, the monotonic clock cannot be used.
* Fortunately, clock selection has become mandatory as of 2008 so that really
* only broken old systems still lack it. */
# if (_POSIX_MONOTONIC_CLOCK > 0)
/* Compile-time POSIX monotonic clock support */ /* Compile-time POSIX monotonic clock support */
# define vlc_clock_id (CLOCK_MONOTONIC) # define vlc_clock_id (CLOCK_MONOTONIC)
# elif (_POSIX_MONOTONIC_CLOCK == 0) # elif (_POSIX_MONOTONIC_CLOCK == 0)
/* Run-time POSIX monotonic clock support (see clock_setup() below) */ /* Run-time POSIX monotonic clock support (see clock_setup() below) */
static clockid_t vlc_clock_id; static clockid_t vlc_clock_id;
# else # else
/* No POSIX monotonic clock support */ /* No POSIX monotonic clock support */
# define vlc_clock_id (CLOCK_REALTIME) # define vlc_clock_id (CLOCK_REALTIME)
# warning Monotonic clock not available. Expect timing issues. # warning Monotonic clock not available. Expect timing issues.
# endif /* _POSIX_MONOTONIC_CLOKC */ # endif /* _POSIX_MONOTONIC_CLOKC */
# else
/* No POSIX clock selection. */
# define pthread_condattr_setclock(attr, clock) (attr, clock, 0)
# warning Clock selection not available. Expect timing issues.
# endif /* _POSIX_CLOCK_SELECTION */
static void vlc_clock_setup_once (void) static void vlc_clock_setup_once (void)
{ {
...@@ -135,6 +125,7 @@ int nanosleep (struct timespec *, struct timespec *); ...@@ -135,6 +125,7 @@ int nanosleep (struct timespec *, struct timespec *);
# endif # endif
# define vlc_clock_setup() (void)0 # define vlc_clock_setup() (void)0
# warning Monotonic clock not available. Expect timing issues.
#endif /* _POSIX_TIMERS */ #endif /* _POSIX_TIMERS */
static struct timespec mtime_to_ts (mtime_t date) static struct timespec mtime_to_ts (mtime_t date)
...@@ -466,21 +457,22 @@ void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex) ...@@ -466,21 +457,22 @@ void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex, int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
mtime_t deadline) mtime_t deadline)
{ {
#if defined(__APPLE__) && !defined(__powerpc__) && !defined( __ppc__ ) && !defined( __ppc64__ ) #if (_POSIX_MONOTONIC_CLOCK > 0) && (_POSIX_CLOCK_SELECTION < 0)
/* mdate() is the monotonic clock, timedwait origin is gettimeofday() which /* Without clock selection, the real-time clock is used for the absolute
* isn't monotonic. Use imedwait_relative_np() instead * timeout in pthread_cond_timedwait(). We may need to adjust. */
*/ # error FIXME: breaks vlc_cond_init_daytime()
mtime_t base = mdate(); if (vlc_clock_id != CLOCK_REALTIME)
deadline -= base; {
if (deadline < 0) struct timeval tv;
deadline = 0;
deadline -= mdate ();
gettimeofday (&tv, NULL);
deadline += tv.tv_sec * UINT64_C(1000000) + tv.tv_usec;
}
#endif
struct timespec ts = mtime_to_ts (deadline);
int val = pthread_cond_timedwait_relative_np(p_condvar, p_mutex, &ts);
#else
struct timespec ts = mtime_to_ts (deadline); struct timespec ts = mtime_to_ts (deadline);
int val = pthread_cond_timedwait (p_condvar, p_mutex, &ts); int val = pthread_cond_timedwait (p_condvar, p_mutex, &ts);
#endif
if (val != ETIMEDOUT) if (val != ETIMEDOUT)
VLC_THREAD_ASSERT ("timed-waiting on condition"); VLC_THREAD_ASSERT ("timed-waiting on condition");
return val; return val;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment