]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/core-rtclock.c
remap: Change remapping function argument type from void to int16_t / float as approp...
[pulseaudio] / src / pulsecore / core-rtclock.c
index 4fe0a47ba041367ed73bd828b55257bf71e08cbb..ee045549c6a1dcba38c6e8c48e9535b0f637ac86 100644 (file)
 #include <config.h>
 #endif
 
+#ifdef OS_IS_DARWIN
+#define _POSIX_C_SOURCE 1
+#endif
+
 #include <stddef.h>
 #include <time.h>
 #include <sys/time.h>
 #include <CoreServices/CoreServices.h>
 #include <mach/mach.h>
 #include <mach/mach_time.h>
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
 #endif
 
 #include <pulse/timeval.h>
 
 #include "core-rtclock.h"
 
+#ifdef OS_IS_WIN32
+static int64_t counter_freq = 0;
+#endif
+
 pa_usec_t pa_rtclock_age(const struct timeval *tv) {
     struct timeval now;
     pa_assert(tv);
@@ -54,16 +67,28 @@ pa_usec_t pa_rtclock_age(const struct timeval *tv) {
 
 struct timeval *pa_rtclock_get(struct timeval *tv) {
 
-#if defined(HAVE_CLOCK_GETTIME)
+#if defined(OS_IS_DARWIN)
+    uint64_t val, abs_time = mach_absolute_time();
+    Nanoseconds nanos;
+
+    nanos = AbsoluteToNanoseconds(*(AbsoluteTime *) &abs_time);
+    val = *(uint64_t *) &nanos;
+
+    tv->tv_sec = val / PA_NSEC_PER_SEC;
+    tv->tv_usec = (val % PA_NSEC_PER_SEC) / PA_NSEC_PER_USEC;
+
+    return tv;
+
+#elif defined(HAVE_CLOCK_GETTIME)
     struct timespec ts;
 
 #ifdef CLOCK_MONOTONIC
     /* No locking or atomic ops for no_monotonic here */
-    static pa_bool_t no_monotonic = FALSE;
+    static bool no_monotonic = false;
 
     if (!no_monotonic)
         if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0)
-            no_monotonic = TRUE;
+            no_monotonic = true;
 
     if (no_monotonic)
 #endif /* CLOCK_MONOTONIC */
@@ -75,65 +100,55 @@ struct timeval *pa_rtclock_get(struct timeval *tv) {
     tv->tv_usec = ts.tv_nsec / PA_NSEC_PER_USEC;
 
     return tv;
+#elif defined(OS_IS_WIN32)
+    if (counter_freq > 0) {
+        LARGE_INTEGER count;
 
-#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
+        pa_assert_se(QueryPerformanceCounter(&count));
 
-       Note: argument is timespec NOT timeval (timespec uses nsec, timeval uses usec)
-    */
+        tv->tv_sec = count.QuadPart / counter_freq;
+        tv->tv_usec = (count.QuadPart % counter_freq) * PA_USEC_PER_SEC / counter_freq;
 
-    /* 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
-
-    tv->tv_sec = time_nsec / PA_NSEC_PER_SEC;
-    tv->tv_usec = time_nsec / PA_NSEC_PER_USEC;
+        return tv;
+    }
+#endif /* HAVE_CLOCK_GETTIME */
 
-    return tv;
+    return pa_gettimeofday(tv);
+}
 
-#else /* OS_IS_DARWIN */
+bool pa_rtclock_hrtimer(void) {
 
-    return pa_gettimeofday(tv);
+#if defined (OS_IS_DARWIN)
+    mach_timebase_info_data_t tbi;
+    uint64_t time_nsec;
 
-#endif
-}
+    mach_timebase_info(&tbi);
 
-pa_bool_t pa_rtclock_hrtimer(void) {
+    /* nsec = nticks * (N/D) - we want 1 tick == resolution !? */
+    time_nsec = tbi.numer / tbi.denom;
+    return time_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC);
 
-#if defined(HAVE_CLOCK_GETTIME)
+#elif defined(HAVE_CLOCK_GETTIME)
     struct timespec ts;
 
 #ifdef CLOCK_MONOTONIC
 
     if (clock_getres(CLOCK_MONOTONIC, &ts) >= 0)
         return ts.tv_sec == 0 && ts.tv_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC);
+
 #endif /* CLOCK_MONOTONIC */
 
     pa_assert_se(clock_getres(CLOCK_REALTIME, &ts) == 0);
     return ts.tv_sec == 0 && ts.tv_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC);
 
-#elif defined (OS_IS_DARWIN)
-    mach_timebase_info_data_t tbi;
-    uint64_t time_nsec;
+#elif defined(OS_IS_WIN32)
 
-    mach_timebase_info(&tbi);
-
-    /* nsec = nticks * (N/D) - we want 1 tick == resolution !? */
-    time_nsec = tbi.numer / tbi.denom;
-    return time_nsec <= (long) (PA_HRTIMER_THRESHOLD_USEC*PA_NSEC_PER_USEC);
+    if (counter_freq > 0)
+        return counter_freq >= (int64_t) (PA_USEC_PER_SEC/PA_HRTIMER_THRESHOLD_USEC);
 
-#else /* OS_IS_DARWIN */
-    return FALSE;
+#endif /* HAVE_CLOCK_GETTIME */
 
-#endif
+    return false;
 }
 
 #define TIMER_SLACK_NS (int) ((500 * PA_NSEC_PER_USEC))
