Kevin Wolf | 00dccaf | 2011-01-17 16:08:14 +0000 | [diff] [blame^] | 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 */ |