From: brarcher Date: Sun, 4 Nov 2012 03:18:59 +0000 (+0000) Subject: Add override for clock_gettime() in libcompat for systems that do not supply it X-Git-Tag: 0.10.0~536 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=68bf2548eb7f57972425574db7ed3382851f619c;p=check Add override for clock_gettime() in libcompat for systems that do not supply it 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 --- diff --git a/configure.ac b/configure.ac index f78bc33..f280894 100644 --- a/configure.ac +++ b/configure.ac @@ -126,9 +126,9 @@ fi # 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 @@ -153,7 +153,6 @@ AC_SUBST([LIBSUBUNIT_PC]) 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. @@ -170,8 +169,8 @@ AC_CHECK_SIZEOF(long, 4) # 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 diff --git a/lib/clock_gettime.c b/lib/clock_gettime.c new file mode 100644 index 0000000..9d26ce5 --- /dev/null +++ b/lib/clock_gettime.c @@ -0,0 +1,68 @@ +#include "libcompat.h" + +#include +#include + +#ifdef __MACH__ +#include +#include +#include +#include +#include +#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; +} diff --git a/lib/libcompat.h b/lib/libcompat.h index 52b84e4..2afa389 100644 --- a/lib/libcompat.h +++ b/lib/libcompat.h @@ -102,6 +102,20 @@ const char *strsignal (int sig); 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);