From af7f8eb591b45e9a950f2622b96640ff1f2a6794 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 21 Dec 2022 14:14:32 +0100 Subject: coroutine: Move coroutine_fn to qemu/osdep.h, trim includes block/block-hmp-cmds.h and qemu/co-shared-resource.h use coroutine_fn without including qemu/coroutine.h. They compile only if it's already included from elsewhere. I could fix that, but pulling in qemu/coroutine.h and everything it includes just for a macro that expands into nothing feels silly. Instead, move the macro to qemu/osdep.h. Inclusions of qemu/coroutine.h just for coroutine_fn become superfluous. Drop them. Signed-off-by: Markus Armbruster Reviewed-by: Stefan Hajnoczi Message-Id: <20221221131435.3851212-3-armbru@redhat.com> --- include/qemu/coroutine.h | 18 +++++++----------- include/qemu/osdep.h | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 11 deletions(-) (limited to 'include/qemu') diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index 89650a2..2496a4f 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -26,23 +26,19 @@ * waiting for events to complete. * * These functions are re-entrant and may be used outside the global mutex. - */ - -/** - * Mark a function that executes in coroutine context * - * Functions that execute in coroutine context cannot be called directly from - * normal functions. In the future it would be nice to enable compiler or - * static checker support for catching such errors. This annotation might make - * it possible and in the meantime it serves as documentation. - * - * For example: + * Functions that execute in coroutine context cannot be called + * directly from normal functions. Use @coroutine_fn to mark such + * functions. For example: * * static void coroutine_fn foo(void) { * .... * } + * + * In the future it would be nice to have the compiler or a static + * checker catch misuse of such functions. This annotation might make + * it possible and in the meantime it serves as documentation. */ -#define coroutine_fn typedef struct Coroutine Coroutine; diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h index bd23a08..c850001 100644 --- a/include/qemu/osdep.h +++ b/include/qemu/osdep.h @@ -157,6 +157,22 @@ extern "C" { #include "qemu/typedefs.h" +/** + * Mark a function that executes in coroutine context + * + * Functions that execute in coroutine context cannot be called directly from + * normal functions. In the future it would be nice to enable compiler or + * static checker support for catching such errors. This annotation might make + * it possible and in the meantime it serves as documentation. + * + * For example: + * + * static void coroutine_fn foo(void) { + * .... + * } + */ +#define coroutine_fn + /* * 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 -- cgit v1.1 From df4bbc9dcb09d9e3a385ca1a2a23daad0819f531 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 21 Dec 2022 14:14:33 +0100 Subject: coroutine: Clean up superfluous inclusion of qemu/lockable.h Signed-off-by: Markus Armbruster Reviewed-by: Stefan Hajnoczi Message-Id: <20221221131435.3851212-4-armbru@redhat.com> --- include/qemu/progress_meter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/qemu') diff --git a/include/qemu/progress_meter.h b/include/qemu/progress_meter.h index dadf822..0f2c0a3 100644 --- a/include/qemu/progress_meter.h +++ b/include/qemu/progress_meter.h @@ -27,7 +27,7 @@ #ifndef QEMU_PROGRESS_METER_H #define QEMU_PROGRESS_METER_H -#include "qemu/lockable.h" +#include "qemu/thread.h" typedef struct ProgressMeter { /** -- cgit v1.1 From 68ba85cecc7a46ceb66c2f4b5e2165546821d062 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Wed, 21 Dec 2022 14:14:34 +0100 Subject: coroutine: Split qemu/coroutine-core.h off qemu/coroutine.h qemu/coroutine.h and qemu/lockable.h include each other. They need each other only in macro expansions, so we could simply drop both inclusions to break the loop, and add suitable includes to files that expand the macros. Instead, move a part of qemu/coroutine.h to new qemu/coroutine-core.h so that qemu/coroutine-core.h doesn't need qemu/lockable.h, and qemu/lockable.h only needs qemu/coroutine-core.h. Result: qemu/coroutine.h includes qemu/lockable.h includes qemu/coroutine-core.h. Signed-off-by: Markus Armbruster Message-Id: <20221221131435.3851212-5-armbru@redhat.com> [Semantic rebase conflict with 7c10cb38cc "accel/tcg: Add debuginfo support" resolved] --- include/qemu/coroutine-core.h | 154 ++++++++++++++++++++++++++++++++++++++++++ include/qemu/coroutine.h | 97 +------------------------- include/qemu/lockable.h | 2 +- include/qemu/typedefs.h | 1 - 4 files changed, 156 insertions(+), 98 deletions(-) create mode 100644 include/qemu/coroutine-core.h (limited to 'include/qemu') diff --git a/include/qemu/coroutine-core.h b/include/qemu/coroutine-core.h new file mode 100644 index 0000000..230bb56 --- /dev/null +++ b/include/qemu/coroutine-core.h @@ -0,0 +1,154 @@ +/* + * QEMU coroutine implementation + * + * Copyright IBM, Corp. 2011 + * + * Authors: + * Stefan Hajnoczi + * Kevin Wolf + * + * This work is licensed under the terms of the GNU LGPL, version 2 or later. + * See the COPYING.LIB file in the top-level directory. + * + */ + +#ifndef QEMU_COROUTINE_CORE_H +#define QEMU_COROUTINE_CORE_H + +/** + * Coroutines are a mechanism for stack switching and can be used for + * cooperative userspace threading. These functions provide a simple but + * useful flavor of coroutines that is suitable for writing sequential code, + * rather than callbacks, for operations that need to give up control while + * waiting for events to complete. + * + * These functions are re-entrant and may be used outside the global mutex. + * + * Functions that execute in coroutine context cannot be called + * directly from normal functions. Use @coroutine_fn to mark such + * functions. For example: + * + * static void coroutine_fn foo(void) { + * .... + * } + * + * In the future it would be nice to have the compiler or a static + * checker catch misuse of such functions. This annotation might make + * it possible and in the meantime it serves as documentation. + */ + +/** + * Mark a function that executes in coroutine context + * + * + * Functions that execute in coroutine context cannot be called + * directly from normal functions. Use @coroutine_fn to mark such + * functions. For example: + * + * static void coroutine_fn foo(void) { + * .... + * } + * + * In the future it would be nice to have the compiler or a static + * checker catch misuse of such functions. This annotation might make + * it possible and in the meantime it serves as documentation. + */ + +typedef struct Coroutine Coroutine; +typedef struct CoMutex CoMutex; + +/** + * Coroutine entry point + * + * When the coroutine is entered for the first time, opaque is passed in as an + * argument. + * + * When this function returns, the coroutine is destroyed automatically and + * execution continues in the caller who last entered the coroutine. + */ +typedef void coroutine_fn CoroutineEntry(void *opaque); + +/** + * Create a new coroutine + * + * Use qemu_coroutine_enter() to actually transfer control to the coroutine. + * The opaque argument is passed as the argument to the entry point. + */ +Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque); + +/** + * Transfer control to a coroutine + */ +void qemu_coroutine_enter(Coroutine *coroutine); + +/** + * Transfer control to a coroutine if it's not active (i.e. part of the call + * stack of the running coroutine). Otherwise, do nothing. + */ +void qemu_coroutine_enter_if_inactive(Coroutine *co); + +/** + * Transfer control to a coroutine and associate it with ctx + */ +void qemu_aio_coroutine_enter(AioContext *ctx, Coroutine *co); + +/** + * Transfer control back to a coroutine's caller + * + * This function does not return until the coroutine is re-entered using + * qemu_coroutine_enter(). + */ +void coroutine_fn qemu_coroutine_yield(void); + +/** + * Get the AioContext of the given coroutine + */ +AioContext *qemu_coroutine_get_aio_context(Coroutine *co); + +/** + * Get the currently executing coroutine + */ +Coroutine *qemu_coroutine_self(void); + +/** + * Return whether or not currently inside a coroutine + * + * This can be used to write functions that work both when in coroutine context + * and when not in coroutine context. Note that such functions cannot use the + * coroutine_fn annotation since they work outside coroutine context. + */ +bool qemu_in_coroutine(void); + +/** + * Return true if the coroutine is currently entered + * + * A coroutine is "entered" if it has not yielded from the current + * qemu_coroutine_enter() call used to run it. This does not mean that the + * coroutine is currently executing code since it may have transferred control + * to another coroutine using qemu_coroutine_enter(). + * + * When several coroutines enter each other there may be no way to know which + * ones have already been entered. In such situations this function can be + * used to avoid recursively entering coroutines. + */ +bool qemu_coroutine_entered(Coroutine *co); + +/** + * Initialises a CoMutex. This must be called before any other operation is used + * on the CoMutex. + */ +void qemu_co_mutex_init(CoMutex *mutex); + +/** + * Locks the mutex. If the lock cannot be taken immediately, control is + * transferred to the caller of the current coroutine. + */ +void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex); + +/** + * Unlocks the mutex and schedules the next coroutine that was waiting for this + * lock to be run. + */ +void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex); + +#endif diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index 2496a4f..a65be66 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -15,6 +15,7 @@ #ifndef QEMU_COROUTINE_H #define QEMU_COROUTINE_H +#include "qemu/coroutine-core.h" #include "qemu/queue.h" #include "qemu/timer.h" @@ -40,84 +41,6 @@ * it possible and in the meantime it serves as documentation. */ -typedef struct Coroutine Coroutine; - -/** - * Coroutine entry point - * - * When the coroutine is entered for the first time, opaque is passed in as an - * argument. - * - * When this function returns, the coroutine is destroyed automatically and - * execution continues in the caller who last entered the coroutine. - */ -typedef void coroutine_fn CoroutineEntry(void *opaque); - -/** - * Create a new coroutine - * - * Use qemu_coroutine_enter() to actually transfer control to the coroutine. - * The opaque argument is passed as the argument to the entry point. - */ -Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque); - -/** - * Transfer control to a coroutine - */ -void qemu_coroutine_enter(Coroutine *coroutine); - -/** - * Transfer control to a coroutine if it's not active (i.e. part of the call - * stack of the running coroutine). Otherwise, do nothing. - */ -void qemu_coroutine_enter_if_inactive(Coroutine *co); - -/** - * Transfer control to a coroutine and associate it with ctx - */ -void qemu_aio_coroutine_enter(AioContext *ctx, Coroutine *co); - -/** - * Transfer control back to a coroutine's caller - * - * This function does not return until the coroutine is re-entered using - * qemu_coroutine_enter(). - */ -void coroutine_fn qemu_coroutine_yield(void); - -/** - * Get the AioContext of the given coroutine - */ -AioContext *qemu_coroutine_get_aio_context(Coroutine *co); - -/** - * Get the currently executing coroutine - */ -Coroutine *qemu_coroutine_self(void); - -/** - * Return whether or not currently inside a coroutine - * - * This can be used to write functions that work both when in coroutine context - * and when not in coroutine context. Note that such functions cannot use the - * coroutine_fn annotation since they work outside coroutine context. - */ -bool qemu_in_coroutine(void); - -/** - * Return true if the coroutine is currently entered - * - * A coroutine is "entered" if it has not yielded from the current - * qemu_coroutine_enter() call used to run it. This does not mean that the - * coroutine is currently executing code since it may have transferred control - * to another coroutine using qemu_coroutine_enter(). - * - * When several coroutines enter each other there may be no way to know which - * ones have already been entered. In such situations this function can be - * used to avoid recursively entering coroutines. - */ -bool qemu_coroutine_entered(Coroutine *co); - /** * Provides a mutex that can be used to synchronise coroutines */ @@ -146,24 +69,6 @@ struct CoMutex { }; /** - * Initialises a CoMutex. This must be called before any other operation is used - * on the CoMutex. - */ -void qemu_co_mutex_init(CoMutex *mutex); - -/** - * Locks the mutex. If the lock cannot be taken immediately, control is - * transferred to the caller of the current coroutine. - */ -void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex); - -/** - * Unlocks the mutex and schedules the next coroutine that was waiting for this - * lock to be run. - */ -void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex); - -/** * Assert that the current coroutine holds @mutex. */ static inline coroutine_fn void qemu_co_mutex_assert_locked(CoMutex *mutex) diff --git a/include/qemu/lockable.h b/include/qemu/lockable.h index 86db7cb..9823220 100644 --- a/include/qemu/lockable.h +++ b/include/qemu/lockable.h @@ -13,7 +13,7 @@ #ifndef QEMU_LOCKABLE_H #define QEMU_LOCKABLE_H -#include "qemu/coroutine.h" +#include "qemu/coroutine-core.h" #include "qemu/thread.h" typedef void QemuLockUnlockFunc(void *); diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h index fba0487..c7c8a85 100644 --- a/include/qemu/typedefs.h +++ b/include/qemu/typedefs.h @@ -38,7 +38,6 @@ typedef struct BusState BusState; typedef struct Chardev Chardev; typedef struct Clock Clock; typedef struct CompatProperty CompatProperty; -typedef struct CoMutex CoMutex; typedef struct ConfidentialGuestSupport ConfidentialGuestSupport; typedef struct CPUAddressSpace CPUAddressSpace; typedef struct CPUArchState CPUArchState; -- cgit v1.1