Browse Source

Use clock_gettime(CLOCK_MONOTONIC) for timers when available

Luke Dashjr 12 years ago
parent
commit
5e8a11062b
2 changed files with 68 additions and 0 deletions
  1. 29 0
      configure.ac
  2. 39 0
      util.c

+ 29 - 0
configure.ac

@@ -844,6 +844,35 @@ AC_TRY_COMPILE([
 ])
 ])
 
 
 
 
+AC_MSG_CHECKING([for clock_gettime(CLOCK_MONOTONIC)])
+AC_TRY_COMPILE([
+	#define _GNU_SOURCE
+	#include <time.h>
+],[
+	struct timespec ts;
+	clock_gettime(CLOCK_MONOTONIC, &ts);
+],[
+	AC_MSG_RESULT([yes])
+	AC_DEFINE([HAVE_CLOCK_GETTIME_MONOTONIC], [1], [Defined to 1 if clock_gettime(CLOCK_MONOTONIC) is defined])
+	AC_SEARCH_LIBS([clock_gettime],[rt posix4])
+	AC_MSG_CHECKING([for clock_gettime(CLOCK_MONOTONIC_RAW)])
+	AC_TRY_COMPILE([
+		#define _GNU_SOURCE
+		#include <time.h>
+	],[
+		struct timespec ts;
+		clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+	],[
+		AC_MSG_RESULT([yes])
+		AC_DEFINE([HAVE_CLOCK_GETTIME_MONOTONIC_RAW], [1], [Defined to 1 if clock_gettime(CLOCK_MONOTONIC_RAW) is defined])
+	],[
+		AC_MSG_RESULT([no])
+	])
+],[
+	AC_MSG_RESULT([no])
+])
+
+
 if test "x$prefix" = xNONE; then
 if test "x$prefix" = xNONE; then
 	prefix=/usr/local
 	prefix=/usr/local
 fi
 fi

+ 39 - 0
util.c

@@ -1137,11 +1137,50 @@ void _now_is_not_set(__maybe_unused struct timeval *tv)
 
 
 void (*timer_set_now)(struct timeval *tv) = _now_is_not_set;
 void (*timer_set_now)(struct timeval *tv) = _now_is_not_set;
 
 
+#ifdef HAVE_CLOCK_GETTIME_MONOTONIC
+static clockid_t bfg_timer_clk;
+
+static
+void _now_clock_gettime(struct timeval *tv)
+{
+	struct timespec ts;
+	if (unlikely(clock_gettime(bfg_timer_clk, &ts)))
+		quit(1, "clock_gettime failed");
+	
+	*tv = (struct timeval){
+		.tv_sec = ts.tv_sec,
+		.tv_usec = ts.tv_nsec / 1000,
+	};
+}
+
+static
+bool _bfg_try_clock_gettime(clockid_t clk)
+{
+	struct timespec ts;
+	if (clock_gettime(clk, &ts))
+		return false;
+	
+	bfg_timer_clk = clk;
+	timer_set_now = _now_clock_gettime;
+	return true;
+}
+#endif
+
 void bfg_init_time()
 void bfg_init_time()
 {
 {
 	if (timer_set_now != _now_is_not_set)
 	if (timer_set_now != _now_is_not_set)
 		return;
 		return;
 	
 	
+#ifdef HAVE_CLOCK_GETTIME_MONOTONIC
+#ifdef HAVE_CLOCK_GETTIME_MONOTONIC_RAW
+	if (_bfg_try_clock_gettime(CLOCK_MONOTONIC_RAW))
+		applog(LOG_DEBUG, "Timers: Using clock_gettime(CLOCK_MONOTONIC_RAW)");
+	else
+#endif
+	if (_bfg_try_clock_gettime(CLOCK_MONOTONIC))
+		applog(LOG_DEBUG, "Timers: Using clock_gettime(CLOCK_MONOTONIC)");
+	else
+#endif
 #ifdef WIN32
 #ifdef WIN32
 	if (QueryPerformanceFrequency(&_perffreq) && _perffreq.QuadPart)
 	if (QueryPerformanceFrequency(&_perffreq) && _perffreq.QuadPart)
 	{
 	{