Signed-off-by: Yury Kotov <yury-ko...@yandex-team.ru> --- include/qemu/thread.h | 12 ++++++++++++ util/qemu-thread-posix.c | 40 ++++++++++++++++++++++++++++------------ util/qemu-thread-win32.c | 16 ++++++++++++++++ 3 files changed, 56 insertions(+), 12 deletions(-)
diff --git a/include/qemu/thread.h b/include/qemu/thread.h index 55d83a907c..80898c5db4 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -140,6 +140,18 @@ static inline void (qemu_cond_wait)(QemuCond *cond, QemuMutex *mutex) qemu_cond_wait(cond, mutex); } +void qemu_cond_timedwait_impl(QemuCond *cond, QemuMutex *mutex, int ms, + const char *file, const int line); + +#define qemu_cond_timedwait(cond, mutex, ms) \ + qemu_cond_timedwait_impl(cond, mutex, ms, __FILE__, __LINE__) + +static inline void (qemu_cond_timedwait)(QemuCond *cond, QemuMutex *mutex, + int ms) +{ + qemu_cond_timedwait(cond, mutex, ms); +} + void qemu_sem_init(QemuSemaphore *sem, int init); void qemu_sem_post(QemuSemaphore *sem); void qemu_sem_wait(QemuSemaphore *sem); diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 1bf5e65dea..eed777d9ec 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -36,6 +36,18 @@ static void error_exit(int err, const char *msg) abort(); } +static void compute_abs_deadline(struct timespec *ts, int ms) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + ts->tv_nsec = tv.tv_usec * 1000 + (ms % 1000) * 1000000; + ts->tv_sec = tv.tv_sec + ms / 1000; + if (ts->tv_nsec >= 1000000000) { + ts->tv_sec++; + ts->tv_nsec -= 1000000000; + } +} + void qemu_mutex_init(QemuMutex *mutex) { int err; @@ -164,6 +176,22 @@ void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, con error_exit(err, __func__); } +void qemu_cond_timedwait_impl(QemuCond *cond, QemuMutex *mutex, int ms, + const char *file, const int line) +{ + int err; + struct timespec ts; + + assert(cond->initialized); + trace_qemu_mutex_unlock(mutex, file, line); + compute_abs_deadline(&ts, ms); + err = pthread_cond_timedwait(&cond->cond, &mutex->lock, &ts); + trace_qemu_mutex_locked(mutex, file, line); + if (err && err != ETIMEDOUT) { + error_exit(err, __func__); + } +} + void qemu_sem_init(QemuSemaphore *sem, int init) { int rc; @@ -238,18 +266,6 @@ void qemu_sem_post(QemuSemaphore *sem) #endif } -static void compute_abs_deadline(struct timespec *ts, int ms) -{ - struct timeval tv; - gettimeofday(&tv, NULL); - ts->tv_nsec = tv.tv_usec * 1000 + (ms % 1000) * 1000000; - ts->tv_sec = tv.tv_sec + ms / 1000; - if (ts->tv_nsec >= 1000000000) { - ts->tv_sec++; - ts->tv_nsec -= 1000000000; - } -} - int qemu_sem_timedwait(QemuSemaphore *sem, int ms) { int rc; diff --git a/util/qemu-thread-win32.c b/util/qemu-thread-win32.c index 572f88535d..5faa01cb61 100644 --- a/util/qemu-thread-win32.c +++ b/util/qemu-thread-win32.c @@ -145,6 +145,22 @@ void qemu_cond_wait_impl(QemuCond *cond, QemuMutex *mutex, const char *file, con qemu_mutex_post_lock(mutex, file, line); } +void qemu_cond_timedwait_impl(QemuCond *cond, QemuMutex *mutex, int ms, + const char *file, const int line) +{ + int rc = 0; + + assert(cond->initialized); + trace_qemu_mutex_unlock(mutex, file, line); + if (!SleepConditionVariableSRW(&cond->var, &mutex->lock, ms, 0)) { + rc = GetLastError(); + } + trace_qemu_mutex_locked(mutex, file, line); + if (rc && rc != ERROR_TIMEOUT) { + error_exit(rc, __func__); + } +} + void qemu_sem_init(QemuSemaphore *sem, int init) { /* Manual reset. */ -- 2.22.0