@@ -161,19 +176,23 @@ void pa_rtclock_hrtimer_enable(void) {
         }
     }
 
+#elif defined(OS_IS_WIN32)
+    LARGE_INTEGER freq;
+
+    pa_assert_se(QueryPerformanceFrequency(&freq));
+    counter_freq = freq.QuadPart;
+
 #endif
 }
 
 struct timeval* pa_rtclock_from_wallclock(struct timeval *tv) {
-
-#ifdef HAVE_CLOCK_GETTIME
     struct timeval wc_now, rt_now;
 
+    pa_assert(tv);
+
     pa_gettimeofday(&wc_now);
     pa_rtclock_get(&rt_now);
 
-    pa_assert(tv);
-
     /* pa_timeval_sub() saturates on underflow! */
 
     if (pa_timeval_cmp(&wc_now, tv) < 0)
@@ -182,11 +201,11 @@ struct timeval* pa_rtclock_from_wallclock(struct timeval *tv) {
         pa_timeval_sub(&rt_now, pa_timeval_diff(&wc_now, tv));
 
     *tv = rt_now;
-#endif
 
     return tv;
 }
 
+#ifdef HAVE_CLOCK_GETTIME
 pa_usec_t pa_timespec_load(const struct timespec *ts) {
 
     if (PA_UNLIKELY(!ts))
@@ -211,17 +230,16 @@ struct timespec* pa_timespec_store(struct timespec *ts, pa_usec_t v) {
 
     return ts;
 }
+#endif
 
 static struct timeval* wallclock_from_rtclock(struct timeval *tv) {
-
-#ifdef HAVE_CLOCK_GETTIME
     struct timeval wc_now, rt_now;
 
+    pa_assert(tv);
+
     pa_gettimeofday(&wc_now);
     pa_rtclock_get(&rt_now);
 
-    pa_assert(tv);
-
     /* pa_timeval_sub() saturates on underflow! */
 
     if (pa_timeval_cmp(&rt_now, tv) < 0)
@@ -230,12 +248,11 @@ static struct timeval* wallclock_from_rtclock(struct timeval *tv) {
         pa_timeval_sub(&wc_now, pa_timeval_diff(&rt_now, tv));
 
     *tv = wc_now;
-#endif
 
     return tv;
 }
 
-struct timeval* pa_timeval_rtstore(struct timeval *tv, pa_usec_t v, pa_bool_t rtclock) {
+struct timeval* pa_timeval_rtstore(struct timeval *tv, pa_usec_t v, bool rtclock) {
     pa_assert(tv);
 
     if (v == PA_USEC_INVALID)