[PATCH] use monotonic timer for timeout in pthread instead of system clock

Keith Mok ek9852 at gmail.com
Wed Oct 15 03:45:42 PDT 2008


Hi all,

Patch for using monotonic timer for pthread timeout instead of system 
clock.
To avoid the problem when system date/time is changed.

Keith

---
configure.in                |    2 ++
dbus/dbus-sysdeps-pthread.c |   33 ++++++++++++++++++++++++++++++++-
2 files changed, 34 insertions(+), 1 deletions(-)

diff --git a/configure.in b/configure.in
index 291e494..74f1a99 100644
--- a/configure.in
+++ b/configure.in
@@ -889,6 +889,8 @@ fi
# Thread lib detection
AC_CHECK_FUNC(pthread_cond_timedwait,,[AC_CHECK_LIB(pthread,pthread_cond_timedwait, 

                                                    
[THREAD_LIBS="-lpthread"])])
+AC_CHECK_FUNC(pthread_condattr_setclock,,[AC_CHECK_LIB(pthread,pthread_condattr_setclock, 

+                                                    
[THREAD_LIBS="-lpthread"])])

# SELinux detection
if test x$enable_selinux = xno ; then
diff --git a/dbus/dbus-sysdeps-pthread.c b/dbus/dbus-sysdeps-pthread.c
index 121ee12..b1f8e64 100644
--- a/dbus/dbus-sysdeps-pthread.c
+++ b/dbus/dbus-sysdeps-pthread.c
@@ -25,6 +25,8 @@
#include "dbus-sysdeps.h"
#include "dbus-threads.h"

+#include <unistd.h>
+#include <sys/syscall.h>
#include <sys/time.h>
#include <pthread.h>
#include <string.h>
@@ -67,6 +69,8 @@ typedef struct {
} while (0)
#endif /* !DBUS_DISABLE_ASSERT */

+static int no_monotonic_timer;
+
static DBusMutex*
_dbus_pthread_mutex_new (void)
{
@@ -184,13 +188,30 @@ static DBusCondVar *
_dbus_pthread_condvar_new (void)
{
  DBusCondVarPThread *pcond;
+  pthread_condattr_t attr;
+  struct timespec dummy;
  int result;
    pcond = dbus_new (DBusCondVarPThread, 1);
  if (pcond == NULL)
    return NULL;

-  result = pthread_cond_init (&pcond->cond, NULL);
+  pthread_condattr_init( &attr );
+
+#ifdef CLOCK_MONOTONIC
+  if((syscall(__NR_clock_getres, CLOCK_MONOTONIC, &dummy) == 0) &&
+      (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0))
+    {
+      no_monotonic_timer = 0;
+    }
+  else
+    {
+      no_monotonic_timer = 1;
+    }
+#endif
+
+  result = pthread_cond_init (&pcond->cond, &attr);
+  pthread_condattr_destroy( &attr );

  if (result == EAGAIN || result == ENOMEM)
    {
@@ -243,12 +264,22 @@ _dbus_pthread_condvar_wait_timeout 
(DBusCondVar               *cond,
  DBusCondVarPThread *pcond = DBUS_COND_VAR_PTHREAD (cond);
  struct timeval time_now;
  struct timespec end_time;
+  struct timespec monotonic_timer;
  int result;
  int old_count;
    _dbus_assert (pmutex->count > 0);
  _dbus_assert (pthread_equal (pmutex->holder, pthread_self ()));    
+#ifdef CLOCK_MONOTONIC
+  if(!no_monotonic_timer)
+    {
+      syscall(__NR_clock_gettime, CLOCK_MONOTONIC, &monotonic_timer);
+      time_now.tv_sec = monotonic_timer.tv_sec;
+      time_now.tv_usec = monotonic_timer.tv_nsec / 1000;
+    }
+  else
+#endif
  gettimeofday (&time_now, NULL);
    end_time.tv_sec = time_now.tv_sec + timeout_milliseconds / 1000;
-- 
1.5.4.3



More information about the dbus mailing list