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")
pa_resample_method_t resample_method;
- struct timespec adjust_timestamp;
+ struct timeval adjust_timestamp;
struct output *master;
pa_idxset* outputs; /* managed in main context */
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;
};
/* 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);
* 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;
}
}
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);
size_t block_size;
- struct timespec timestamp;
+ struct timeval timestamp;
};
static const char* const valid_modargs[] = {
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;
}
}
/* 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);
#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
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
}
USA.
***/
-#include <sys/types.h>
-#include <time.h>
+struct timeval;
-#include <pulse/sample.h>
+/* 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
#include <config.h>
#endif
-#include <sys/utsname.h>
#include <sys/types.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
+#ifdef __linux__
+#include <sys/utsname.h>
+#endif
+
+#ifdef HAVE_POLL_H
+#include <poll.h>
+#else
+#include <pulsecore/poll.h>
+#endif
+
#include <pulse/xmalloc.h>
+#include <pulse/timeval.h>
#include <pulsecore/core-error.h>
#include <pulsecore/rtclock.h>
#include <pulsecore/flist.h>
#include <pulsecore/core-util.h>
+#include <pulsecore/winsock.h>
+
#include "rtpoll.h"
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;
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);
/* 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 */
#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)
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;
#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);
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);
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);
USA.
***/
-#include <poll.h>
#include <sys/types.h>
#include <limits.h>
* 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);