[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 12/35] define magic macros for stackless coroutines
From: |
Paolo Bonzini |
Subject: |
[PATCH 12/35] define magic macros for stackless coroutines |
Date: |
Thu, 10 Mar 2022 13:43:50 +0100 |
Because conversion to stackless coroutines is incredibly repetitive,
define some magic variable-argument macros that simplify the task:
- CO_DECLARE_FRAME() declares a frame structure, with a couple common fields
and the extras coming from variable arguments
- CO_INIT_FRAME() allocates the frame structure, builds it using any arguments
provided by the user, and continues with the second part of the
awaitable function that takes the frame as its only argument
- CO_ARG() declare variables and load them from the frame structure. It
uses typeof() to avoid repetition of the type of the variable (it is needed
only twice, in CO_DECLARE_FRAME() and in the declaration of the user-visible
awaitable function)
- CO_DECLARE() also declares variables using typeof, but it's for locals that
are not prepared by CO_INIT_FRAME()
- CO_SAVE() and CO_LOAD() copy to and from the frame structure
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/qemu/coroutine.h | 41 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
index 2f2be6abfe..df148ff80e 100644
--- a/include/qemu/coroutine.h
+++ b/include/qemu/coroutine.h
@@ -361,4 +361,45 @@ void qemu_coroutine_decrease_pool_batch_size(unsigned int
additional_pool_size);
void *coroutine_only_fn stack_alloc(CoroutineImpl *func, size_t bytes);
CoroutineAction coroutine_only_fn stack_free(CoroutineFrame *f);
+
+#define CO_DO(MACRO, ...) CO_DO_(MACRO, __VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3,
2, 1, 0)
+#define CO_DO_(MACRO, a0, a1, a2, a3, a4, a5, a6, a7, a8 , a9, n, ...)
CO_DO##n(MACRO, a0, a1, a2, a3, a4, a5, a6, a7, a8 , a9)
+#define CO_DO0(MACRO, a0, ...)
+#define CO_DO1(MACRO, a0, ...) MACRO(a0)
+#define CO_DO2(MACRO, a0, ...) MACRO(a0); CO_DO1(MACRO, __VA_ARGS__)
+#define CO_DO3(MACRO, a0, ...) MACRO(a0); CO_DO2(MACRO, __VA_ARGS__)
+#define CO_DO4(MACRO, a0, ...) MACRO(a0); CO_DO3(MACRO, __VA_ARGS__)
+#define CO_DO5(MACRO, a0, ...) MACRO(a0); CO_DO4(MACRO, __VA_ARGS__)
+#define CO_DO6(MACRO, a0, ...) MACRO(a0); CO_DO5(MACRO, __VA_ARGS__)
+#define CO_DO7(MACRO, a0, ...) MACRO(a0); CO_DO6(MACRO, __VA_ARGS__)
+#define CO_DO8(MACRO, a0, ...) MACRO(a0); CO_DO7(MACRO, __VA_ARGS__)
+#define CO_DO9(MACRO, a0, ...) MACRO(a0); CO_DO8(MACRO, __VA_ARGS__)
+
+#define CO_FRAME1(decl) decl
+#define CO_SAVE1(var) _f->var = var
+#define CO_LOAD1(var) var = _f->var
+#define CO_DECLARE1(var) typeof(_f->var) var
+#define CO_ARG1(var) typeof(_f->var) var = _f->var
+
+#define CO_SAVE(...) CO_DO(CO_SAVE1, __VA_ARGS__)
+#define CO_LOAD(...) CO_DO(CO_LOAD1, __VA_ARGS__)
+#define CO_DECLARE(...) CO_DO(CO_DECLARE1, __VA_ARGS__)
+#define CO_ARG(...) CO_DO(CO_ARG1, __VA_ARGS__)
+
+#define CO_DECLARE_FRAME(func, ...) \
+ struct FRAME__##func { \
+ CoroutineFrame common; \
+ uint32_t _step; \
+ CO_DO(CO_FRAME1, __VA_ARGS__); \
+ }
+
+#define CO_INIT_FRAME(func, ...) \
+ co__##func(({ \
+ struct FRAME__##func *_f; \
+ _f = stack_alloc(co__##func, sizeof(*_f)); \
+ __VA_OPT__(CO_SAVE(__VA_ARGS__);) \
+ _f->_step = 0; \
+ _f; \
+ }))
+
#endif /* QEMU_COROUTINE_H */
--
2.35.1
- [PATCH 09/35] convert qemu-coroutine-sleep.c to stackless coroutines, (continued)
- [PATCH 09/35] convert qemu-coroutine-sleep.c to stackless coroutines, Paolo Bonzini, 2022/03/10
- [PATCH 02/35] coroutine: qemu_coroutine_get_aio_context is not a coroutine_fn, Paolo Bonzini, 2022/03/10
- [PATCH 04/35] coroutine: introduce coroutine_only_fn, Paolo Bonzini, 2022/03/10
- [PATCH 06/35] disable some code, Paolo Bonzini, 2022/03/10
- [PATCH 15/35] /basic/self, Paolo Bonzini, 2022/03/10
- [PATCH 03/35] coroutine: introduce QemuCoLockable, Paolo Bonzini, 2022/03/10
- [PATCH 18/35] /basic/order, Paolo Bonzini, 2022/03/10
- [PATCH 21/35] /perf/yield, Paolo Bonzini, 2022/03/10
- [PATCH 08/35] /basic/lifecycle, Paolo Bonzini, 2022/03/10
- [PATCH 10/35] enable tail call optimization of qemu_co_mutex_lock, Paolo Bonzini, 2022/03/10
- [PATCH 12/35] define magic macros for stackless coroutines,
Paolo Bonzini <=
- [PATCH 27/35] /locking/co-mutex/lockable, Paolo Bonzini, 2022/03/10
- [PATCH 16/35] /basic/entered, Paolo Bonzini, 2022/03/10
- [PATCH 30/35] qemu_co_rwlock_unlock, Paolo Bonzini, 2022/03/10
- [PATCH 32/35] qemu_co_rwlock_wrlock, Paolo Bonzini, 2022/03/10
- [PATCH 13/35] /basic/yield, Paolo Bonzini, 2022/03/10
- [PATCH 14/35] /basic/nesting, Paolo Bonzini, 2022/03/10
- [PATCH 19/35] /perf/lifecycle, Paolo Bonzini, 2022/03/10
- [PATCH 20/35] /perf/nesting, Paolo Bonzini, 2022/03/10
- [PATCH 25/35] /locking/co-mutex, Paolo Bonzini, 2022/03/10
- [PATCH 26/35] convert qemu_co_mutex_lock_slowpath to magic macros, Paolo Bonzini, 2022/03/10