summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/gethrxtime.c80
-rw-r--r--lib/gethrxtime.h37
-rw-r--r--lib/xtime.h87
-rw-r--r--m4/gethrxtime.m457
4 files changed, 261 insertions, 0 deletions
diff --git a/lib/gethrxtime.c b/lib/gethrxtime.c
new file mode 100644
index 000000000..6f7bc098c
--- /dev/null
+++ b/lib/gethrxtime.c
@@ -0,0 +1,80 @@
+/* gethrxtime -- get high resolution real time
+
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "gethrxtime.h"
+
+#include <sys/types.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+#endif
+
+/* Get the time of a high-resolution clock, preferably one that is not
+ subject to resetting or drifting. */
+
+xtime_t
+gethrxtime (void)
+{
+#if HAVE_NANOUPTIME
+ {
+ struct timespec ts;
+ nanouptime (&ts);
+ return xtime_make (ts.tv_sec, ts.tv_nsec);
+ }
+#else
+
+# if defined CLOCK_MONOTONIC && HAVE_CLOCK_GETTIME
+ {
+ struct timespec ts;
+ if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0)
+ return xtime_make (ts.tv_sec, ts.tv_nsec);
+ }
+# endif
+
+#if HAVE_MICROUPTIME
+ {
+ struct timeval tv;
+ microuptime (&tv);
+ return xtime_make (tv.tv_sec, 1000 * tv.tv_usec);
+ }
+
+ /* No monotonically increasing clocks are available; fall back on a
+ clock that might jump backwards, since it's the best we can do. */
+# elif HAVE_GETTIMEOFDAY && XTIME_PRECISION != 1
+ {
+ struct timeval tv;
+ gettimeofday (&tv, NULL);
+ return xtime_make (tv.tv_sec, 1000 * tv.tv_usec);
+ }
+# else
+ return xtime_make (time (NULL), 0);
+# endif
+#endif
+}
diff --git a/lib/gethrxtime.h b/lib/gethrxtime.h
new file mode 100644
index 000000000..2c0e36da7
--- /dev/null
+++ b/lib/gethrxtime.h
@@ -0,0 +1,37 @@
+/* gethrxtime -- get high resolution real time
+
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#ifndef GETHRXTIME_H_
+#define GETHRXTIME_H_ 1
+
+#include "xtime.h"
+
+/* Get the current time, as a count of the number of nanoseconds since
+ an arbitrary epoch (e.g., the system boot time). This clock can't
+ be set, is always increasing, and is nearly linear. */
+
+#if HAVE_ARITHMETIC_HRTIME_T && HAVE_DECL_GETHRTIME
+# include <time.h>
+static inline xtime_t gethrxtime (void) { return gethrtime (); }
+#else
+xtime_t gethrxtime (void);
+#endif
+
+#endif
diff --git a/lib/xtime.h b/lib/xtime.h
new file mode 100644
index 000000000..333f895b6
--- /dev/null
+++ b/lib/xtime.h
@@ -0,0 +1,87 @@
+/* xtime -- extended-resolution integer time stamps
+
+ Copyright (C) 2005 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+/* Written by Paul Eggert. */
+
+#ifndef XTIME_H_
+#define XTIME_H_ 1
+
+/* xtime_t is a signed type used for time stamps. It is an integer
+ type that is a count of nanoseconds -- except for obsolescent hosts
+ without sufficiently-wide integers, where it is a count of
+ seconds. */
+#if HAVE_LONG_LONG
+typedef long long int xtime_t;
+# define XTIME_PRECISION 1000000000LL
+#else
+# include <limits.h>
+typedef long int xtime_t;
+# if LONG_MAX >> 31 >> 31 == 0
+# define XTIME_PRECISION 1L
+# else
+# define XTIME_PRECISION 1000000000L
+# endif
+#endif
+
+/* Return an extended time value that contains S seconds and NS
+ nanoseconds, without any overflow checking. */
+static inline xtime_t
+xtime_make (xtime_t s, int ns)
+{
+ if (XTIME_PRECISION == 1)
+ return s;
+ else
+ return XTIME_PRECISION * s + ns;
+}
+
+/* Return the number of seconds in T, which must be nonnegative. */
+static inline xtime_t
+xtime_nonnegative_sec (xtime_t t)
+{
+ return t / XTIME_PRECISION;
+}
+
+/* Return the number of seconds in T. */
+static inline xtime_t
+xtime_sec (xtime_t t)
+{
+ return (XTIME_PRECISION == 1
+ ? t
+ : t < 0
+ ? (t + XTIME_PRECISION - 1) / XTIME_PRECISION - 1
+ : xtime_nonnegative_sec (t));
+}
+
+/* Return the number of nanoseconds in T, which must be nonnegative. */
+static inline int
+xtime_nonnegative_nsec (xtime_t t)
+{
+ return t % XTIME_PRECISION;
+}
+
+/* Return the number of nanoseconds in T. */
+static inline int
+xtime_nsec (xtime_t t)
+{
+ int ns = t % XTIME_PRECISION;
+ if (ns < 0)
+ ns += XTIME_PRECISION;
+ return ns;
+}
+
+#endif
diff --git a/m4/gethrxtime.m4 b/m4/gethrxtime.m4
new file mode 100644
index 000000000..89c6a21e7
--- /dev/null
+++ b/m4/gethrxtime.m4
@@ -0,0 +1,57 @@
+# gethrxtime.m4 serial 1
+dnl Copyright (C) 2005 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_GETHRXTIME],
+[
+ AC_LIBSOURCES([gethrxtime.c, gethrxtime.h, xtime.h])
+ AC_REQUIRE([gl_ARITHMETIC_HRTIME_T])
+ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+ AC_REQUIRE([gl_XTIME])
+ AC_CHECK_DECLS([gethrtime], [], [], [#include <time.h>])
+ case $ac_cv_have_decl_gethrtime,$gl_cv_arithmetic_hrtime_t in
+ yes,yes) ;;
+ *)
+ AC_LIBOBJ([gethrxtime])
+ gl_PREREQ_GETHRXTIME;;
+ esac
+])
+
+# Test whether hrtime_t is an arithmetic type.
+# It is not arithmetic in older Solaris c89 (which insists on
+# not having a long long int type).
+AC_DEFUN([gl_ARITHMETIC_HRTIME_T],
+[
+ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+ AC_CACHE_CHECK([for arithmetic hrtime_t], gl_cv_arithmetic_hrtime_t,
+ [AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM([#include <time.h>],
+ [hrtime_t x = 0; return x/x;])],
+ [gl_cv_arithmetic_hrtime_t=yes],
+ [gl_cv_arithmetic_hrtime_t=no])])
+ if test $gl_cv_arithmetic_hrtime_t = yes; then
+ AC_DEFINE([HAVE_ARITHMETIC_HRTIME_T], 1,
+ [Define if you have an arithmetic hrtime_t type.])
+ fi
+])
+
+# Prerequisites of lib/xtime.h.
+AC_DEFUN([gl_XTIME],
+[
+ AC_REQUIRE([AC_C_INLINE])
+ AC_REQUIRE([gl_AC_TYPE_LONG_LONG])
+ :
+])
+
+# Prerequisites of lib/gethrxtime.c.
+AC_DEFUN([gl_PREREQ_GETHRXTIME],
+[
+ dnl Do not AC_REQUIRE([gl_CLOCK_TIME]), since that would unnecessarily
+ dnl require -lrt on Solaris. Invocations of clock_gettime should be
+ dnl safe in gethrxtime.c since Solaris has native gethrtime.
+ AC_REQUIRE([AC_HEADER_TIME])
+ AC_CHECK_FUNCS_ONCE(gettimeofday microuptime nanouptime)
+ :
+])