diff options
author | Martin Willi <martin@strongswan.org> | 2009-08-31 15:13:48 +0200 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2009-08-31 15:13:48 +0200 |
commit | 3d5818ec38c464b24f382d88c70b10df6c04b160 (patch) | |
tree | 58b41fa9794a8677757d642c10bc33e50bb9c438 | |
parent | 3f310c0d1f664f5811327c5a89b5d6c2f3e42bdc (diff) | |
download | strongswan-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.in | 14 | ||||
-rw-r--r-- | src/charon/processing/scheduler.c | 6 | ||||
-rw-r--r-- | src/charon/processing/scheduler.h | 3 | ||||
-rw-r--r-- | src/libstrongswan/utils.c | 9 | ||||
-rw-r--r-- | src/libstrongswan/utils/mutex.c | 22 | ||||
-rw-r--r-- | src/libstrongswan/utils/mutex.h | 17 |
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. |