diff options
Diffstat (limited to 'src/libstrongswan')
-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 |
3 files changed, 30 insertions, 18 deletions
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. |