[pulseaudio-discuss] [PATCH 4/4] Wrap clock_gettime and friends
Daniel Mack
daniel at caiaq.de
Wed Sep 16 00:15:23 PDT 2009
From: Kim Lester <kim at dfusion.com.au>
OS X does not define clockid_t or clock_gettime() and friends.
Add a wrapper to fix this.
Signed-off-by: Kim Lester <kim at dfusion.com.au>
Signed-off-by: Daniel Mack <daniel at caiaq.de>
---
src/Makefile.am | 1 +
src/pulsecore/core-clock.c | 176 ++++++++++++++++++++++++++++++++++++++++++
src/pulsecore/core-clock.h | 75 ++++++++++++++++++
src/pulsecore/core-rtclock.c | 13 ++--
src/tests/rtstutter.c | 9 +-
5 files changed, 264 insertions(+), 10 deletions(-)
create mode 100644 src/pulsecore/core-clock.c
create mode 100644 src/pulsecore/core-clock.h
diff --git a/src/Makefile.am b/src/Makefile.am
index b12ed8f..f73772e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -580,6 +580,7 @@ libpulsecommon_ at PA_MAJORMINORMICRO@_la_SOURCES = \
pulsecore/conf-parser.c pulsecore/conf-parser.h \
pulsecore/core-error.c pulsecore/core-error.h \
pulsecore/core-rtclock.c pulsecore/core-rtclock.h \
+ pulsecore/core-clock.c pulsecore/core-clock.h \
pulsecore/core-util.c pulsecore/core-util.h \
pulsecore/creds.h \
pulsecore/dynarray.c pulsecore/dynarray.h \
diff --git a/src/pulsecore/core-clock.c b/src/pulsecore/core-clock.c
new file mode 100644
index 0000000..d4a47ce
--- /dev/null
+++ b/src/pulsecore/core-clock.c
@@ -0,0 +1,176 @@
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2009 Kim Lester, Datafusion Systems P/L
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef OS_IS_DARWIN
+#include <CoreServices/CoreServices.h>
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#endif
+
+#include <time.h>
+#include <errno.h>
+
+#include "core-clock.h"
+
+
+int pa_clock_getres(clockid_t clk_id, struct timespec *res) {
+#ifndef OS_IS_DARWIN
+/* #ifdef HAVE_CLOCK_GETRES - use this eventually !? */
+
+ return clock_getres(clk_id, res);
+
+#elif defined(OS_IS_DARWIN)
+
+ mach_timebase_info_data_t tbi;
+ uint64_t time_nsec;
+
+ if (!res) {
+ /* KRL: can one always set errno - cross platform ? */
+ errno = EFAULT;
+ return -1;
+ }
+
+ switch (clk_id) {
+ case PA_CLOCK_REALTIME:
+ /* System-wide realtime clock (may be changed). */
+ case PA_CLOCK_MONOTONIC:
+ /* Clock that cannot be set and represents
+ monotonic time since some unspecified starting point. */
+ case PA_CLOCK_MONOTONIC_RAW:
+ /* What's the difference? */
+ break;
+
+#if 0
+ case PA_CLOCK_PROCESS_CPUTIME_ID:
+ /* High-resolution per-process timer from the CPU. */
+ case PA_CLOCK_THREAD_CPUTIME_ID:
+ /* Thread-specific CPU-time clock. */
+#endif
+
+ default:
+ /* KRL: can one always set errno - cross platform ? */
+ errno = EINVAL;
+ return -1;
+ }
+
+ mach_timebase_info(&tbi);
+
+ /* nsec = nticks * (N/D) - we want 1 tick == resolution !? */
+ time_nsec = tbi.numer / tbi.denom;
+
+ /* I presume this is expected to be set !? */
+ res->tv_sec = time_nsec / 1E9;
+ res->tv_nsec = time_nsec;
+
+ return 0;
+#endif
+}
+
+
+int pa_clock_gettime(clockid_t clk_id, struct timespec *tp) {
+/* can't use HAVE_CLOCK_GETTIME as we override this to be true for Darwin */
+#ifndef OS_IS_DARWIN
+
+ return clock_gettime(clk_id, tp);
+
+#elif defined(OS_IS_DARWIN)
+
+ static mach_timebase_info_data_t tbi;
+ uint64_t nticks;
+ uint64_t time_nsec;
+
+ /* Refer Apple ADC QA1398
+ Also: http://devworld.apple.com/documentation/Darwin/Conceptual/KernelProgramming/services/services.html
+
+ Note: argument is timespec NOT timeval (timespec uses nsec, timeval uses usec)
+ */
+
+ if (!tp) {
+ /* KRL: can one always set errno - cross platform ? */
+ errno = EFAULT;
+ return -1; // an error occurred
+ }
+
+ switch (clk_id) {
+ case PA_CLOCK_REALTIME:
+ /* System-wide realtime clock (may be changed). */
+ case PA_CLOCK_MONOTONIC:
+ /* Clock that cannot be set and represents
+ monotonic time since some unspecified starting point. */
+ case PA_CLOCK_MONOTONIC_RAW:
+ /* What's the difference? */
+ break;
+
+#if 0
+ case PA_CLOCK_PROCESS_CPUTIME_ID:
+ /* High-resolution per-process timer from the CPU. */
+ case PA_CLOCK_THREAD_CPUTIME_ID:
+ /* Thread-specific CPU-time clock. */
+#endif
+
+ default:
+ // KRL: can one always set errno - cross platform ?
+ errno = EINVAL; // unsupported clk_id
+ return -1; // an error occurred (unsupported clk_id)
+ }
+
+ /* try and be a mite efficient - maybe I should keep the N/D as a float !? */
+ if (tbi.denom == 0)
+ mach_timebase_info(&tbi);
+
+ nticks = mach_absolute_time();
+ time_nsec = nticks * tbi.numer / tbi.denom; // see above
+
+ tp->tv_sec = time_nsec / 1E9;
+ tp->tv_nsec = time_nsec;
+
+ /* FIXME: For CLOCK_REALTIME - modify by epoch else intermixing results of
+ gettimeofday() and this may cause confusion ....
+ However we probably want MONOTONIC anyway... */
+
+ return 0;
+
+#else
+
+ /* No clock_gettime() or replacement :-( */
+
+#endif
+}
+
+
+int pa_clock_settime(clockid_t clk_id, const struct timespec *tp) {
+#ifndef OS_IS_DARWIN
+/* #ifdef HAVE_CLOCK_SETTIME - use this eventually !? */
+
+ return clock_settime(clk_id, tp);
+
+#else
+
+ /* NOT IMPLEMENTED */
+ errno = EINVAL;
+ return -1;
+
+#endif
+}
diff --git a/src/pulsecore/core-clock.h b/src/pulsecore/core-clock.h
new file mode 100644
index 0000000..12d410b
--- /dev/null
+++ b/src/pulsecore/core-clock.h
@@ -0,0 +1,75 @@
+#ifndef foopulseclockhfoo
+#define foopulseclockhfoo
+
+/***
+ This file is part of PulseAudio.
+
+ Copyright 2009 Kim Lester, Datafusion Systems P/L
+
+ PulseAudio is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as
+ published by the Free Software Foundation; either version 2.1 of the
+ License, or (at your option) any later version.
+
+ PulseAudio is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with PulseAudio; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA.
+***/
+
+#include <time.h>
+
+
+#ifdef OS_IS_DARWIN
+
+/* OS X does not define clockid_t or clock_gettime() and friends */
+typedef int clockid_t;
+
+#define PA_CLOCK_REALTIME 0
+#define PA_CLOCK_MONOTONIC 1
+
+#if 0
+/* Not yet implemented, commented out for calling code that tests #defines: */
+#define PA_CLOCK_PROCESS_CPUTIME_ID 2
+#define PA_CLOCK_THREAD_CPUTIME_ID 3
+#endif
+
+/* treated as MONOTONIC for now...: */
+#define PA_CLOCK_MONOTONIC_RAW 4
+
+#else
+
+/* probably shouldn't expose the underlying implementation, however
+ it is expedient for now as calling code tests for #define existence */
+#ifdef CLOCK_REALTIME
+#define PA_CLOCK_REALTIME CLOCK_REALTIME
+#endif
+
+#ifdef CLOCK_MONOTONIC
+#define PA_CLOCK_MONOTONIC CLOCK_MONOTONIC
+#endif
+
+#ifdef CLOCK_PROCESS_CPUTIME_ID
+#define PA_CLOCK_PROCESS_CPUTIME_ID CLOCK_PROCESS_CPUTIME_ID
+#endif
+
+#ifdef CLOCK_THREAD_CPUTIME_ID
+#define PA_CLOCK_THREAD_CPUTIME_ID CLOCK_THREAD_CPUTIME_ID
+#endif
+
+#if CLOCK_MONOTONIC_RAW
+#define PA_CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC_RAW
+#endif
+
+#endif
+
+int pa_clock_getres(clockid_t clk_id, struct timespec *res);
+int pa_clock_gettime(clockid_t clk_id, struct timespec *tp);
+int pa_clock_settime(clockid_t clk_id, const struct timespec *tp);
+
+#endif
diff --git a/src/pulsecore/core-rtclock.c b/src/pulsecore/core-rtclock.c
index 3b3e3a6..8d564f3 100644
--- a/src/pulsecore/core-rtclock.c
+++ b/src/pulsecore/core-rtclock.c
@@ -38,6 +38,7 @@
#include <pulsecore/core-error.h>
#include "core-rtclock.h"
+#include "core-clock.h"
pa_usec_t pa_rtclock_age(const struct timeval *tv) {
struct timeval now;
@@ -50,17 +51,17 @@ struct timeval *pa_rtclock_get(struct timeval *tv) {
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;
-#ifdef CLOCK_MONOTONIC
+#ifdef PA_CLOCK_MONOTONIC
/* No locking or atomic ops for no_monotonic here */
static pa_bool_t no_monotonic = FALSE;
if (!no_monotonic)
- if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0)
+ if (pa_clock_gettime(PA_CLOCK_MONOTONIC, &ts) < 0)
no_monotonic = TRUE;
if (no_monotonic)
#endif
- pa_assert_se(clock_gettime(CLOCK_REALTIME, &ts) == 0);
+ pa_assert_se(pa_clock_gettime(PA_CLOCK_REALTIME, &ts) == 0);
pa_assert(tv);
@@ -80,12 +81,12 @@ pa_bool_t pa_rtclock_hrtimer(void) {
#ifdef HAVE_CLOCK_GETTIME
struct timespec ts;
-#ifdef CLOCK_MONOTONIC
- if (clock_getres(CLOCK_MONOTONIC, &ts) >= 0)
+#ifdef PA_CLOCK_MONOTONIC
+ if (pa_clock_getres(PA_CLOCK_MONOTONIC, &ts) >= 0)
return ts.tv_sec == 0 && ts.tv_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC);
#endif
- pa_assert_se(clock_getres(CLOCK_REALTIME, &ts) == 0);
+ pa_assert_se(pa_clock_getres(PA_CLOCK_REALTIME, &ts) == 0);
return ts.tv_sec == 0 && ts.tv_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC);
#else /* HAVE_CLOCK_GETTIME */
diff --git a/src/tests/rtstutter.c b/src/tests/rtstutter.c
index c93fee9..ba5f109 100644
--- a/src/tests/rtstutter.c
+++ b/src/tests/rtstutter.c
@@ -37,6 +37,7 @@
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
#include <pulsecore/core-util.h>
+#include <pulsecore/core-clock.h>
static int msec_lower, msec_upper;
@@ -67,8 +68,8 @@ static void* work(void *p) {
pa_log_notice("CPU%i: Sleeping for 1s", PA_PTR_TO_UINT(p));
sleep(1);
-#ifdef CLOCK_REALTIME
- pa_assert_se(clock_gettime(CLOCK_REALTIME, &end) == 0);
+#ifdef PA_CLOCK_REALTIME
+ pa_assert_se(pa_clock_gettime(PA_CLOCK_REALTIME, &end) == 0);
#endif
nsec =
@@ -86,8 +87,8 @@ static void* work(void *p) {
}
do {
-#ifdef CLOCK_REALTIME
- pa_assert_se(clock_gettime(CLOCK_REALTIME, &now) == 0);
+#ifdef PA_CLOCK_REALTIME
+ pa_assert_se(pa_clock_gettime(PA_CLOCK_REALTIME, &now) == 0);
#endif
} while (now.tv_sec < end.tv_sec ||
(now.tv_sec == end.tv_sec && now.tv_nsec < end.tv_nsec));
--
1.6.3.3
More information about the pulseaudio-discuss
mailing list