1aaaa20b6SVladimir Sementsov-Ogievskiy======================= 2aaaa20b6SVladimir Sementsov-Ogievskiyblock-coroutine-wrapper 3aaaa20b6SVladimir Sementsov-Ogievskiy======================= 4aaaa20b6SVladimir Sementsov-Ogievskiy 5aaaa20b6SVladimir Sementsov-OgievskiyA lot of functions in QEMU block layer (see ``block/*``) can only be 6aaaa20b6SVladimir Sementsov-Ogievskiycalled in coroutine context. Such functions are normally marked by the 7aaaa20b6SVladimir Sementsov-Ogievskiycoroutine_fn specifier. Still, sometimes we need to call them from 8aaaa20b6SVladimir Sementsov-Ogievskiynon-coroutine context; for this we need to start a coroutine, run the 9aaaa20b6SVladimir Sementsov-Ogievskiyneeded function from it and wait for the coroutine to finish in a 10aaaa20b6SVladimir Sementsov-OgievskiyBDRV_POLL_WHILE() loop. To run a coroutine we need a function with one 11aaaa20b6SVladimir Sementsov-Ogievskiyvoid* argument. So for each coroutine_fn function which needs a 12aaaa20b6SVladimir Sementsov-Ogievskiynon-coroutine interface, we should define a structure to pack the 13aaaa20b6SVladimir Sementsov-Ogievskiyparameters, define a separate function to unpack the parameters and 14aaaa20b6SVladimir Sementsov-Ogievskiycall the original function and finally define a new interface function 15aaaa20b6SVladimir Sementsov-Ogievskiywith same list of arguments as original one, which will pack the 16aaaa20b6SVladimir Sementsov-Ogievskiyparameters into a struct, create a coroutine, run it and wait in 17aaaa20b6SVladimir Sementsov-OgievskiyBDRV_POLL_WHILE() loop. It's boring to create such wrappers by hand, 18aaaa20b6SVladimir Sementsov-Ogievskiyso we have a script to generate them. 19aaaa20b6SVladimir Sementsov-Ogievskiy 20aaaa20b6SVladimir Sementsov-OgievskiyUsage 21aaaa20b6SVladimir Sementsov-Ogievskiy===== 22aaaa20b6SVladimir Sementsov-Ogievskiy 23aaaa20b6SVladimir Sementsov-OgievskiyAssume we have defined the ``coroutine_fn`` function 24aaaa20b6SVladimir Sementsov-Ogievskiy``bdrv_co_foo(<some args>)`` and need a non-coroutine interface for it, 25aaaa20b6SVladimir Sementsov-Ogievskiycalled ``bdrv_foo(<same args>)``. In this case the script can help. To 26aaaa20b6SVladimir Sementsov-Ogievskiytrigger the generation: 27aaaa20b6SVladimir Sementsov-Ogievskiy 28aaaa20b6SVladimir Sementsov-Ogievskiy1. You need ``bdrv_foo`` declaration somewhere (for example, in 29*76a2f554SEmanuele Giuseppe Esposito ``block/coroutines.h``) with the ``co_wrapper`` mark, 30aaaa20b6SVladimir Sementsov-Ogievskiy like this: 31aaaa20b6SVladimir Sementsov-Ogievskiy 32aaaa20b6SVladimir Sementsov-Ogievskiy.. code-block:: c 33aaaa20b6SVladimir Sementsov-Ogievskiy 34*76a2f554SEmanuele Giuseppe Esposito int co_wrapper bdrv_foo(<some args>); 35aaaa20b6SVladimir Sementsov-Ogievskiy 36aaaa20b6SVladimir Sementsov-Ogievskiy2. You need to feed this declaration to block-coroutine-wrapper script. 37aaaa20b6SVladimir Sementsov-Ogievskiy For this, add the .h (or .c) file with the declaration to the 38aaaa20b6SVladimir Sementsov-Ogievskiy ``input: files(...)`` list of ``block_gen_c`` target declaration in 39aaaa20b6SVladimir Sementsov-Ogievskiy ``block/meson.build`` 40aaaa20b6SVladimir Sementsov-Ogievskiy 41aaaa20b6SVladimir Sementsov-OgievskiyYou are done. During the build, coroutine wrappers will be generated in 42aaaa20b6SVladimir Sementsov-Ogievskiy``<BUILD_DIR>/block/block-gen.c``. 43aaaa20b6SVladimir Sementsov-Ogievskiy 44aaaa20b6SVladimir Sementsov-OgievskiyLinks 45aaaa20b6SVladimir Sementsov-Ogievskiy===== 46aaaa20b6SVladimir Sementsov-Ogievskiy 47aaaa20b6SVladimir Sementsov-Ogievskiy1. The script location is ``scripts/block-coroutine-wrapper.py``. 48aaaa20b6SVladimir Sementsov-Ogievskiy 49*76a2f554SEmanuele Giuseppe Esposito2. Generic place for private ``co_wrapper`` declarations is 50aaaa20b6SVladimir Sementsov-Ogievskiy ``block/coroutines.h``, for public declarations: 51aaaa20b6SVladimir Sementsov-Ogievskiy ``include/block/block.h`` 52aaaa20b6SVladimir Sementsov-Ogievskiy 53aaaa20b6SVladimir Sementsov-Ogievskiy3. The core API of generated coroutine wrappers is placed in 54aaaa20b6SVladimir Sementsov-Ogievskiy (not generated) ``block/block-gen.h`` 55