From: Yasushi SHOJI Date: Thu, 28 Dec 2017 01:53:47 +0000 (+0900) Subject: mutex: down_timeout: check against the base time X-Git-Tag: fio-3.4~34^2 X-Git-Url: https://git.kernel.dk/?p=fio.git;a=commitdiff_plain;h=7e92a66a681f8da4879a0006ee64e5ea35b6a749 mutex: down_timeout: check against the base time When the commit 8b6a404cdd2c40715885e562416c3db039912773 changed timeval to timespec, it accsidentally picked timeout time `t' instead of the current `base' time for checking timewait() really timed out. t is base + msecs as follows: base = gettimeofday() t = base + msecs pthread_cond_timedwait() while (!done) if (timedout) if (mutex_timed_out(t, msecs)) done = true Thus, after a good timedout, it burns the cpu for the given msecs seconds doing tight loop in the while shown above. This causes 30 to 40 % CPU load on my i5-3360M 2.80GHz while fio server is running. --- diff --git a/mutex.c b/mutex.c index 9fab715b..63229eda 100644 --- a/mutex.c +++ b/mutex.c @@ -156,14 +156,15 @@ static bool mutex_timed_out(struct timespec *t, unsigned int msecs) int fio_mutex_down_timeout(struct fio_mutex *mutex, unsigned int msecs) { struct timeval tv_s; + struct timespec base; struct timespec t; int ret = 0; assert(mutex->magic == FIO_MUTEX_MAGIC); gettimeofday(&tv_s, NULL); - t.tv_sec = tv_s.tv_sec; - t.tv_nsec = tv_s.tv_usec * 1000; + base.tv_sec = t.tv_sec = tv_s.tv_sec; + base.tv_nsec = t.tv_nsec = tv_s.tv_usec * 1000; t.tv_sec += msecs / 1000; t.tv_nsec += ((msecs * 1000000ULL) % 1000000000); @@ -181,7 +182,7 @@ int fio_mutex_down_timeout(struct fio_mutex *mutex, unsigned int msecs) * way too early, double check. */ ret = pthread_cond_timedwait(&mutex->cond, &mutex->lock, &t); - if (ret == ETIMEDOUT && !mutex_timed_out(&t, msecs)) + if (ret == ETIMEDOUT && !mutex_timed_out(&base, msecs)) ret = 0; } mutex->waiters--;