]> granicus.if.org Git - check/commitdiff
Add override for clock_gettime() in libcompat for systems that do not supply it
authorbrarcher <brarcher@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Sun, 4 Nov 2012 03:18:59 +0000 (03:18 +0000)
committerbrarcher <brarcher@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Sun, 4 Nov 2012 03:18:59 +0000 (03:18 +0000)
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

configure.ac
lib/clock_gettime.c [new file with mode: 0644]
lib/libcompat.h

index f78bc333dba84662e97ca7e18e8a92f030639f70..f280894dc9465366c901c14de7b07c96b076f57d 100644 (file)
@@ -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 (file)
index 0000000..9d26ce5
--- /dev/null
@@ -0,0 +1,68 @@
+#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;
+}
index 52b84e4cac7f147a1792c349c391b46f1f5aa1c3..2afa389eb25aa651ad0478f089427cd841987f0f 100644 (file)
@@ -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);