From nobody Sat Feb 7 05:49:35 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; dkim=fail spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1498743137086303.9478657126414; Thu, 29 Jun 2017 06:32:17 -0700 (PDT) Received: from localhost ([::1]:39379 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dQZYI-0001H8-Ld for importer@patchew.org; Thu, 29 Jun 2017 09:32:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48809) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dQZUD-0005hx-FB for qemu-devel@nongnu.org; Thu, 29 Jun 2017 09:27:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dQZUC-0001Iu-DW for qemu-devel@nongnu.org; Thu, 29 Jun 2017 09:27:57 -0400 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:33443) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dQZUC-0001Hg-73; Thu, 29 Jun 2017 09:27:56 -0400 Received: by mail-wr0-x243.google.com with SMTP id x23so36841328wrb.0; Thu, 29 Jun 2017 06:27:56 -0700 (PDT) Received: from localhost.localdomain (94-39-191-51.adsl-ull.clienti.tiscali.it. [94.39.191.51]) by smtp.gmail.com with ESMTPSA id i22sm4087691wrb.30.2017.06.29.06.27.53 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 29 Jun 2017 06:27:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=KBeaj3aYqi8JMNfs0DSXKShI7jN8gQe+HkV6nGVLTvg=; b=NUd6/B6tlygiOlW0N1jHTDjxW3e0RsQ6hw/C/4yMLBCQKwVo2ox8/HZXJ+xR57RWMJ 4Y7N0+JyLyAwfKA+vvx0v6YDZmqjhXmF8ZS/WBx8vjWfqX7fUIVqBjYQwdSMv0zUl2s9 6P0fj+LenZ1O5JV0q8P7AP8FLNxbVd4wyQfReJgMnH02oEMMv6sPlTEsbfUbwmSJXLPv 2C0KjSWuvuijGag2cn/0XR9o8yugY8Yqx9e5Y7f27Lpc2AiGxGjMDqx3jcH0YNFVzafe zNWAGniKr3wU0ruHO3qpBW+0+mVoBeAxo40hKEjxW2GI3B3B5OKang8tMlm3QGyUMN+I AXcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=KBeaj3aYqi8JMNfs0DSXKShI7jN8gQe+HkV6nGVLTvg=; b=oIoYIZ8ZlP4KJvyO5VbnENOtUiaKeIlVYnxF49QMZzmoAYZmdWE29ZdQTBlW9NkMwm Lcz6e69+V1g7KNV+AZoDHBZPT9cd2IZALULHQcl3KmSbbMPA6VYGUNEO298IXF8h3PRa oE74xl+Btm3yCA6GJObxdnTUug26fv/F5CnBC4fqzcP1KmoncuK7esR5rNg5qQ9LyOuK I7mfV11M+fjMAHXE6n1ECVWb7MUe/ikYFs2zaKyWVa0F6m1FoKEetVCSFtBGO69l/SE+ sbtBQ18jJsWB0QYH5QbZQBSM+DFTvVN6fIBYgNJIrjDpbdoOUPmjXleRwB/c8leaAXUv EnrA== X-Gm-Message-State: AKS2vOyaH8tcrclQwLXZBNsBsu2OpUgd3YKAxToc9oO1uuiti2yJpFMT l1TesDrPEWWUWbOOo3o= X-Received: by 10.223.170.138 with SMTP id h10mr11069040wrc.153.1498742874994; Thu, 29 Jun 2017 06:27:54 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Thu, 29 Jun 2017 15:27:40 +0200 Message-Id: <20170629132749.997-3-pbonzini@redhat.com> X-Mailer: git-send-email 2.13.0 In-Reply-To: <20170629132749.997-1-pbonzini@redhat.com> References: <20170629132749.997-1-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::243 Subject: [Qemu-devel] [PATCH 02/11] coroutine-lock: add qemu_co_rwlock_downgrade and qemu_co_rwlock_upgrade X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-block@nongnu.org, stefanha@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" These functions are more efficient in the presence of contention. qemu_co_rwlock_downgrade also guarantees not to block, which may be useful in some algorithms too. Reviewed-by: Eric Blake Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini --- include/qemu/coroutine.h | 18 ++++++++++++++++++ util/qemu-coroutine-lock.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index a4509bd977..9aff9a735e 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -229,6 +229,24 @@ void qemu_co_rwlock_init(CoRwlock *lock); void qemu_co_rwlock_rdlock(CoRwlock *lock); =20 /** + * Write Locks the CoRwlock from a reader. This is a bit more efficient t= han + * @qemu_co_rwlock_unlock followed by a separate @qemu_co_rwlock_wrlock. + * However, if the lock cannot be upgraded immediately, control is transfe= rred + * to the caller of the current coroutine. Also, @qemu_co_rwlock_upgrade + * only overrides CoRwlock fairness if there are no concurrent readers, so + * another writer might run while @qemu_co_rwlock_upgrade blocks. + */ +void qemu_co_rwlock_upgrade(CoRwlock *lock); + +/** + * Downgrades a write-side critical section to a reader. Downgrading with + * @qemu_co_rwlock_downgrade never blocks, unlike @qemu_co_rwlock_unlock + * followed by @qemu_co_rwlock_rdlock. This makes it more efficient, but + * may also sometimes be necessary for correctness. + */ +void qemu_co_rwlock_downgrade(CoRwlock *lock); + +/** * Write Locks the mutex. If the lock cannot be taken immediately because * of a parallel reader, control is transferred to the caller of the curre= nt * coroutine. diff --git a/util/qemu-coroutine-lock.c b/util/qemu-coroutine-lock.c index b44b5d55eb..846ff9167f 100644 --- a/util/qemu-coroutine-lock.c +++ b/util/qemu-coroutine-lock.c @@ -402,6 +402,21 @@ void qemu_co_rwlock_unlock(CoRwlock *lock) qemu_co_mutex_unlock(&lock->mutex); } =20 +void qemu_co_rwlock_downgrade(CoRwlock *lock) +{ + Coroutine *self =3D qemu_coroutine_self(); + + /* lock->mutex critical section started in qemu_co_rwlock_wrlock or + * qemu_co_rwlock_upgrade. + */ + assert(lock->reader =3D=3D 0); + lock->reader++; + qemu_co_mutex_unlock(&lock->mutex); + + /* The rest of the read-side critical section is run without the mutex= . */ + self->locks_held++; +} + void qemu_co_rwlock_wrlock(CoRwlock *lock) { qemu_co_mutex_lock(&lock->mutex); @@ -416,3 +431,23 @@ void qemu_co_rwlock_wrlock(CoRwlock *lock) * There is no need to update self->locks_held. */ } + +void qemu_co_rwlock_upgrade(CoRwlock *lock) +{ + Coroutine *self =3D qemu_coroutine_self(); + + qemu_co_mutex_lock(&lock->mutex); + assert(lock->reader > 0); + lock->reader--; + lock->pending_writer++; + while (lock->reader) { + qemu_co_queue_wait(&lock->queue, &lock->mutex); + } + lock->pending_writer--; + + /* The rest of the write-side critical section is run with + * the mutex taken, similar to qemu_co_rwlock_wrlock. Do + * not account for the lock twice in self->locks_held. + */ + self->locks_held--; +} --=20 2.13.0