mirror of https://github.com/xemu-project/xemu.git
block: Add no_coroutine_fn and coroutine_mixed_fn marker
Add more annotations to functions, describing valid and invalid calls from coroutine to non-coroutine context. When applied to a function, no_coroutine_fn advertises that it should not be called from coroutine_fn functions. This can be because the function blocks or, in the case of generated_co_wrapper, to enforce that coroutine_fn functions directly call the coroutine_fn that backs the generated_co_wrapper. coroutine_mixed_fn instead is for function that can be called in both coroutine and non-coroutine context, but will suspend when called in coroutine context. Annotating them is a first step towards enforcing that non-annotated functions are absolutely not going to suspend. These can be used for example with the vrc tool: # find functions that *really* cannot be called from no_coroutine_fn (vrc) load --loader clang libblock.fa.p/meson-generated_.._block_block-gen.c.o (vrc) paths [no_coroutine_fn,!coroutine_mixed_fn] bdrv_remove_persistent_dirty_bitmap bdrv_create bdrv_can_store_new_dirty_bitmap # find how coroutine_fns end up calling a mixed function (vrc) load --loader clang --force libblock.fa.p/*.c.o (vrc) paths [coroutine_fn] [!no_coroutine_fn]* [coroutine_mixed_fn] ... bdrv_pread <- vhdx_log_write <- vhdx_log_write_and_flush <- vhdx_co_writev ... Signed-off-by: Alberto Faria <afaria@redhat.com> [Rebase, add coroutine_mixed_fn. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20221216110758.559947-3-pbonzini@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
cbdbc47cee
commit
0f3de970fe
|
@ -45,11 +45,14 @@
|
|||
* - co_wrapper_mixed_bdrv_rdlock are co_wrapper_mixed functions but
|
||||
* automatically take and release the graph rdlock when creating a new
|
||||
* coroutine.
|
||||
*
|
||||
* These functions should not be called from a coroutine_fn; instead,
|
||||
* call the wrapped function directly.
|
||||
*/
|
||||
#define co_wrapper
|
||||
#define co_wrapper_mixed
|
||||
#define co_wrapper_bdrv_rdlock
|
||||
#define co_wrapper_mixed_bdrv_rdlock
|
||||
#define co_wrapper no_coroutine_fn
|
||||
#define co_wrapper_mixed no_coroutine_fn coroutine_mixed_fn
|
||||
#define co_wrapper_bdrv_rdlock no_coroutine_fn
|
||||
#define co_wrapper_mixed_bdrv_rdlock no_coroutine_fn coroutine_mixed_fn
|
||||
|
||||
#include "block/blockjob.h"
|
||||
|
||||
|
|
|
@ -177,6 +177,46 @@ extern "C" {
|
|||
#define coroutine_fn
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Mark a function that can suspend when executed in coroutine context,
|
||||
* but can handle running in non-coroutine context too.
|
||||
*/
|
||||
#ifdef __clang__
|
||||
#define coroutine_mixed_fn __attribute__((__annotate__("coroutine_mixed_fn")))
|
||||
#else
|
||||
#define coroutine_mixed_fn
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Mark a function that should not be called from a coroutine context.
|
||||
* Usually there will be an analogous, coroutine_fn function that should
|
||||
* be used instead.
|
||||
*
|
||||
* When the function is also marked as coroutine_mixed_fn, the function should
|
||||
* only be called if the caller does not know whether it is in coroutine
|
||||
* context.
|
||||
*
|
||||
* Functions that are only no_coroutine_fn, on the other hand, should not
|
||||
* be called from within coroutines at all. This for example includes
|
||||
* functions that block.
|
||||
*
|
||||
* In the future it would be nice to enable compiler or static checker
|
||||
* support for catching such errors. This annotation is the first step
|
||||
* towards this, and in the meantime it serves as documentation.
|
||||
*
|
||||
* For example:
|
||||
*
|
||||
* static void no_coroutine_fn foo(void) {
|
||||
* ....
|
||||
* }
|
||||
*/
|
||||
#ifdef __clang__
|
||||
#define no_coroutine_fn __attribute__((__annotate__("no_coroutine_fn")))
|
||||
#else
|
||||
#define no_coroutine_fn
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* For mingw, as of v6.0.0, the function implementing the assert macro is
|
||||
* not marked as noreturn, so the compiler cannot delete code following an
|
||||
|
|
Loading…
Reference in New Issue