aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Willi <martin@strongswan.org>2009-08-31 15:13:48 +0200
committerMartin Willi <martin@strongswan.org>2009-08-31 15:13:48 +0200
commit3d5818ec38c464b24f382d88c70b10df6c04b160 (patch)
tree58b41fa9794a8677757d642c10bc33e50bb9c438
parent3f310c0d1f664f5811327c5a89b5d6c2f3e42bdc (diff)
downloadstrongswan-3d5818ec38c464b24f382d88c70b10df6c04b160.tar.bz2
strongswan-3d5818ec38c464b24f382d88c70b10df6c04b160.tar.xz
use monotonic time source in convar->timed_wait, and in the scheduler using it
-rw-r--r--configure.in14
-rw-r--r--src/charon/processing/scheduler.c6
-rw-r--r--src/charon/processing/scheduler.h3
-rw-r--r--src/libstrongswan/utils.c9
-rw-r--r--src/libstrongswan/utils/mutex.c22
-rw-r--r--src/libstrongswan/utils/mutex.h17
6 files changed, 50 insertions, 21 deletions
diff --git a/configure.in b/configure.in
index 7caa8c1b3..903d74229 100644
--- a/configure.in
+++ b/configure.in
@@ -927,6 +927,20 @@ AC_TRY_COMPILE(
[AC_MSG_RESULT([no])]
)
+dnl check if pthread_condattr_setclock(CLOCK_MONOTONE) is supported
+saved_LIBS=$LIBS
+LIBS="-lpthread"
+AC_MSG_CHECKING([for pthread_condattr_setclock(CLOCK_MONOTONE)])
+AC_TRY_RUN(
+ [#include <pthread.h>
+ int main() { pthread_condattr_t attr;
+ pthread_condattr_init(&attr);
+ return pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);}],
+ [AC_MSG_RESULT([yes]); AC_DEFINE([HAVE_CONDATTR_CLOCK_MONOTONIC])],
+ [AC_MSG_RESULT([no])]
+)
+LIBS=$saved_LIBS
+
AC_CHECK_FUNCS(prctl)
AC_CHECK_HEADERS(sys/sockio.h)
diff --git a/src/charon/processing/scheduler.c b/src/charon/processing/scheduler.c
index 1f59205af..f53ccb99a 100644
--- a/src/charon/processing/scheduler.c
+++ b/src/charon/processing/scheduler.c
@@ -190,7 +190,7 @@ static job_requeue_t schedule(private_scheduler_t * this)
this->mutex->lock(this->mutex);
- gettimeofday(&now, NULL);
+ time_monotonic(&now);
if ((event = peek_event(this)) != NULL)
{
@@ -290,7 +290,7 @@ static void schedule_job(private_scheduler_t *this, job_t *job, u_int32_t s)
{
timeval_t tv;
- gettimeofday(&tv, NULL);
+ time_monotonic(&tv);
tv.tv_sec += s;
schedule_job_tv(this, job, tv);
@@ -303,7 +303,7 @@ static void schedule_job_ms(private_scheduler_t *this, job_t *job, u_int32_t ms)
{
timeval_t tv, add;
- gettimeofday(&tv, NULL);
+ time_monotonic(&tv);
add.tv_sec = ms / 1000;
add.tv_usec = (ms % 1000) * 1000;
diff --git a/src/charon/processing/scheduler.h b/src/charon/processing/scheduler.h
index 502f70b33..927b561bb 100644
--- a/src/charon/processing/scheduler.h
+++ b/src/charon/processing/scheduler.h
@@ -101,6 +101,9 @@ struct scheduler_t {
/**
* Adds a event to the queue, using an absolut time.
*
+ * The passed timeval should be calculated based on the time_monotonic()
+ * function.
+ *
* @param job job to schedule
* @param time absolut time to schedule job
*/
diff --git a/src/libstrongswan/utils.c b/src/libstrongswan/utils.c
index 91242da2e..2d5ff3d79 100644
--- a/src/libstrongswan/utils.c
+++ b/src/libstrongswan/utils.c
@@ -167,7 +167,9 @@ bool mkdir_p(const char *path, mode_t mode)
*/
time_t time_monotonic(timeval_t *tv)
{
-#if defined(HAVE_CLOCK_GETTIME)
+#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_CONDATTR_CLOCK_MONOTONIC)
+ /* as we use time_monotonic() for condvar operations, we use the
+ * monotonic time source only if it is also supported by pthread. */
timespec_t ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
@@ -179,11 +181,12 @@ time_t time_monotonic(timeval_t *tv)
}
return ts.tv_sec;
}
-#endif /* HAVE_CLOCK_MONOTONIC */
+#endif /* HAVE_CLOCK_MONOTONIC && HAVE_CONDATTR_CLOCK_MONOTONIC */
/* Fallback to non-monotonic timestamps:
* On MAC OS X, creating monotonic timestamps is rather difficult. We
* could use mach_absolute_time() and catch sleep/wakeup notifications.
- * We stick to the simpler (non-monotonic) gettimeofday() for now. */
+ * We stick to the simpler (non-monotonic) gettimeofday() for now.
+ * But keep in mind: we need the same time source here as in condvar! */
if (!tv)
{
return time(NULL);
diff --git a/src/libstrongswan/utils/mutex.c b/src/libstrongswan/utils/mutex.c
index a6c39e94c..fef25706d 100644
--- a/src/libstrongswan/utils/mutex.c
+++ b/src/libstrongswan/utils/mutex.c
@@ -47,7 +47,7 @@ struct lock_profile_t {
/**
* how long threads have waited for the lock in this mutex so far
*/
- struct timeval waited;
+ timeval_t waited;
/**
* backtrace where mutex has been created
@@ -81,10 +81,10 @@ static void profiler_init(lock_profile_t *profile)
#define profiler_start(profile) { \
struct timeval _start, _end, _diff; \
- gettimeofday(&_start, NULL);
+ time_monotonic(&_start);
#define profiler_end(profile) \
- gettimeofday(&_end, NULL); \
+ time_monotonic(&_end); \
timersub(&_end, &_start, &_diff); \
timeradd(&(profile)->waited, &_diff, &(profile)->waited); }
@@ -368,7 +368,7 @@ static bool timed_wait(private_condvar_t *this, private_mutex_t *mutex,
timeval_t tv;
u_int s, ms;
- gettimeofday(&tv, NULL);
+ time_monotonic(&tv);
s = timeout / 1000;
ms = timeout % 1000;
@@ -419,17 +419,23 @@ condvar_t *condvar_create(condvar_type_t type)
case CONDVAR_TYPE_DEFAULT:
default:
{
+ pthread_condattr_t condattr;
private_condvar_t *this = malloc_thing(private_condvar_t);
-
+
this->public.wait = (void(*)(condvar_t*, mutex_t *mutex))_wait;
this->public.timed_wait = (bool(*)(condvar_t*, mutex_t *mutex, u_int timeout))timed_wait;
this->public.timed_wait_abs = (bool(*)(condvar_t*, mutex_t *mutex, timeval_t time))timed_wait_abs;
this->public.signal = (void(*)(condvar_t*))_signal;
this->public.broadcast = (void(*)(condvar_t*))broadcast;
this->public.destroy = (void(*)(condvar_t*))condvar_destroy;
-
- pthread_cond_init(&this->condvar, NULL);
-
+
+ pthread_condattr_init(&condattr);
+#ifdef HAVE_CONDATTR_CLOCK_MONOTONIC
+ pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
+#endif
+ pthread_cond_init(&this->condvar, &condattr);
+ pthread_condattr_destroy(&condattr);
+
return &this->public;
}
}
diff --git a/src/libstrongswan/utils/mutex.h b/src/libstrongswan/utils/mutex.h
index 273f56b47..39763f901 100644
--- a/src/libstrongswan/utils/mutex.h
+++ b/src/libstrongswan/utils/mutex.h
@@ -98,11 +98,11 @@ struct mutex_t {
* Release the lock on the mutex.
*/
void (*unlock)(mutex_t *this);
-
+
/**
- * Destroy a mutex instance.
- */
- void (*destroy)(mutex_t *this);
+ * Destroy a mutex instance.
+ */
+ void (*destroy)(mutex_t *this);
};
/**
@@ -128,12 +128,15 @@ struct condvar_t {
/**
* Wait on a condvar until it gets signalized, or times out.
- *
+ *
+ * The passed timeval should be calculated based on the time_monotonic()
+ * function.
+ *
* @param mutex mutex to release while waiting
- * @param time absolute time until timeout
+ * @param tv absolute time until timeout
* @return TRUE if timed out, FALSE otherwise
*/
- bool (*timed_wait_abs)(condvar_t *this, mutex_t *mutex, timeval_t timeout);
+ bool (*timed_wait_abs)(condvar_t *this, mutex_t *mutex, timeval_t tv);
/**
* Wake up a single thread in a condvar.