From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50914) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UuIL2-0006n2-Sl for qemu-devel@nongnu.org; Wed, 03 Jul 2013 04:23:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UuIKx-0007Pf-Ky for qemu-devel@nongnu.org; Wed, 03 Jul 2013 04:22:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:44932) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UuIKx-0007PY-D0 for qemu-devel@nongnu.org; Wed, 03 Jul 2013 04:22:51 -0400 Message-ID: <51D3DFE8.7080202@redhat.com> Date: Wed, 03 Jul 2013 10:25:12 +0200 From: Laszlo Ersek MIME-Version: 1.0 References: <1372784047-12468-1-git-send-email-tsutsui@ceres.dti.ne.jp> In-Reply-To: <1372784047-12468-1-git-send-email-tsutsui@ceres.dti.ne.jp> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH v2] semaphore: fix a hangup problem under load on NetBSD hosts. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Izumi Tsutsui Cc: qemu-devel@nongnu.org On 07/02/13 18:54, Izumi Tsutsui wrote: > Fix following bugs in "fallback implementation of counting semaphores > with mutex+condvar" added in c166cb72f1676855816340666c3b618beef4b976: > - waiting threads are not restarted properly if more than one threads > are waiting unblock signals in qemu_sem_timedwait() > - possible missing pthread_cond_signal(3) calls when waiting threads > are returned by ETIMEDOUT > - fix an uninitialized variable > The problem is analyzed by and fix is provided by Noriyuki Soda. > > Also put additional cleanup suggested by Laszlo Ersek: > - make QemuSemaphore.count unsigned (it won't be negative) > - check a return value of in pthread_cond_wait() in qemu_sem_wait() > > Signed-off-by: Izumi Tsutsui > Reviewed-by: Laszlo Ersek > --- > > v2: > - make QemuSemaphore.count unsigned (it won't be negative) > - also eliminate checks for negative count values > - check a return value of in pthread_cond_wait() in qemu_sem_wait() I've compared this patch against v1. I can see one problem near the end: > > include/qemu/thread-posix.h | 2 +- > util/qemu-thread-posix.c | 26 +++++++++++++++----------- > 2 files changed, 16 insertions(+), 12 deletions(-) > > diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h > index 0f30dcc..361566a 100644 > --- a/include/qemu/thread-posix.h > +++ b/include/qemu/thread-posix.h > @@ -15,7 +15,7 @@ struct QemuSemaphore { > #if defined(__APPLE__) || defined(__NetBSD__) > pthread_mutex_t lock; > pthread_cond_t cond; > - int count; > + unsigned int count; > #else > sem_t sem; > #endif > diff --git a/util/qemu-thread-posix.c b/util/qemu-thread-posix.c > index 4489abf..44f6f30 100644 > --- a/util/qemu-thread-posix.c > +++ b/util/qemu-thread-posix.c > @@ -170,12 +170,11 @@ void qemu_sem_post(QemuSemaphore *sem) > > #if defined(__APPLE__) || defined(__NetBSD__) > pthread_mutex_lock(&sem->lock); > - if (sem->count == INT_MAX) { > + if (sem->count == UINT_MAX) { > rc = EINVAL; > - } else if (sem->count++ < 0) { > - rc = pthread_cond_signal(&sem->cond); > } else { > - rc = 0; > + sem->count++; > + rc = pthread_cond_signal(&sem->cond); > } > pthread_mutex_unlock(&sem->lock); > if (rc != 0) { > @@ -207,19 +206,21 @@ int qemu_sem_timedwait(QemuSemaphore *sem, int ms) > struct timespec ts; > > #if defined(__APPLE__) || defined(__NetBSD__) > + rc = 0; > compute_abs_deadline(&ts, ms); > pthread_mutex_lock(&sem->lock); > - --sem->count; > - while (sem->count < 0) { > + while (sem->count == 0) { > rc = pthread_cond_timedwait(&sem->cond, &sem->lock, &ts); > if (rc == ETIMEDOUT) { > - ++sem->count; > break; > } > if (rc != 0) { > error_exit(rc, __func__); > } > } > + if (rc != ETIMEDOUT) { > + --sem->count; > + } > pthread_mutex_unlock(&sem->lock); > return (rc == ETIMEDOUT ? -1 : 0); > #else > @@ -249,16 +250,19 @@ int qemu_sem_timedwait(QemuSemaphore *sem, int ms) > > void qemu_sem_wait(QemuSemaphore *sem) > { > + int rc; > + > #if defined(__APPLE__) || defined(__NetBSD__) > pthread_mutex_lock(&sem->lock); > - --sem->count; > - while (sem->count < 0) { > + while (sem->count == 0) { > pthread_cond_wait(&sem->cond, &sem->lock); > + if (rc != 0) { > + error_exit(rc, __func__); > + } You forgot to store the retval of pthread_cond_wait() in "rc", the (rc!=0) check refers to an indeterminate value. Otherwise it's good IMO. Thanks! Laszlo > } > + --sem->count; > pthread_mutex_unlock(&sem->lock); > #else > - int rc; > - > do { > rc = sem_wait(&sem->sem); > } while (rc == -1 && errno == EINTR); >