]>
Commit | Line | Data |
---|---|---|
00dccaf1 KW |
1 | /* |
2 | * QEMU coroutine implementation | |
3 | * | |
4 | * Copyright IBM, Corp. 2011 | |
5 | * | |
6 | * Authors: | |
7 | * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> | |
8 | * | |
9 | * This work is licensed under the terms of the GNU LGPL, version 2 or later. | |
10 | * See the COPYING.LIB file in the top-level directory. | |
11 | * | |
12 | */ | |
13 | ||
14 | #ifndef QEMU_COROUTINE_H | |
15 | #define QEMU_COROUTINE_H | |
16 | ||
17 | #include <stdbool.h> | |
18 | ||
19 | /** | |
20 | * Coroutines are a mechanism for stack switching and can be used for | |
21 | * cooperative userspace threading. These functions provide a simple but | |
22 | * useful flavor of coroutines that is suitable for writing sequential code, | |
23 | * rather than callbacks, for operations that need to give up control while | |
24 | * waiting for events to complete. | |
25 | * | |
26 | * These functions are re-entrant and may be used outside the global mutex. | |
27 | */ | |
28 | ||
29 | /** | |
30 | * Mark a function that executes in coroutine context | |
31 | * | |
32 | * Functions that execute in coroutine context cannot be called directly from | |
33 | * normal functions. In the future it would be nice to enable compiler or | |
34 | * static checker support for catching such errors. This annotation might make | |
35 | * it possible and in the meantime it serves as documentation. | |
36 | * | |
37 | * For example: | |
38 | * | |
39 | * static void coroutine_fn foo(void) { | |
40 | * .... | |
41 | * } | |
42 | */ | |
43 | #define coroutine_fn | |
44 | ||
45 | typedef struct Coroutine Coroutine; | |
46 | ||
47 | /** | |
48 | * Coroutine entry point | |
49 | * | |
50 | * When the coroutine is entered for the first time, opaque is passed in as an | |
51 | * argument. | |
52 | * | |
53 | * When this function returns, the coroutine is destroyed automatically and | |
54 | * execution continues in the caller who last entered the coroutine. | |
55 | */ | |
56 | typedef void coroutine_fn CoroutineEntry(void *opaque); | |
57 | ||
58 | /** | |
59 | * Create a new coroutine | |
60 | * | |
61 | * Use qemu_coroutine_enter() to actually transfer control to the coroutine. | |
62 | */ | |
63 | Coroutine *qemu_coroutine_create(CoroutineEntry *entry); | |
64 | ||
65 | /** | |
66 | * Transfer control to a coroutine | |
67 | * | |
68 | * The opaque argument is passed as the argument to the entry point when | |
69 | * entering the coroutine for the first time. It is subsequently ignored. | |
70 | */ | |
71 | void qemu_coroutine_enter(Coroutine *coroutine, void *opaque); | |
72 | ||
73 | /** | |
74 | * Transfer control back to a coroutine's caller | |
75 | * | |
76 | * This function does not return until the coroutine is re-entered using | |
77 | * qemu_coroutine_enter(). | |
78 | */ | |
79 | void coroutine_fn qemu_coroutine_yield(void); | |
80 | ||
81 | /** | |
82 | * Get the currently executing coroutine | |
83 | */ | |
84 | Coroutine *coroutine_fn qemu_coroutine_self(void); | |
85 | ||
86 | /** | |
87 | * Return whether or not currently inside a coroutine | |
88 | * | |
89 | * This can be used to write functions that work both when in coroutine context | |
90 | * and when not in coroutine context. Note that such functions cannot use the | |
91 | * coroutine_fn annotation since they work outside coroutine context. | |
92 | */ | |
93 | bool qemu_in_coroutine(void); | |
94 | ||
95 | #endif /* QEMU_COROUTINE_H */ |