Statistics
| Branch: | Revision:

root / qemu-coroutine.h @ 4d5b97da

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