[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