summaryrefslogtreecommitdiffstats
path: root/tests/test-coroutine.c
diff options
context:
space:
mode:
authorPeter Maydell2018-02-08 15:31:51 +0100
committerPeter Maydell2018-02-08 15:31:51 +0100
commit008a51bbb343972dd8cf09126da8c3b87f4e1c96 (patch)
tree6e5f7c697a796ef35198a65623e4dbdc76d3e6da /tests/test-coroutine.c
parentMerge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into ... (diff)
parentdocs: Add docs/devel/testing.rst (diff)
downloadqemu-008a51bbb343972dd8cf09126da8c3b87f4e1c96.tar.gz
qemu-008a51bbb343972dd8cf09126da8c3b87f4e1c96.tar.xz
qemu-008a51bbb343972dd8cf09126da8c3b87f4e1c96.zip
Merge remote-tracking branch 'remotes/famz/tags/staging-pull-request' into staging
# gpg: Signature made Thu 08 Feb 2018 01:29:22 GMT # gpg: using RSA key CA35624C6A9171C6 # gpg: Good signature from "Fam Zheng <famz@redhat.com>" # Primary key fingerprint: 5003 7CB7 9706 0F76 F021 AD56 CA35 624C 6A91 71C6 * remotes/famz/tags/staging-pull-request: docs: Add docs/devel/testing.rst qapi: Add NVMe driver options to the schema docs: Add section for NVMe VFIO driver block: Move NVMe constants to a separate header qemu-img: Map bench buffer block/nvme: Implement .bdrv_(un)register_buf block: Introduce buf register API block: Add VFIO based NVMe driver util: Introduce vfio helpers stubs: Add stubs for ram block API curl: convert to CoQueue coroutine-lock: make qemu_co_enter_next thread-safe coroutine-lock: convert CoQueue to use QemuLockable lockable: add QemuLockable test-coroutine: add simple CoMutex test docker: change Fedora base image to fedora:27 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'tests/test-coroutine.c')
-rw-r--r--tests/test-coroutine.c75
1 files changed, 73 insertions, 2 deletions
diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c
index 76c646107e..28e79b3210 100644
--- a/tests/test-coroutine.c
+++ b/tests/test-coroutine.c
@@ -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
@@ -175,7 +176,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 +196,74 @@ 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 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);
+ 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);
+}
+
+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
*/
@@ -422,7 +491,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 +501,8 @@ 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);
+ 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);