From: Pierre Ossman Date: Wed, 3 Oct 2007 14:43:56 +0000 (+0000) Subject: Adapt rtpoll and friends to Windows by replacing timespec with timeval and X-Git-Tag: v0.9.11~63^2~1^2~44 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8dcc1fa6161c2a507d008a50a6d7f5170ce54a14;p=platform%2Fupstream%2Fpulseaudio.git Adapt rtpoll and friends to Windows by replacing timespec with timeval and add a fallback when clock_gettime() isn't available. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/lennart@1926 fefdeb5f-60dc-0310-8127-8f9354f1896f --- diff --git a/configure.ac b/configure.ac index b22a990..152cd51 100644 --- a/configure.ac +++ b/configure.ac @@ -271,9 +271,10 @@ AC_CHECK_FUNCS([lrintf strtof]) AC_FUNC_FORK AC_FUNC_GETGROUPS AC_FUNC_SELECT_ARGTYPES -AC_CHECK_FUNCS([chmod chown getaddrinfo getgrgid_r getpwuid_r gettimeofday \ - getuid inet_ntop inet_pton nanosleep pipe posix_fadvise posix_madvise \ - posix_memalign setpgid setsid shm_open sigaction sleep sysconf]) +AC_CHECK_FUNCS([chmod chown clock_gettime getaddrinfo getgrgid_r \ + getpwuid_r gettimeofday getuid inet_ntop inet_pton mlock nanosleep \ + pipe posix_fadvise posix_madvise posix_memalign setpgid setsid shm_open \ + sigaction sleep sysconf]) AC_CHECK_FUNCS([mkfifo], [HAVE_MKFIFO=1], [HAVE_MKFIFO=0]) AM_CONDITIONAL(HAVE_MKFIFO, test "x$HAVE_MKFIFO" = "x1") diff --git a/src/modules/module-combine.c b/src/modules/module-combine.c index 447f41c..665bf9d 100644 --- a/src/modules/module-combine.c +++ b/src/modules/module-combine.c @@ -118,7 +118,7 @@ struct userdata { pa_resample_method_t resample_method; - struct timespec adjust_timestamp; + struct timeval adjust_timestamp; struct output *master; pa_idxset* outputs; /* managed in main context */ @@ -126,7 +126,7 @@ struct userdata { struct { PA_LLIST_HEAD(struct output, active_outputs); /* managed in IO thread context */ pa_atomic_t running; /* we cache that value here, so that every thread can query it cheaply */ - struct timespec timestamp; + struct timeval timestamp; pa_bool_t in_null_mode; } thread_info; }; @@ -247,17 +247,17 @@ static void thread_func(void *userdata) { /* If no outputs are connected, render some data and drop it immediately. */ if (u->sink->thread_info.state == PA_SINK_RUNNING && !u->thread_info.active_outputs) { - struct timespec now; + struct timeval now; pa_rtclock_get(&now); - if (!u->thread_info.in_null_mode || pa_timespec_cmp(&u->thread_info.timestamp, &now) <= 0) { + if (!u->thread_info.in_null_mode || pa_timeval_cmp(&u->thread_info.timestamp, &now) <= 0) { pa_sink_skip(u->sink, u->block_size); if (!u->thread_info.in_null_mode) u->thread_info.timestamp = now; - pa_timespec_add(&u->thread_info.timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec)); + pa_timeval_add(&u->thread_info.timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec)); } pa_rtpoll_set_timer_absolute(u->rtpoll, &u->thread_info.timestamp); @@ -563,10 +563,10 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse * sink_get_latency_cb() below */ if (u->thread_info.in_null_mode) { - struct timespec now; + struct timeval now; - if (pa_timespec_cmp(&u->thread_info.timestamp, pa_rtclock_get(&now)) > 0) { - *((pa_usec_t*) data) = pa_timespec_diff(&u->thread_info.timestamp, &now); + if (pa_timeval_cmp(&u->thread_info.timestamp, pa_rtclock_get(&now)) > 0) { + *((pa_usec_t*) data) = pa_timeval_diff(&u->thread_info.timestamp, &now); break; } } @@ -947,7 +947,7 @@ int pa__init(pa_module*m) { u->thread = NULL; u->resample_method = resample_method; u->outputs = pa_idxset_new(NULL, NULL); - pa_timespec_reset(&u->adjust_timestamp); + memset(&u->adjust_timestamp, 0, sizeof(u->adjust_timestamp)); u->sink_new_slot = u->sink_unlink_slot = u->sink_state_changed_slot = NULL; PA_LLIST_HEAD_INIT(struct output, u->thread_info.active_outputs); pa_atomic_store(&u->thread_info.running, FALSE); diff --git a/src/modules/module-null-sink.c b/src/modules/module-null-sink.c index 04df239..d993988 100644 --- a/src/modules/module-null-sink.c +++ b/src/modules/module-null-sink.c @@ -75,7 +75,7 @@ struct userdata { size_t block_size; - struct timespec timestamp; + struct timeval timestamp; }; static const char* const valid_modargs[] = { @@ -100,14 +100,14 @@ static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offse break; case PA_SINK_MESSAGE_GET_LATENCY: { - struct timespec now; + struct timeval now; pa_rtclock_get(&now); - if (pa_timespec_cmp(&u->timestamp, &now) > 0) + if (pa_timeval_cmp(&u->timestamp, &now) > 0) *((pa_usec_t*) data) = 0; else - *((pa_usec_t*) data) = pa_timespec_diff(&u->timestamp, &now); + *((pa_usec_t*) data) = pa_timeval_diff(&u->timestamp, &now); break; } } @@ -132,13 +132,13 @@ static void thread_func(void *userdata) { /* Render some data and drop it immediately */ if (u->sink->thread_info.state == PA_SINK_RUNNING) { - struct timespec now; + struct timeval now; pa_rtclock_get(&now); - if (pa_timespec_cmp(&u->timestamp, &now) <= 0) { + if (pa_timeval_cmp(&u->timestamp, &now) <= 0) { pa_sink_skip(u->sink, u->block_size); - pa_timespec_add(&u->timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec)); + pa_timeval_add(&u->timestamp, pa_bytes_to_usec(u->block_size, &u->sink->sample_spec)); } pa_rtpoll_set_timer_absolute(u->rtpoll, &u->timestamp); diff --git a/src/pulsecore/rtclock.c b/src/pulsecore/rtclock.c index 7dd83b3..0d983f8 100644 --- a/src/pulsecore/rtclock.c +++ b/src/pulsecore/rtclock.c @@ -35,123 +35,48 @@ #include "rtclock.h" -struct timespec *pa_timespec_store(struct timespec *a, pa_usec_t u) { - pa_assert(a); +pa_usec_t pa_rtclock_age(const struct timeval *tv) { + struct timeval now; + pa_assert(tv); - a->tv_sec = u / PA_USEC_PER_SEC; - - u -= (pa_usec_t) a->tv_sec * PA_USEC_PER_SEC; - - a->tv_nsec = u * 1000; - - return a; -} - -struct timespec *pa_timespec_reset(struct timespec *a) { - pa_assert(a); - - a->tv_sec = a->tv_nsec = 0; - return a; -} - -pa_usec_t pa_timespec_load(struct timespec *ts) { - pa_assert(ts); - - return (pa_usec_t) ts->tv_sec * PA_USEC_PER_SEC + (pa_usec_t) (ts->tv_nsec / 1000); -} - -pa_usec_t pa_timespec_diff(const struct timespec *a, const struct timespec *b) { - pa_usec_t r; - - pa_assert(a); - pa_assert(b); - - /* Check which whan is the earlier time and swap the two arguments if required. */ - if (pa_timespec_cmp(a, b) < 0) { - const struct timespec *c; - c = a; - a = b; - b = c; - } - - /* Calculate the second difference*/ - r = ((pa_usec_t) a->tv_sec - b->tv_sec) * PA_USEC_PER_SEC; - - /* Calculate the microsecond difference */ - if (a->tv_nsec > b->tv_nsec) - r += (pa_usec_t) ((a->tv_nsec - b->tv_nsec) / 1000); - else if (a->tv_nsec < b->tv_nsec) - r -= (pa_usec_t) ((b->tv_nsec - a->tv_nsec) / 1000); - - return r; -} - -int pa_timespec_cmp(const struct timespec *a, const struct timespec *b) { - pa_assert(a); - pa_assert(b); - - if (a->tv_sec < b->tv_sec) - return -1; - - if (a->tv_sec > b->tv_sec) - return 1; - - if (a->tv_nsec < b->tv_nsec) - return -1; - - if (a->tv_nsec > b->tv_nsec) - return 1; - - return 0; + return pa_timeval_diff(pa_rtclock_get(&now), tv); } -struct timespec* pa_timespec_add(struct timespec *ts, pa_usec_t v) { - unsigned long secs; - pa_assert(ts); - - secs = (unsigned long) (v/PA_USEC_PER_SEC); - ts->tv_sec += secs; - v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC; - - ts->tv_nsec += (long) (v*1000); - - /* Normalize */ - while (ts->tv_nsec >= PA_NSEC_PER_SEC) { - ts->tv_sec++; - ts->tv_nsec -= PA_NSEC_PER_SEC; - } - - return ts; -} - -pa_usec_t pa_rtclock_age(const struct timespec *ts) { - struct timespec now; - pa_assert(ts); - - return pa_timespec_diff(pa_rtclock_get(&now), ts); -} - -struct timespec *pa_rtclock_get(struct timespec *ts) { +struct timeval *pa_rtclock_get(struct timeval *tv) { +#ifdef HAVE_CLOCK_GETTIME static int no_monotonic = 0; + struct timespec ts; /* No locking or atomic ops for no_monotonic here */ - - pa_assert(ts); if (!no_monotonic) { #ifdef CLOCK_MONOTONIC - if (clock_gettime(CLOCK_MONOTONIC, ts) >= 0) - return ts; + if (clock_gettime(CLOCK_MONOTONIC, &ts) >= 0) + goto out; #endif no_monotonic = 1; } pa_assert_se(clock_gettime(CLOCK_REALTIME, ts) == 0); - return ts; + +out: + pa_assert(tv); + + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + + return tv; + +#else /* HAVE_CLOCK_GETTIME */ + + return pa_gettimeofday(tv); + +#endif } int pa_rtclock_hrtimer(void) { +#ifdef HAVE_CLOCK_GETTIME struct timespec ts; #ifdef CLOCK_MONOTONIC @@ -161,5 +86,11 @@ int pa_rtclock_hrtimer(void) { pa_assert_se(clock_getres(CLOCK_REALTIME, &ts) == 0); return ts.tv_sec == 0 && ts.tv_nsec <= PA_HRTIMER_THRESHOLD_USEC*1000; + +#else /* HAVE_CLOCK_GETTIME */ + + return 0; + +#endif } diff --git a/src/pulsecore/rtclock.h b/src/pulsecore/rtclock.h index cfc968f..0d232a0 100644 --- a/src/pulsecore/rtclock.h +++ b/src/pulsecore/rtclock.h @@ -24,25 +24,14 @@ USA. ***/ -#include -#include +struct timeval; -#include +/* Something like pulse/timeval.h but based on CLOCK_MONOTONIC */ -/* Something like pulse/timeval.h but based on CLOCK_MONOTONIC and - * timespec instead of timeval */ - -struct timespec *pa_rtclock_get(struct timespec *ts); -pa_usec_t pa_rtclock_age(const struct timespec *tv); +struct timeval *pa_rtclock_get(struct timeval *ts); +pa_usec_t pa_rtclock_age(const struct timeval *tv); int pa_rtclock_hrtimer(void); -struct timespec *pa_timespec_store(struct timespec *a, pa_usec_t u); -struct timespec *pa_timespec_reset(struct timespec *a); -pa_usec_t pa_timespec_load(struct timespec *tv); -struct timespec *pa_timespec_add(struct timespec *tv, pa_usec_t t); -pa_usec_t pa_timespec_diff(const struct timespec *a, const struct timespec *b); -int pa_timespec_cmp(const struct timespec *a, const struct timespec *b); - /* timer with a resolution better than this are considered high-resolution */ #define PA_HRTIMER_THRESHOLD_USEC 10 diff --git a/src/pulsecore/rtpoll.c b/src/pulsecore/rtpoll.c index de0ffa4..c81fcd1 100644 --- a/src/pulsecore/rtpoll.c +++ b/src/pulsecore/rtpoll.c @@ -26,14 +26,24 @@ #include #endif -#include #include #include #include #include #include +#ifdef __linux__ +#include +#endif + +#ifdef HAVE_POLL_H +#include +#else +#include +#endif + #include +#include #include #include @@ -43,6 +53,8 @@ #include #include +#include + #include "rtpoll.h" struct pa_rtpoll { @@ -50,7 +62,7 @@ struct pa_rtpoll { unsigned n_pollfd_alloc, n_pollfd_used; pa_bool_t timer_enabled; - struct timespec next_elapse; + struct timeval next_elapse; pa_usec_t period; pa_bool_t scan_for_dead; @@ -290,7 +302,7 @@ static void reset_all_revents(pa_rtpoll *p) { int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { pa_rtpoll_item *i; int r = 0; - struct timespec timeout; + struct timeval timeout; pa_assert(p); pa_assert(!p->running); @@ -357,15 +369,14 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { /* Calculate timeout */ if (!wait || p->quit) { timeout.tv_sec = 0; - timeout.tv_nsec = 0; + timeout.tv_usec = 0; } else if (p->timer_enabled) { - struct timespec now; + struct timeval now; pa_rtclock_get(&now); - if (pa_timespec_cmp(&p->next_elapse, &now) <= 0) - memset(&timeout, 0, sizeof(timeout)); - else - pa_timespec_store(&timeout, pa_timespec_diff(&p->next_elapse, &now)); + memset(&timeout, 0, sizeof(timeout)); + if (pa_timeval_cmp(&p->next_elapse, &now) > 0) + pa_timeval_add(&timeout, pa_timeval_diff(&p->next_elapse, &now)); } /* OK, now let's sleep */ @@ -380,7 +391,7 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { #endif #endif - r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled ? (timeout.tv_sec*1000) + (timeout.tv_nsec / 1000000) : -1); + r = poll(p->pollfd, p->n_pollfd_used, p->timer_enabled ? (timeout.tv_sec*1000) + (timeout.tv_usec / 1000) : -1); if (r < 0) { if (errno == EAGAIN || errno == EINTR) @@ -393,14 +404,14 @@ int pa_rtpoll_run(pa_rtpoll *p, pa_bool_t wait) { if (p->timer_enabled) { if (p->period > 0) { - struct timespec now; + struct timeval now; pa_rtclock_get(&now); - pa_timespec_add(&p->next_elapse, p->period); + pa_timeval_add(&p->next_elapse, p->period); /* Guarantee that the next timeout will happen in the future */ - if (pa_timespec_cmp(&p->next_elapse, &now) < 0) - pa_timespec_add(&p->next_elapse, (pa_timespec_diff(&now, &p->next_elapse) / p->period + 1) * p->period); + if (pa_timeval_cmp(&p->next_elapse, &now) < 0) + pa_timeval_add(&p->next_elapse, (pa_timeval_diff(&now, &p->next_elapse) / p->period + 1) * p->period); } else p->timer_enabled = FALSE; @@ -487,7 +498,7 @@ static void update_timer(pa_rtpoll *p) { #endif } -void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts) { +void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timeval *ts) { pa_assert(p); pa_assert(ts); @@ -503,7 +514,7 @@ void pa_rtpoll_set_timer_periodic(pa_rtpoll *p, pa_usec_t usec) { p->period = usec; pa_rtclock_get(&p->next_elapse); - pa_timespec_add(&p->next_elapse, usec); + pa_timeval_add(&p->next_elapse, usec); p->timer_enabled = TRUE; update_timer(p); @@ -514,7 +525,7 @@ void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec) { p->period = 0; pa_rtclock_get(&p->next_elapse); - pa_timespec_add(&p->next_elapse, usec); + pa_timeval_add(&p->next_elapse, usec); p->timer_enabled = TRUE; update_timer(p); diff --git a/src/pulsecore/rtpoll.h b/src/pulsecore/rtpoll.h index a1242b3..d38d086 100644 --- a/src/pulsecore/rtpoll.h +++ b/src/pulsecore/rtpoll.h @@ -24,7 +24,6 @@ USA. ***/ -#include #include #include @@ -75,7 +74,7 @@ void pa_rtpoll_install(pa_rtpoll *p); * cleanly. */ int pa_rtpoll_run(pa_rtpoll *f, pa_bool_t wait); -void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timespec *ts); +void pa_rtpoll_set_timer_absolute(pa_rtpoll *p, const struct timeval *ts); void pa_rtpoll_set_timer_periodic(pa_rtpoll *p, pa_usec_t usec); void pa_rtpoll_set_timer_relative(pa_rtpoll *p, pa_usec_t usec); void pa_rtpoll_set_timer_disabled(pa_rtpoll *p);