Comments
Patch
@@ -2135,6 +2135,23 @@ if test "$mingw32" != yes -a "$pthread" = no; then
fi
##########################################
+# pthread_condattr_setclock probe
+condattr_setclock="no"
+if test "pthread" != "no" ; then
+ cat > $TMPC << EOF
+#include <pthread.h>
+int main(void) {
+ pthread_condattr_t attr;
+ pthread_condattr_init(&attr);
+ return pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+}
+EOF
+ if compile_prog "" "$LIBS" && $TMPE; then
+ condattr_setclock="yes"
+ fi
+fi
+
+##########################################
# rbd probe
if test "$rbd" != "no" ; then
cat > $TMPC <<EOF
@@ -3040,6 +3057,7 @@ echo "preadv support $preadv"
echo "fdatasync $fdatasync"
echo "madvise $madvise"
echo "posix_madvise $posix_madvise"
+echo "condattr_setclock $condattr_setclock"
echo "uuid support $uuid"
echo "libcap-ng support $cap_ng"
echo "vhost-net support $vhost_net"
@@ -3324,6 +3342,9 @@ fi
if test "$posix_madvise" = "yes" ; then
echo "CONFIG_POSIX_MADVISE=y" >> $config_host_mak
fi
+if test "$condattr_setclock" = "yes" ; then
+ echo "CONFIG_CONDATTR_SETCLOCK=y" >> $config_host_mak
+fi
if test "$spice" = "yes" ; then
echo "CONFIG_SPICE=y" >> $config_host_mak
@@ -17,6 +17,8 @@
#include <signal.h>
#include <stdint.h>
#include <string.h>
+#include <sys/time.h>
+#include "config-host.h"
#include "qemu-thread.h"
static void error_exit(int err, const char *msg)
@@ -73,8 +75,20 @@ void qemu_mutex_unlock(QemuMutex *mutex)
void qemu_cond_init(QemuCond *cond)
{
int err;
+ pthread_condattr_t attr;
- err = pthread_cond_init(&cond->cond, NULL);
+ err = pthread_condattr_init(&attr);
+ if (err) {
+ error_exit(err, __func__);
+ }
+#ifdef CONFIG_CONDATTR_SETCLOCK
+ err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+ if (err) {
+ error_exit(err, __func__);
+ }
+#endif
+
+ err = pthread_cond_init(&cond->cond, &attr);
if (err)
error_exit(err, __func__);
}
@@ -115,6 +129,36 @@ void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
error_exit(err, __func__);
}
+/* Returns true if condition was signals, false if timed out. */
+bool qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex,
+ unsigned int timeout_ms)
+{
+ struct timespec ts;
+ int err;
+
+#ifdef CONFIG_CONDATTR_SETCLOCK
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+#else
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = tv.tv_usec * 1000;
+#endif
+
+ ts.tv_sec += timeout_ms / 1000;
+ ts.tv_nsec += (timeout_ms % 1000) * 1000000;
+ if (ts.tv_nsec > 1000000000) {
+ ts.tv_sec++;
+ ts.tv_nsec -= 1000000000;
+ }
+ err = pthread_cond_timedwait(&cond->cond, &mutex->lock, &ts);
+ if (err && err != ETIMEDOUT) {
+ error_exit(err, __func__);
+ }
+ return err == 0;
+}
+
void qemu_thread_create(QemuThread *thread,
void *(*start_routine)(void*),
void *arg, int mode)
@@ -1,5 +1,6 @@
#ifndef __QEMU_THREAD_POSIX_H
#define __QEMU_THREAD_POSIX_H 1
+#include <stdbool.h>
#include "pthread.h"
struct QemuMutex {
@@ -14,4 +15,8 @@ struct QemuThread {
pthread_t thread;
};
+/* only provided for posix so far */
+bool qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex,
+ unsigned int timeout_ms);
+
#endif
First user will be POSIX compat aio. Windows use cases aren't in sight, so this remains a POSIX-only service for now. This version uses CLOCK_MONOTONIC for the timeout to avoid jumps on wall clock adjustments, provided the host support pthread_condattr_setclock. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> --- configure | 21 +++++++++++++++++++++ qemu-thread-posix.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- qemu-thread-posix.h | 5 +++++ 3 files changed, 71 insertions(+), 1 deletions(-)