[vlc-commits] Android: use monotonic clock
Rémi Denis-Courmont
git at videolan.org
Tue Oct 16 17:23:38 CEST 2012
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Oct 15 20:53:49 2012 +0300| [3405b7dab84d995cb708a0753ff2e4a843f63134] | committer: Rémi Denis-Courmont
Android: use monotonic clock
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3405b7dab84d995cb708a0753ff2e4a843f63134
---
include/vlc_threads.h | 8 +++++--
src/android/thread.c | 60 ++++++++++++++++++++++++++++++-------------------
2 files changed, 43 insertions(+), 25 deletions(-)
diff --git a/include/vlc_threads.h b/include/vlc_threads.h
index d369178..e38f5ba 100644
--- a/include/vlc_threads.h
+++ b/include/vlc_threads.h
@@ -124,8 +124,12 @@ typedef struct vlc_timer *vlc_timer_t;
typedef struct vlc_thread *vlc_thread_t;
typedef pthread_mutex_t vlc_mutex_t;
#define VLC_STATIC_MUTEX PTHREAD_MUTEX_INITIALIZER
-typedef pthread_cond_t vlc_cond_t;
-#define VLC_STATIC_COND PTHREAD_COND_INITIALIZER
+typedef struct
+{
+ pthread_cond_t cond;
+ unsigned clock;
+} vlc_cond_t;
+#define VLC_STATIC_COND { PTHREAD_COND_INITIALIZER, CLOCK_REALTIME }
typedef pthread_key_t vlc_threadvar_t;
typedef struct vlc_timer *vlc_timer_t;
diff --git a/src/android/thread.c b/src/android/thread.c
index 64aa5a4..0294baa 100644
--- a/src/android/thread.c
+++ b/src/android/thread.c
@@ -35,6 +35,7 @@
#include <signal.h>
#include <errno.h>
#include <time.h>
+#include <assert.h>
#include <sys/types.h>
#include <unistd.h> /* fsync() */
@@ -44,10 +45,6 @@
#include <android/log.h>
#include <sys/syscall.h> /* __NR_gettid */
-/* FIXME: Android has a monotonic clock
- * XXX : how to use it with pthread_cond_wait() ? */
-# warning Monotonic clock not available. Expect timing issues.
-
/* helper */
static struct timespec mtime_to_ts (mtime_t date)
{
@@ -186,44 +183,47 @@ void vlc_threads_setup (libvlc_int_t *p_libvlc)
/* cond */
-void vlc_cond_init (vlc_cond_t *p_condvar)
+void vlc_cond_init (vlc_cond_t *condvar)
{
- if (unlikely(pthread_cond_init (p_condvar, NULL)))
+ if (unlikely(pthread_cond_init (&condvar->cond, NULL)))
abort ();
+ condvar->clock = CLOCK_MONOTONIC;
}
-void vlc_cond_init_daytime (vlc_cond_t *p_condvar)
+void vlc_cond_init_daytime (vlc_cond_t *condvar)
{
- vlc_cond_init(p_condvar);
+ if (unlikely(pthread_cond_init (&condvar->cond, NULL)))
+ abort ();
+ condvar->clock = CLOCK_REALTIME;
}
-void vlc_cond_destroy (vlc_cond_t *p_condvar)
+void vlc_cond_destroy (vlc_cond_t *condvar)
{
- int val = pthread_cond_destroy( p_condvar );
+ int val = pthread_cond_destroy (&condvar->cond);
VLC_THREAD_ASSERT ("destroying condition");
}
-void vlc_cond_signal (vlc_cond_t *p_condvar)
+void vlc_cond_signal (vlc_cond_t *condvar)
{
- int val = pthread_cond_signal( p_condvar );
+ int val = pthread_cond_signal (&condvar->cond);
VLC_THREAD_ASSERT ("signaling condition variable");
}
-void vlc_cond_broadcast (vlc_cond_t *p_condvar)
+void vlc_cond_broadcast (vlc_cond_t *condvar)
{
- pthread_cond_broadcast (p_condvar);
+ pthread_cond_broadcast (&condvar->cond);
}
-void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
+void vlc_cond_wait (vlc_cond_t *condvar, vlc_mutex_t *p_mutex)
{
if (thread) {
vlc_testcancel();
vlc_mutex_lock(&thread->lock);
- thread->cond = p_condvar;
+ thread->cond = &condvar->cond;
vlc_mutex_unlock(&thread->lock);
}
- int val = pthread_cond_wait( p_condvar, p_mutex );
+ int val = pthread_cond_wait (&condvar->cond, p_mutex);
if (thread) {
vlc_mutex_lock(&thread->lock);
@@ -235,19 +235,32 @@ void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
VLC_THREAD_ASSERT ("waiting on condition");
}
-int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
+int vlc_cond_timedwait (vlc_cond_t *condvar, vlc_mutex_t *p_mutex,
mtime_t deadline)
{
struct timespec ts = mtime_to_ts (deadline);
+ int (*cb)(pthread_cond_t *, pthread_mutex_t *, const struct timespec *);
if (thread) {
vlc_testcancel();
vlc_mutex_lock(&thread->lock);
- thread->cond = p_condvar;
+ thread->cond = &condvar->cond;
vlc_mutex_unlock(&thread->lock);
}
- int val = pthread_cond_timedwait (p_condvar, p_mutex, &ts);
+ switch (condvar->clock)
+ {
+ case CLOCK_REALTIME:
+ cb = pthread_cond_timedwait;
+ break;
+ case CLOCK_MONOTONIC:
+ cb = pthread_cond_timedwait_monotonic_np;
+ break;
+ default:
+ assert (0);
+ }
+
+ int val = cb (&condvar->cond, p_mutex, &ts);
if (val != ETIMEDOUT)
VLC_THREAD_ASSERT ("timed-waiting on condition");
@@ -369,11 +382,12 @@ int vlc_set_priority (vlc_thread_t th, int priority)
void vlc_cancel (vlc_thread_t thread_id)
{
+ pthread_cond_t *cond;
+
vlc_atomic_set(&thread_id->killed, true);
vlc_mutex_lock(&thread_id->lock);
- vlc_cond_t *cond = thread_id->cond;
-
+ cond = thread_id->cond;
if (cond)
pthread_cond_broadcast(cond);
vlc_mutex_unlock(&thread_id->lock);
@@ -438,7 +452,7 @@ mtime_t mdate (void)
{
struct timespec ts;
- if (unlikely(clock_gettime (CLOCK_REALTIME, &ts) != 0))
+ if (unlikely(clock_gettime (CLOCK_MONOTONIC, &ts) != 0))
abort ();
return (INT64_C(1000000) * ts.tv_sec) + (ts.tv_nsec / 1000);
More information about the vlc-commits
mailing list