From: "Emilio G. Cota" <cota@braap.org>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-devel@nongnu.org, qemu-block@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 02/10] qemu-thread: introduce QemuLockCnt
Date: Thu, 02 Feb 2017 19:06:47 -0000 [thread overview]
Message-ID: <20161206014943.GA25612@flamenco> (raw)
In-Reply-To: <20161129114707.2975-3-pbonzini@redhat.com>
On Tue, Nov 29, 2016 at 12:46:59 +0100, Paolo Bonzini wrote:
> A QemuLockCnt comprises a counter and a mutex, with primitives
> to increment and decrement the counter, and to take and release the
> mutex. It can be used to do lock-free visits to a data structure
> whenever mutexes would be too heavy-weight and the critical section
> is too long for RCU.
>
> This could be implemented simply by protecting the counter with the
> mutex, but QemuLockCnt is harder to misuse and more efficient.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(snip)
> +++ b/docs/lockcnt.txt
> @@ -0,0 +1,343 @@
> +DOCUMENTATION FOR LOCKED COUNTERS (aka QemuLockCnt)
> +===================================================
(snip)
> + bool qemu_lockcnt_dec_if_lock(QemuLockCnt *lockcnt);
> +
> + If the count is 1, decrement the count to zero, lock
> + the mutex and return true. Otherwise, return false.
> +
(snip)
> +++ b/util/lockcnt.c
(snip)
> +void qemu_lockcnt_init(QemuLockCnt *lockcnt)
> +{
> + qemu_mutex_init(&lockcnt->mutex);
> + lockcnt->count = 0;
Minor nit: a release barrier here wouldn't harm.
> +}
> +
> +void qemu_lockcnt_destroy(QemuLockCnt *lockcnt)
> +{
> + qemu_mutex_destroy(&lockcnt->mutex);
> +}
> +
> +void qemu_lockcnt_inc(QemuLockCnt *lockcnt)
> +{
> + int old;
> + for (;;) {
> + old = atomic_read(&lockcnt->count);
> + if (old == 0) {
> + qemu_lockcnt_lock(lockcnt);
> + qemu_lockcnt_inc_and_unlock(lockcnt);
> + return;
> + } else {
> + if (atomic_cmpxchg(&lockcnt->count, old, old + 1) == old) {
> + return;
> + }
> + }
> + }
> +}
> +
> +void qemu_lockcnt_dec(QemuLockCnt *lockcnt)
> +{
> + atomic_dec(&lockcnt->count);
> +}
> +
> +/* Decrement a counter, and return locked if it is decremented to zero.
> + * It is impossible for the counter to become nonzero while the mutex
> + * is taken.
> + */
> +bool qemu_lockcnt_dec_and_lock(QemuLockCnt *lockcnt)
> +{
> + int val = atomic_read(&lockcnt->count);
> + while (val > 1) {
> + int old = atomic_cmpxchg(&lockcnt->count, val, val - 1);
> + if (old != val) {
> + val = old;
> + continue;
> + }
> +
> + return false;
> + }
Minor nit:
while (val > 1) {
int old = cmpxchg();
if (old == val) {
return false;
}
val = old;
}
seems to me a little easier to read.
> + qemu_lockcnt_lock(lockcnt);
> + if (atomic_fetch_dec(&lockcnt->count) == 1) {
> + return true;
> + }
> +
> + qemu_lockcnt_unlock(lockcnt);
> + return false;
> +}
> +
> +/* Decrement a counter and return locked if it is decremented to zero.
> + * Otherwise do nothing.
This comment doesn't match the code below nor the description in the
.txt file (quoted above) [we might not decrement the counter at all!]
> + *
> + * It is impossible for the counter to become nonzero while the mutex
> + * is taken.
> + */
> +bool qemu_lockcnt_dec_if_lock(QemuLockCnt *lockcnt)
> +{
> + int val = atomic_mb_read(&lockcnt->count);
> + if (val > 1) {
> + return false;
> + }
> +
> + qemu_lockcnt_lock(lockcnt);
> + if (atomic_fetch_dec(&lockcnt->count) == 1) {
> + return true;
> + }
> +
> + qemu_lockcnt_inc_and_unlock(lockcnt);
The choice of dec+(maybe)inc over cmpxchg seems a little odd to me.
Emilio
next prev parent reply other threads:[~2017-02-02 19:06 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-11-29 11:46 [Qemu-devel] [PATCH for-2.9 00/10] aio_context_acquire/release pushdown, part 1 Paolo Bonzini
2016-11-29 11:46 ` [Qemu-devel] [PATCH 01/10] aio: rename bh_lock to list_lock Paolo Bonzini
2016-11-30 12:53 ` Stefan Hajnoczi
2016-11-29 11:46 ` [Qemu-devel] [PATCH 02/10] qemu-thread: introduce QemuLockCnt Paolo Bonzini
2016-11-29 19:34 ` Eric Blake
2016-11-30 13:05 ` Stefan Hajnoczi
2017-02-02 19:06 ` Emilio G. Cota [this message]
2017-02-02 19:20 ` Emilio G. Cota
2016-11-29 11:47 ` [Qemu-devel] [PATCH 03/10] aio: make ctx->list_lock a QemuLockCnt, subsuming ctx->walking_bh Paolo Bonzini
2016-11-30 13:06 ` Stefan Hajnoczi
2016-11-29 11:47 ` [Qemu-devel] [PATCH 04/10] qemu-thread: optimize QemuLockCnt with futexes on Linux Paolo Bonzini
2016-11-30 13:19 ` Stefan Hajnoczi
2016-11-29 11:47 ` [Qemu-devel] [PATCH 05/10] aio: tweak walking in dispatch phase Paolo Bonzini
2016-11-30 13:38 ` Stefan Hajnoczi
2016-11-29 11:47 ` [Qemu-devel] [PATCH 06/10] aio-posix: remove walking_handlers, protecting AioHandler list with list_lock Paolo Bonzini
2016-11-30 13:31 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2016-11-30 13:36 ` Paolo Bonzini
2016-12-01 15:32 ` [Qemu-devel] " Paolo Bonzini
2016-11-29 11:47 ` [Qemu-devel] [PATCH 07/10] aio-win32: " Paolo Bonzini
2016-11-30 13:34 ` Stefan Hajnoczi
2016-11-29 11:47 ` [Qemu-devel] [PATCH 08/10] aio: document locking Paolo Bonzini
2016-11-30 13:35 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2016-11-29 11:47 ` [Qemu-devel] [PATCH 09/10] aio: push aio_context_acquire/release down to dispatching Paolo Bonzini
2016-11-30 13:37 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2016-11-29 11:47 ` [Qemu-devel] [PATCH 10/10] async: optimize aio_bh_poll Paolo Bonzini
2016-11-30 13:38 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
-- strict thread matches above, loose matches on Subject: below --
2016-12-21 14:03 [Qemu-devel] [PATCH v2 00/10] aio_context_acquire/release pushdown, part 1 Paolo Bonzini
2016-12-21 14:03 ` [Qemu-devel] [PATCH 02/10] qemu-thread: introduce QemuLockCnt Paolo Bonzini
2017-01-04 13:26 [Qemu-devel] [PATCH v3 00/10] aio_context_acquire/release pushdown, part 1 Paolo Bonzini
2017-01-04 13:26 ` [Qemu-devel] [PATCH 02/10] qemu-thread: introduce QemuLockCnt Paolo Bonzini
2017-01-11 15:48 ` Fam Zheng
2017-01-11 16:09 ` Paolo Bonzini
2017-01-11 16:35 ` Stefan Hajnoczi
2017-01-11 16:51 ` Paolo Bonzini
2017-01-11 16:56 ` Stefan Hajnoczi
2017-01-12 16:55 [Qemu-devel] [PATCH v4 00/10] aio_context_acquire/release pushdown, part 1 Paolo Bonzini
2017-01-12 16:55 ` [Qemu-devel] [PATCH 02/10] qemu-thread: introduce QemuLockCnt Paolo Bonzini
2017-01-12 18:07 [Qemu-devel] [PATCH v5 00/10] aio_context_acquire/release pushdown, part 1 Paolo Bonzini
2017-01-12 18:07 ` [Qemu-devel] [PATCH 02/10] qemu-thread: introduce QemuLockCnt Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20161206014943.GA25612@flamenco \
--to=cota@braap.org \
--cc=pbonzini@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.