X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=util%2Fqemu-thread-posix.c;h=ce51b37c1de5ab7c782ca2cc19f88c2c35bf9392;hb=6d3f4049ba532b01ff738f9e5a66df1477c5ffdd;hp=50a29d8f7aad7fe5882ba33d18dce4b7bf2ccb97;hpb=158ef8cbb7e0fe8bb430310924b8bebe5f186e6e;p=mirror_qemu.git diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c index 50a29d8f7a..ce51b37c1d 100644 --- a/util/qemu-thread-posix.c +++ b/util/qemu-thread-posix.c @@ -10,16 +10,7 @@ * See the COPYING file in the top-level directory. * */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "qemu/osdep.h" #ifdef __linux__ #include #include @@ -51,12 +42,8 @@ static void error_exit(int err, const char *msg) void qemu_mutex_init(QemuMutex *mutex) { int err; - pthread_mutexattr_t mutexattr; - pthread_mutexattr_init(&mutexattr); - pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_ERRORCHECK); - err = pthread_mutex_init(&mutex->lock, &mutexattr); - pthread_mutexattr_destroy(&mutexattr); + err = pthread_mutex_init(&mutex->lock, NULL); if (err) error_exit(err, __func__); } @@ -302,7 +289,16 @@ static inline void futex_wake(QemuEvent *ev, int n) static inline void futex_wait(QemuEvent *ev, unsigned val) { - futex(ev, FUTEX_WAIT, (int) val, NULL, NULL, 0); + while (futex(ev, FUTEX_WAIT, (int) val, NULL, NULL, 0)) { + switch (errno) { + case EWOULDBLOCK: + return; + case EINTR: + break; /* get out of switch and retry */ + default: + abort(); + } + } } #else static inline void futex_wake(QemuEvent *ev, int n) @@ -364,7 +360,11 @@ void qemu_event_destroy(QemuEvent *ev) void qemu_event_set(QemuEvent *ev) { - if (atomic_mb_read(&ev->value) != EV_SET) { + /* qemu_event_set has release semantics, but because it *loads* + * ev->value we need a full memory barrier here. + */ + smp_mb(); + if (atomic_read(&ev->value) != EV_SET) { if (atomic_xchg(&ev->value, EV_SET) == EV_BUSY) { /* There were waiters, wake them up. */ futex_wake(ev, INT_MAX); @@ -374,7 +374,11 @@ void qemu_event_set(QemuEvent *ev) void qemu_event_reset(QemuEvent *ev) { - if (atomic_mb_read(&ev->value) == EV_SET) { + unsigned value; + + value = atomic_read(&ev->value); + smp_mb_acquire(); + if (value == EV_SET) { /* * If there was a concurrent reset (or even reset+wait), * do nothing. Otherwise change EV_SET->EV_FREE. @@ -387,13 +391,14 @@ void qemu_event_wait(QemuEvent *ev) { unsigned value; - value = atomic_mb_read(&ev->value); + value = atomic_read(&ev->value); + smp_mb_acquire(); if (value != EV_SET) { if (value == EV_FREE) { /* * Leave the event reset and tell qemu_event_set that there * are waiters. No need to retry, because there cannot be - * a concurent busy->free transition. After the CAS, the + * a concurrent busy->free transition. After the CAS, the * event will be either set or busy. */ if (atomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) {