clock_gettime() is defined in POSIX.1-2001. However, some systems
(notably OSX) do not provide it. To allow such system to compile check,
clock_gettime() is added to libcompat. In the libcompat version, equivalent
calls for OSX are added to get time. For other systems, clock_gettime()
simply sets the time to 0.
git-svn-id: svn+ssh://svn.code.sf.net/p/check/code/trunk@644
64e312b2-a51f-0410-8e61-
82d0ca0eb02a
# Checks for libraries.
-# Link with rt for clock_gettime
-LIBS=-lrt
-AC_SUBST(LIBS)
+# Check if clock_gettime is available in lib rt, and if so,
+# add -lrt to LIBS
+AC_CHECK_LIB([rt], [clock_gettime])
# Checks for header files.
AC_HEADER_STDC
AC_DEFINE_UNQUOTED(ENABLE_SUBUNIT, $ENABLE_SUBUNIT, [Subunit protocol result output])
AM_CONDITIONAL(SUBUNIT, test x"$enable_subunit" != "xfalse")
-
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_REALLOC
-AC_REPLACE_FUNCS([fileno localtime_r pipe putenv setenv sleep strdup strsignal unsetenv])
-AC_CHECK_DECLS([fileno, localtime_r, pipe, putenv, setenv, sleep, strdup, strsignal, unsetenv])
+AC_REPLACE_FUNCS([clock_gettime fileno localtime_r pipe putenv setenv sleep strdup strsignal unsetenv])
+AC_CHECK_DECLS([clock_gettime, fileno, localtime_r, pipe, putenv, setenv, sleep, strdup, strsignal, unsetenv])
# Checks for pthread implementation.
ACX_PTHREAD
--- /dev/null
+#include "libcompat.h"
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef __MACH__
+#include <mach/clock.h>
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#include <CoreServices/CoreServices.h>
+#include <unistd.h>
+#endif
+
+#define NANOSECONDS_PER_SECOND 1000000000
+
+
+
+int clock_gettime(int clk_id CK_ATTRIBUTE_UNUSED, struct timespec *ts)
+{
+
+#ifdef __MACH__
+ /* OS X does not have clock_gettime, use mach_absolute_time */
+
+ static mach_timebase_info_data_t sTimebaseInfo;
+ uint64_t rawTime;
+ uint64_t nanos;
+
+ rawTime = mach_absolute_time();
+
+ /*
+ * OS X has a function to convert abs time to nano seconds: AbsoluteToNanoseconds
+ * However, the function may not be available as we may not have
+ * access to CoreServices. Because of this, we convert the abs time
+ * to nano seconds manually.
+ */
+
+ /*
+ * First grab the time base used on the system, if this is the first
+ * time we are being called. We can check if the value is uninitialized,
+ * as the denominator will be zero.
+ */
+ if ( sTimebaseInfo.denom == 0 )
+ {
+ (void) mach_timebase_info(&sTimebaseInfo);
+ }
+
+ /*
+ * Do the conversion. We hope that the multiplication doesn't
+ * overflow; the price you pay for working in fixed point.
+ */
+ nanos = rawTime * sTimebaseInfo.numer / sTimebaseInfo.denom;
+
+ /*
+ * Fill in the timespec container
+ */
+ ts->tv_sec = nanos / NANOSECONDS_PER_SECOND;
+ ts->tv_nsec = nanos - (ts->tv_sec * NANOSECONDS_PER_SECOND);
+#else
+ /*
+ * As there is no function to fall back onto to get the current
+ * time, zero out the time so the caller will have a sane value.
+ */
+ ts->tv_sec = 0;
+ ts->tv_nsec = 0;
+#endif
+
+ return 0;
+}
int unsetenv (const char *name);
#endif /* !HAVE_DECL_UNSETENV */
+#ifndef HAVE_LIBRT
+/*
+ * On systems where clock_gettime() is not available, the
+ * definition for CLOCK_MONOTONIC will also not be available.
+ * This variable should define which type of clock clock_gettime()
+ * should use. We define it here if it is not defined simply
+ * so the reimplementation can ignore it.
+ */
+#ifndef CLOCK_MONOTONIC
+#define CLOCK_MONOTONIC 0
+#endif
+int clock_gettime(int clk_id, struct timespec *ts);
+#endif /* HAVE_LIBRT */
+
/* silence warnings about an empty library */
void ck_do_nothing (void);