#include <math.h>
#include <errno.h>
+#if defined(__APPLE__) && !defined(HAVE_MACH_ABSOLUTE_TIME)
+#define HAVE_MACH_ABSOLUTE_TIME
+#endif
+#ifdef HAVE_MACH_ABSOLUTE_TIME
+#include <mach/mach_time.h>
+#endif
+
#include "pa_util.h"
#include "pa_unix_util.h"
#include "pa_debugprint.h"
#endif
}
-/* *** NOT USED YET: ***
-static int usePerformanceCounter_;
-static double microsecondsPerTick_;
+#ifdef HAVE_MACH_ABSOLUTE_TIME
+/*
+ Discussion on the CoreAudio mailing list suggests that calling
+ gettimeofday (or anything else in the BSD layer) is not real-time
+ safe, so we use mach_absolute_time on OSX. This implementation is
+ based on these two links:
+
+ Technical Q&A QA1398 - Mach Absolute Time Units
+ http://developer.apple.com/mac/library/qa/qa2004/qa1398.html
+
+ Tutorial: Performance and Time.
+ http://www.macresearch.org/tutorial_performance_and_time
*/
+/* Scaler to convert the result of mach_absolute_time to seconds */
+static double machSecondsConversionScaler_ = 0.0;
+#endif
+
void PaUtil_InitializeClock( void )
{
- /* TODO */
+#ifdef HAVE_MACH_ABSOLUTE_TIME
+ mach_timebase_info_data_t info;
+ kern_return_t err = mach_timebase_info( &info );
+ if( err == 0 )
+ machSecondsConversionScaler_ = 1e-9 * (double) info.numer / (double) info.denom;
+#endif
}
PaTime PaUtil_GetTime( void )
{
-#ifdef HAVE_CLOCK_GETTIME
+#ifdef HAVE_MACH_ABSOLUTE_TIME
+ return mach_absolute_time() * machSecondsConversionScaler_;
+#elif defined(HAVE_CLOCK_GETTIME)
struct timespec tp;
clock_gettime(CLOCK_REALTIME, &tp);
- return (PaTime)(tp.tv_sec + tp.tv_nsec / 1.e9);
+ return (PaTime)(tp.tv_sec + tp.tv_nsec * 1e-9);
#else
struct timeval tv;
gettimeofday( &tv, NULL );
- return (PaTime) tv.tv_usec / 1000000. + tv.tv_sec;
+ return (PaTime) tv.tv_usec * 1e-6 + tv.tv_sec;
#endif
}
/* paUnixMainThread
* We have to be a bit careful with defining this global variable,
* as explained below. */
-#ifdef __apple__
+#ifdef __APPLE__
/* apple/gcc has a "problem" with global vars and dynamic libs.
Initializing it seems to fix the problem.
Described a bit in this thread: