Statistics
| Branch: | Revision:

root / qemu-coroutine.h @ e7c5e893

History | View | Annotate | Download (5 kB)

1 00dccaf1 Kevin Wolf
/*
2 00dccaf1 Kevin Wolf
 * QEMU coroutine implementation
3 00dccaf1 Kevin Wolf
 *
4 00dccaf1 Kevin Wolf
 * Copyright IBM, Corp. 2011
5 00dccaf1 Kevin Wolf
 *
6 00dccaf1 Kevin Wolf
 * Authors:
7 00dccaf1 Kevin Wolf
 *  Stefan Hajnoczi    <stefanha@linux.vnet.ibm.com>
8 b96e9247 Kevin Wolf
 *  Kevin Wolf         <kwolf@redhat.com>
9 00dccaf1 Kevin Wolf
 *
10 00dccaf1 Kevin Wolf
 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
11 00dccaf1 Kevin Wolf
 * See the COPYING.LIB file in the top-level directory.
12 00dccaf1 Kevin Wolf
 *
13 00dccaf1 Kevin Wolf
 */
14 00dccaf1 Kevin Wolf
15 00dccaf1 Kevin Wolf
#ifndef QEMU_COROUTINE_H
16 00dccaf1 Kevin Wolf
#define QEMU_COROUTINE_H
17 00dccaf1 Kevin Wolf
18 00dccaf1 Kevin Wolf
#include <stdbool.h>
19 b96e9247 Kevin Wolf
#include "qemu-queue.h"
20 00dccaf1 Kevin Wolf
21 00dccaf1 Kevin Wolf
/**
22 00dccaf1 Kevin Wolf
 * Coroutines are a mechanism for stack switching and can be used for
23 00dccaf1 Kevin Wolf
 * cooperative userspace threading.  These functions provide a simple but
24 00dccaf1 Kevin Wolf
 * useful flavor of coroutines that is suitable for writing sequential code,
25 00dccaf1 Kevin Wolf
 * rather than callbacks, for operations that need to give up control while
26 00dccaf1 Kevin Wolf
 * waiting for events to complete.
27 00dccaf1 Kevin Wolf
 *
28 00dccaf1 Kevin Wolf
 * These functions are re-entrant and may be used outside the global mutex.
29 00dccaf1 Kevin Wolf
 */
30 00dccaf1 Kevin Wolf
31 00dccaf1 Kevin Wolf
/**
32 00dccaf1 Kevin Wolf
 * Mark a function that executes in coroutine context
33 00dccaf1 Kevin Wolf
 *
34 00dccaf1 Kevin Wolf
 * Functions that execute in coroutine context cannot be called directly from
35 00dccaf1 Kevin Wolf
 * normal functions.  In the future it would be nice to enable compiler or
36 00dccaf1 Kevin Wolf
 * static checker support for catching such errors.  This annotation might make
37 00dccaf1 Kevin Wolf
 * it possible and in the meantime it serves as documentation.
38 00dccaf1 Kevin Wolf
 *
39 00dccaf1 Kevin Wolf
 * For example:
40 00dccaf1 Kevin Wolf
 *
41 00dccaf1 Kevin Wolf
 *   static void coroutine_fn foo(void) {
42 00dccaf1 Kevin Wolf
 *       ....
43 00dccaf1 Kevin Wolf
 *   }
44 00dccaf1 Kevin Wolf
 */
45 00dccaf1 Kevin Wolf
#define coroutine_fn
46 00dccaf1 Kevin Wolf
47 00dccaf1 Kevin Wolf
typedef struct Coroutine Coroutine;
48 00dccaf1 Kevin Wolf
49 00dccaf1 Kevin Wolf
/**
50 00dccaf1 Kevin Wolf
 * Coroutine entry point
51 00dccaf1 Kevin Wolf
 *
52 00dccaf1 Kevin Wolf
 * When the coroutine is entered for the first time, opaque is passed in as an
53 00dccaf1 Kevin Wolf
 * argument.
54 00dccaf1 Kevin Wolf
 *
55 00dccaf1 Kevin Wolf
 * When this function returns, the coroutine is destroyed automatically and
56 00dccaf1 Kevin Wolf
 * execution continues in the caller who last entered the coroutine.
57 00dccaf1 Kevin Wolf
 */
58 00dccaf1 Kevin Wolf
typedef void coroutine_fn CoroutineEntry(void *opaque);
59 00dccaf1 Kevin Wolf
60 00dccaf1 Kevin Wolf
/**
61 00dccaf1 Kevin Wolf
 * Create a new coroutine
62 00dccaf1 Kevin Wolf
 *
63 00dccaf1 Kevin Wolf
 * Use qemu_coroutine_enter() to actually transfer control to the coroutine.
64 00dccaf1 Kevin Wolf
 */
65 00dccaf1 Kevin Wolf
Coroutine *qemu_coroutine_create(CoroutineEntry *entry);
66 00dccaf1 Kevin Wolf
67 00dccaf1 Kevin Wolf
/**
68 00dccaf1 Kevin Wolf
 * Transfer control to a coroutine
69 00dccaf1 Kevin Wolf
 *
70 00dccaf1 Kevin Wolf
 * The opaque argument is passed as the argument to the entry point when
71 00dccaf1 Kevin Wolf
 * entering the coroutine for the first time.  It is subsequently ignored.
72 00dccaf1 Kevin Wolf
 */
73 00dccaf1 Kevin Wolf
void qemu_coroutine_enter(Coroutine *coroutine, void *opaque);
74 00dccaf1 Kevin Wolf
75 00dccaf1 Kevin Wolf
/**
76 00dccaf1 Kevin Wolf
 * Transfer control back to a coroutine's caller
77 00dccaf1 Kevin Wolf
 *
78 00dccaf1 Kevin Wolf
 * This function does not return until the coroutine is re-entered using
79 00dccaf1 Kevin Wolf
 * qemu_coroutine_enter().
80 00dccaf1 Kevin Wolf
 */
81 00dccaf1 Kevin Wolf
void coroutine_fn qemu_coroutine_yield(void);
82 00dccaf1 Kevin Wolf
83 00dccaf1 Kevin Wolf
/**
84 00dccaf1 Kevin Wolf
 * Get the currently executing coroutine
85 00dccaf1 Kevin Wolf
 */
86 00dccaf1 Kevin Wolf
Coroutine *coroutine_fn qemu_coroutine_self(void);
87 00dccaf1 Kevin Wolf
88 00dccaf1 Kevin Wolf
/**
89 00dccaf1 Kevin Wolf
 * Return whether or not currently inside a coroutine
90 00dccaf1 Kevin Wolf
 *
91 00dccaf1 Kevin Wolf
 * This can be used to write functions that work both when in coroutine context
92 00dccaf1 Kevin Wolf
 * and when not in coroutine context.  Note that such functions cannot use the
93 00dccaf1 Kevin Wolf
 * coroutine_fn annotation since they work outside coroutine context.
94 00dccaf1 Kevin Wolf
 */
95 00dccaf1 Kevin Wolf
bool qemu_in_coroutine(void);
96 00dccaf1 Kevin Wolf
97 b96e9247 Kevin Wolf
98 b96e9247 Kevin Wolf
99 b96e9247 Kevin Wolf
/**
100 b96e9247 Kevin Wolf
 * CoQueues are a mechanism to queue coroutines in order to continue executing
101 b96e9247 Kevin Wolf
 * them later. They provide the fundamental primitives on which coroutine locks
102 b96e9247 Kevin Wolf
 * are built.
103 b96e9247 Kevin Wolf
 */
104 b96e9247 Kevin Wolf
typedef struct CoQueue {
105 b96e9247 Kevin Wolf
    QTAILQ_HEAD(, Coroutine) entries;
106 b96e9247 Kevin Wolf
} CoQueue;
107 b96e9247 Kevin Wolf
108 b96e9247 Kevin Wolf
/**
109 b96e9247 Kevin Wolf
 * Initialise a CoQueue. This must be called before any other operation is used
110 b96e9247 Kevin Wolf
 * on the CoQueue.
111 b96e9247 Kevin Wolf
 */
112 b96e9247 Kevin Wolf
void qemu_co_queue_init(CoQueue *queue);
113 b96e9247 Kevin Wolf
114 b96e9247 Kevin Wolf
/**
115 b96e9247 Kevin Wolf
 * Adds the current coroutine to the CoQueue and transfers control to the
116 b96e9247 Kevin Wolf
 * caller of the coroutine.
117 b96e9247 Kevin Wolf
 */
118 b96e9247 Kevin Wolf
void coroutine_fn qemu_co_queue_wait(CoQueue *queue);
119 b96e9247 Kevin Wolf
120 b96e9247 Kevin Wolf
/**
121 b96e9247 Kevin Wolf
 * Restarts the next coroutine in the CoQueue and removes it from the queue.
122 b96e9247 Kevin Wolf
 *
123 b96e9247 Kevin Wolf
 * Returns true if a coroutine was restarted, false if the queue is empty.
124 b96e9247 Kevin Wolf
 */
125 b96e9247 Kevin Wolf
bool qemu_co_queue_next(CoQueue *queue);
126 b96e9247 Kevin Wolf
127 b96e9247 Kevin Wolf
/**
128 b96e9247 Kevin Wolf
 * Checks if the CoQueue is empty.
129 b96e9247 Kevin Wolf
 */
130 b96e9247 Kevin Wolf
bool qemu_co_queue_empty(CoQueue *queue);
131 b96e9247 Kevin Wolf
132 b96e9247 Kevin Wolf
133 b96e9247 Kevin Wolf
/**
134 b96e9247 Kevin Wolf
 * Provides a mutex that can be used to synchronise coroutines
135 b96e9247 Kevin Wolf
 */
136 b96e9247 Kevin Wolf
typedef struct CoMutex {
137 b96e9247 Kevin Wolf
    bool locked;
138 b96e9247 Kevin Wolf
    CoQueue queue;
139 b96e9247 Kevin Wolf
} CoMutex;
140 b96e9247 Kevin Wolf
141 b96e9247 Kevin Wolf
/**
142 b96e9247 Kevin Wolf
 * Initialises a CoMutex. This must be called before any other operation is used
143 b96e9247 Kevin Wolf
 * on the CoMutex.
144 b96e9247 Kevin Wolf
 */
145 b96e9247 Kevin Wolf
void qemu_co_mutex_init(CoMutex *mutex);
146 b96e9247 Kevin Wolf
147 b96e9247 Kevin Wolf
/**
148 b96e9247 Kevin Wolf
 * Locks the mutex. If the lock cannot be taken immediately, control is
149 b96e9247 Kevin Wolf
 * transferred to the caller of the current coroutine.
150 b96e9247 Kevin Wolf
 */
151 b96e9247 Kevin Wolf
void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex);
152 b96e9247 Kevin Wolf
153 b96e9247 Kevin Wolf
/**
154 b96e9247 Kevin Wolf
 * Unlocks the mutex and schedules the next coroutine that was waiting for this
155 b96e9247 Kevin Wolf
 * lock to be run.
156 b96e9247 Kevin Wolf
 */
157 b96e9247 Kevin Wolf
void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex);
158 b96e9247 Kevin Wolf
159 12888904 Aneesh Kumar K.V
typedef struct CoRwlock {
160 12888904 Aneesh Kumar K.V
    bool writer;
161 12888904 Aneesh Kumar K.V
    int reader;
162 12888904 Aneesh Kumar K.V
    CoQueue queue;
163 12888904 Aneesh Kumar K.V
} CoRwlock;
164 12888904 Aneesh Kumar K.V
165 12888904 Aneesh Kumar K.V
/**
166 12888904 Aneesh Kumar K.V
 * Initialises a CoRwlock. This must be called before any other operation
167 12888904 Aneesh Kumar K.V
 * is used on the CoRwlock
168 12888904 Aneesh Kumar K.V
 */
169 12888904 Aneesh Kumar K.V
void qemu_co_rwlock_init(CoRwlock *lock);
170 12888904 Aneesh Kumar K.V
171 12888904 Aneesh Kumar K.V
/**
172 12888904 Aneesh Kumar K.V
 * Read locks the CoRwlock. If the lock cannot be taken immediately because
173 12888904 Aneesh Kumar K.V
 * of a parallel writer, control is transferred to the caller of the current
174 12888904 Aneesh Kumar K.V
 * coroutine.
175 12888904 Aneesh Kumar K.V
 */
176 12888904 Aneesh Kumar K.V
void qemu_co_rwlock_rdlock(CoRwlock *lock);
177 12888904 Aneesh Kumar K.V
178 12888904 Aneesh Kumar K.V
/**
179 12888904 Aneesh Kumar K.V
 * Write Locks the mutex. If the lock cannot be taken immediately because
180 12888904 Aneesh Kumar K.V
 * of a parallel reader, control is transferred to the caller of the current
181 12888904 Aneesh Kumar K.V
 * coroutine.
182 12888904 Aneesh Kumar K.V
 */
183 12888904 Aneesh Kumar K.V
void qemu_co_rwlock_wrlock(CoRwlock *lock);
184 12888904 Aneesh Kumar K.V
185 12888904 Aneesh Kumar K.V
/**
186 12888904 Aneesh Kumar K.V
 * Unlocks the read/write lock and schedules the next coroutine that was
187 12888904 Aneesh Kumar K.V
 * waiting for this lock to be run.
188 12888904 Aneesh Kumar K.V
 */
189 12888904 Aneesh Kumar K.V
void qemu_co_rwlock_unlock(CoRwlock *lock);
190 12888904 Aneesh Kumar K.V
191 00dccaf1 Kevin Wolf
#endif /* QEMU_COROUTINE_H */