qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v9 4/7] scripts: add block-coroutine-wrapper.py


From: Eric Blake
Subject: Re: [PATCH v9 4/7] scripts: add block-coroutine-wrapper.py
Date: Thu, 24 Sep 2020 14:10:30 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.11.0

On 9/24/20 1:54 PM, Vladimir Sementsov-Ogievskiy wrote:
We have a very frequent pattern of creating a coroutine from a function
with several arguments:

   - create a structure to pack parameters
   - create _entry function to call original function taking parameters
     from struct
   - do different magic to handle completion: set ret to NOT_DONE or
     EINPROGRESS or use separate bool field
   - fill the struct and create coroutine from _entry function with this
     struct as a parameter
   - do coroutine enter and BDRV_POLL_WHILE loop

Let's reduce code duplication by generating coroutine wrappers.

This patch adds scripts/block-coroutine-wrapper.py together with some
friends, which will generate functions with declared prototypes marked
by the 'generated_co_wrapper' specifier.

The usage of new code generation is as follows:

     1. define the coroutine function somewhere

         int coroutine_fn bdrv_co_NAME(...) {...}

     2. declare in some header file

         int generated_co_wrapper bdrv_NAME(...);

        with same list of parameters (generated_co_wrapper is
        defined in "include/block/block.h").

     3. Make sure the block_gen_c delaration in block/meson.build

declaration

        mentions the file with your marker function.

Still, no function is now marked, this work is for the following
commit.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---

+++ b/docs/devel/block-coroutine-wrapper.rst
@@ -0,0 +1,54 @@
+=======================
+block-coroutine-wrapper
+=======================
+
+A lot of functions in QEMU block layer (see ``block/*``) can only be
+called in coroutine context. Such functions are normally marked by the
+coroutine_fn specifier. Still, sometimes we need to call them from
+non-coroutine context; for this we need to start a coroutine, run the
+needed function from it and wait for coroutine finish in

to finish in a

+BDRV_POLL_WHILE() loop. To run a coroutine we need a function with one
+void* argument. So for each coroutine_fn function which needs a
+non-coroutine interface, we should define a structure to pack the
+parameters, define a separate function to unpack the parameters and
+call the original function and finally define a new interface function
+with same list of arguments as original one, which will pack the
+parameters into a struct, create a coroutine, run it and wait in
+BDRV_POLL_WHILE() loop. It's boring to create such wrappers by hand,
+so we have a script to generate them.
+

+++ b/scripts/block-coroutine-wrapper.py
Reviewed-by: Eric Blake <eblake@redhat.com>

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org




reply via email to

[Prev in Thread] Current Thread [Next in Thread]