aboutsummaryrefslogtreecommitdiff
path: root/tests/test-coroutine.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2018-02-03 10:39:31 -0500
committerFam Zheng <famz@redhat.com>2018-02-08 09:21:34 +0800
commit439b6e5efcd79effc5199cba533fe4b28d75e0f6 (patch)
treefd7f3588d15f8d9c614f846372d6386a49c83029 /tests/test-coroutine.c
parent5b9b49d7bd3e0da13e8f6d58578443a11817f56e (diff)
test-coroutine: add simple CoMutex test
In preparation for adding a similar test using QemuLockable, add a very simple testcase that has two interleaved calls to lock and unlock. Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20180203153935.8056-2-pbonzini@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Fam Zheng <famz@redhat.com> Signed-off-by: Fam Zheng <famz@redhat.com>
Diffstat (limited to 'tests/test-coroutine.c')
-rw-r--r--tests/test-coroutine.c50
1 files changed, 48 insertions, 2 deletions
diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c
index 76c646107e..ab8fdf701e 100644
--- a/tests/test-coroutine.c
+++ b/tests/test-coroutine.c
@@ -175,7 +175,7 @@ static void coroutine_fn c1_fn(void *opaque)
qemu_coroutine_enter(c2);
}
-static void test_co_queue(void)
+static void test_no_dangling_access(void)
{
Coroutine *c1;
Coroutine *c2;
@@ -195,6 +195,51 @@ static void test_co_queue(void)
*c1 = tmp;
}
+static bool locked;
+static int done;
+
+static void coroutine_fn mutex_fn(void *opaque)
+{
+ CoMutex *m = opaque;
+ qemu_co_mutex_lock(m);
+ assert(!locked);
+ locked = true;
+ qemu_coroutine_yield();
+ locked = false;
+ qemu_co_mutex_unlock(m);
+ done++;
+}
+
+static void do_test_co_mutex(CoroutineEntry *entry, void *opaque)
+{
+ Coroutine *c1 = qemu_coroutine_create(entry, opaque);
+ Coroutine *c2 = qemu_coroutine_create(entry, opaque);
+
+ done = 0;
+ qemu_coroutine_enter(c1);
+ g_assert(locked);
+ qemu_coroutine_enter(c2);
+
+ /* Unlock queues c2. It is then started automatically when c1 yields or
+ * terminates.
+ */
+ qemu_coroutine_enter(c1);
+ g_assert_cmpint(done, ==, 1);
+ g_assert(locked);
+
+ qemu_coroutine_enter(c2);
+ g_assert_cmpint(done, ==, 2);
+ g_assert(!locked);
+}
+
+static void test_co_mutex(void)
+{
+ CoMutex m;
+
+ qemu_co_mutex_init(&m);
+ do_test_co_mutex(mutex_fn, &m);
+}
+
/*
* Check that creation, enter, and return work
*/
@@ -422,7 +467,7 @@ int main(int argc, char **argv)
* crash, so skip it.
*/
if (CONFIG_COROUTINE_POOL) {
- g_test_add_func("/basic/co_queue", test_co_queue);
+ g_test_add_func("/basic/no-dangling-access", test_no_dangling_access);
}
g_test_add_func("/basic/lifecycle", test_lifecycle);
@@ -432,6 +477,7 @@ int main(int argc, char **argv)
g_test_add_func("/basic/entered", test_entered);
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);
if (g_test_perf()) {
g_test_add_func("/perf/lifecycle", perf_lifecycle);
g_test_add_func("/perf/nesting", perf_nesting);