mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
lockable: add QemuLockable
QemuLockable is a polymorphic lock type that takes an object and knows which function to use for locking and unlocking. The implementation could use C11 _Generic, but since the support is not very widespread I am instead using __builtin_choose_expr and __builtin_types_compatible_p, which are already used by include/qemu/atomic.h. QemuLockable can be used to implement lock guards, or to pass around a lock in such a way that a function can release it and re-acquire it. The next patch will do this for CoQueue. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20180203153935.8056-3-pbonzini@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Signed-off-by: Fam Zheng <famz@redhat.com>
This commit is contained in:
parent
439b6e5efc
commit
e70372fcaf
6 changed files with 168 additions and 5 deletions
|
@ -14,6 +14,7 @@
|
|||
#include "qemu/osdep.h"
|
||||
#include "qemu/coroutine.h"
|
||||
#include "qemu/coroutine_int.h"
|
||||
#include "qemu/lockable.h"
|
||||
|
||||
/*
|
||||
* Check that qemu_in_coroutine() works
|
||||
|
@ -210,6 +211,18 @@ static void coroutine_fn mutex_fn(void *opaque)
|
|||
done++;
|
||||
}
|
||||
|
||||
static void coroutine_fn lockable_fn(void *opaque)
|
||||
{
|
||||
QemuLockable *x = opaque;
|
||||
qemu_lockable_lock(x);
|
||||
assert(!locked);
|
||||
locked = true;
|
||||
qemu_coroutine_yield();
|
||||
locked = false;
|
||||
qemu_lockable_unlock(x);
|
||||
done++;
|
||||
}
|
||||
|
||||
static void do_test_co_mutex(CoroutineEntry *entry, void *opaque)
|
||||
{
|
||||
Coroutine *c1 = qemu_coroutine_create(entry, opaque);
|
||||
|
@ -240,6 +253,17 @@ static void test_co_mutex(void)
|
|||
do_test_co_mutex(mutex_fn, &m);
|
||||
}
|
||||
|
||||
static void test_co_mutex_lockable(void)
|
||||
{
|
||||
CoMutex m;
|
||||
CoMutex *null_pointer = NULL;
|
||||
|
||||
qemu_co_mutex_init(&m);
|
||||
do_test_co_mutex(lockable_fn, QEMU_MAKE_LOCKABLE(&m));
|
||||
|
||||
g_assert(QEMU_MAKE_LOCKABLE(null_pointer) == NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that creation, enter, and return work
|
||||
*/
|
||||
|
@ -478,6 +502,7 @@ int main(int argc, char **argv)
|
|||
g_test_add_func("/basic/in_coroutine", test_in_coroutine);
|
||||
g_test_add_func("/basic/order", test_order);
|
||||
g_test_add_func("/locking/co-mutex", test_co_mutex);
|
||||
g_test_add_func("/locking/co-mutex/lockable", test_co_mutex_lockable);
|
||||
if (g_test_perf()) {
|
||||
g_test_add_func("/perf/lifecycle", perf_lifecycle);
|
||||
g_test_add_func("/perf/nesting", perf_nesting);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue