diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-06-28 17:08:34 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-06-28 18:58:19 +0100 |
commit | 9e654e10197f5a014eccd71de5ea633c1b0f4303 (patch) | |
tree | f2b4d3eef40dc0aa3871511bae70b75fabb2010b /util/qemu-co-shared-resource.c | |
parent | 271fc190b309a47dc76cbe995e12d1bc6350f7ad (diff) | |
parent | 149009bef4b4b4db37b3cf72b41dc2c6e8ca1885 (diff) |
Merge remote-tracking branch 'remotes/vsementsov/tags/pull-jobs-2021-06-25' into staging
block: Make block-copy API thread-safe
# gpg: Signature made Fri 25 Jun 2021 13:40:24 BST
# gpg: using RSA key 8B9C26CDB2FD147C880E86A1561F24C1F19F79FB
# gpg: Good signature from "Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8B9C 26CD B2FD 147C 880E 86A1 561F 24C1 F19F 79FB
* remotes/vsementsov/tags/pull-jobs-2021-06-25:
block-copy: atomic .cancelled and .finished fields in BlockCopyCallState
block-copy: add CoMutex lock
block-copy: move progress_set_remaining in block_copy_task_end
block-copy: streamline choice of copy_range vs. read/write
block-copy: small refactor in block_copy_task_entry and block_copy_common
co-shared-resource: protect with a mutex
progressmeter: protect with a mutex
blockjob: let ratelimit handle a speed of 0
block-copy: let ratelimit handle a speed of 0
ratelimit: treat zero speed as unlimited
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/qemu-co-shared-resource.c')
-rw-r--r-- | util/qemu-co-shared-resource.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/util/qemu-co-shared-resource.c b/util/qemu-co-shared-resource.c index 1c83cd9d29..a66cc07e75 100644 --- a/util/qemu-co-shared-resource.c +++ b/util/qemu-co-shared-resource.c @@ -28,10 +28,13 @@ #include "qemu/co-shared-resource.h" struct SharedResource { - uint64_t total; - uint64_t available; + uint64_t total; /* Set in shres_create() and not changed anymore */ + /* State fields protected by lock */ + uint64_t available; CoQueue queue; + + QemuMutex lock; }; SharedResource *shres_create(uint64_t total) @@ -40,6 +43,7 @@ SharedResource *shres_create(uint64_t total) s->total = s->available = total; qemu_co_queue_init(&s->queue); + qemu_mutex_init(&s->lock); return s; } @@ -47,10 +51,12 @@ SharedResource *shres_create(uint64_t total) void shres_destroy(SharedResource *s) { assert(s->available == s->total); + qemu_mutex_destroy(&s->lock); g_free(s); } -bool co_try_get_from_shres(SharedResource *s, uint64_t n) +/* Called with lock held. */ +static bool co_try_get_from_shres_locked(SharedResource *s, uint64_t n) { if (s->available >= n) { s->available -= n; @@ -60,16 +66,24 @@ bool co_try_get_from_shres(SharedResource *s, uint64_t n) return false; } +bool co_try_get_from_shres(SharedResource *s, uint64_t n) +{ + QEMU_LOCK_GUARD(&s->lock); + return co_try_get_from_shres_locked(s, n); +} + void coroutine_fn co_get_from_shres(SharedResource *s, uint64_t n) { assert(n <= s->total); - while (!co_try_get_from_shres(s, n)) { - qemu_co_queue_wait(&s->queue, NULL); + QEMU_LOCK_GUARD(&s->lock); + while (!co_try_get_from_shres_locked(s, n)) { + qemu_co_queue_wait(&s->queue, &s->lock); } } void coroutine_fn co_put_to_shres(SharedResource *s, uint64_t n) { + QEMU_LOCK_GUARD(&s->lock); assert(s->total - s->available >= n); s->available += n; qemu_co_queue_restart_all(&s->queue); |