From 9c1b05828a88eff54409760b92162c7cc2c7cff6 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Tue, 19 Apr 2011 09:20:44 +0300 Subject: [PATCH] Fix portability problems in mythread.h. Use gettimeofday() if clock_gettime() isn't available (e.g. Darwin). The test for availability of pthread_condattr_setclock() and CLOCK_MONOTONIC was incorrect. Instead of fixing the #ifdefs, use an Autoconf test. That way if there exists a system that supports them but doesn't specify the matching POSIX #defines, the features will still get detected. Don't try to use pthread_sigmask() on OpenVMS. It doesn't have that function. Guard mythread.h against being #included multiple times. --- configure.ac | 7 +++++++ src/common/mythread.h | 31 +++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 8cba630c..73dc358c 100644 --- a/configure.ac +++ b/configure.ac @@ -435,7 +435,14 @@ if test "x$enable_threads" = xyes; then LIBS="$LIBS $PTHREAD_LIBS" AM_CFLAGS="$AM_CFLAGS $PTHREAD_CFLAGS" CC="$PTHREAD_CC" + + # These are nice to have but not mandatory. + OLD_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" AC_SEARCH_LIBS([clock_gettime], [rt]) + AC_CHECK_FUNCS([clock_gettime pthread_condattr_setclock]) + AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include ]]) + CFLAGS=$OLD_CFLAGS fi AM_CONDITIONAL([COND_THREADS], [test "x$ax_pthread_ok" = xyes]) diff --git a/src/common/mythread.h b/src/common/mythread.h index 39641408..47af4932 100644 --- a/src/common/mythread.h +++ b/src/common/mythread.h @@ -10,6 +10,9 @@ // /////////////////////////////////////////////////////////////////////////////// +#ifndef MYTHREAD_H +#define MYTHREAD_H + #include "sysdefs.h" @@ -19,19 +22,23 @@ // Using pthreads // //////////////////// +#include #include #include #include -#include +#ifdef __VMS +// Do nothing on OpenVMS. It doesn't have pthread_sigmask(). +#define mythread_sigmask(how, set, oset) do { } while (0) +#else /// \brief Set the process signal mask /// /// If threads are disabled, sigprocmask() is used instead /// of pthread_sigmask(). #define mythread_sigmask(how, set, oset) \ pthread_sigmask(how, set, oset) - +#endif /// \brief Call the given function once /// @@ -96,7 +103,9 @@ typedef struct { static inline int mythread_cond_init(mythread_cond *mycond) { -#if defined(_POSIX_CLOCK_SELECTION) && defined(_POSIX_MONOTONIC_CLOCK) +#ifdef HAVE_CLOCK_GETTIME + // NOTE: HAVE_DECL_CLOCK_MONOTONIC is always defined to 0 or 1. +# if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && HAVE_DECL_CLOCK_MONOTONIC struct timespec ts; pthread_condattr_t condattr; @@ -119,9 +128,11 @@ mythread_cond_init(mythread_cond *mycond) } // If anything above fails, fall back to the default CLOCK_REALTIME. -#endif +# endif mycond->clk_id = CLOCK_REALTIME; +#endif + return pthread_cond_init(&mycond->cond, NULL); } @@ -133,11 +144,21 @@ mythread_cond_init(mythread_cond *mycond) static inline void mythread_cond_abstime(const mythread_cond *mycond, struct timespec *ts) { +#ifdef HAVE_CLOCK_GETTIME struct timespec now; clock_gettime(mycond->clk_id, &now); ts->tv_sec += now.tv_sec; ts->tv_nsec += now.tv_nsec; +#else + (void)mycond; + + struct timeval now; + gettimeofday(&now, NULL); + + ts->tv_sec += now.tv_sec; + ts->tv_nsec += now.tv_usec * 1000L; +#endif // tv_nsec must stay in the range [0, 999_999_999]. if (ts->tv_nsec >= 1000000000L) { @@ -200,3 +221,5 @@ do { \ } while (0) #endif + +#endif