root / async.c @ ff667e2e
History | View | Annotate | Download (5 kB)
1 | 4f999d05 | Kevin Wolf | /*
|
---|---|---|---|
2 | 4f999d05 | Kevin Wolf | * QEMU System Emulator
|
3 | 4f999d05 | Kevin Wolf | *
|
4 | 4f999d05 | Kevin Wolf | * Copyright (c) 2003-2008 Fabrice Bellard
|
5 | 4f999d05 | Kevin Wolf | *
|
6 | 4f999d05 | Kevin Wolf | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 | 4f999d05 | Kevin Wolf | * of this software and associated documentation files (the "Software"), to deal
|
8 | 4f999d05 | Kevin Wolf | * in the Software without restriction, including without limitation the rights
|
9 | 4f999d05 | Kevin Wolf | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10 | 4f999d05 | Kevin Wolf | * copies of the Software, and to permit persons to whom the Software is
|
11 | 4f999d05 | Kevin Wolf | * furnished to do so, subject to the following conditions:
|
12 | 4f999d05 | Kevin Wolf | *
|
13 | 4f999d05 | Kevin Wolf | * The above copyright notice and this permission notice shall be included in
|
14 | 4f999d05 | Kevin Wolf | * all copies or substantial portions of the Software.
|
15 | 4f999d05 | Kevin Wolf | *
|
16 | 4f999d05 | Kevin Wolf | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 | 4f999d05 | Kevin Wolf | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 | 4f999d05 | Kevin Wolf | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
19 | 4f999d05 | Kevin Wolf | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 | 4f999d05 | Kevin Wolf | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 | 4f999d05 | Kevin Wolf | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 | 4f999d05 | Kevin Wolf | * THE SOFTWARE.
|
23 | 4f999d05 | Kevin Wolf | */
|
24 | 4f999d05 | Kevin Wolf | |
25 | 4f999d05 | Kevin Wolf | #include "qemu-common.h" |
26 | 737e150e | Paolo Bonzini | #include "block/aio.h" |
27 | 1de7afc9 | Paolo Bonzini | #include "qemu/main-loop.h" |
28 | 9a1e9481 | Kevin Wolf | |
29 | 4f999d05 | Kevin Wolf | /***********************************************************/
|
30 | 4f999d05 | Kevin Wolf | /* bottom halves (can be seen as timers which expire ASAP) */
|
31 | 4f999d05 | Kevin Wolf | |
32 | 4f999d05 | Kevin Wolf | struct QEMUBH {
|
33 | 2f4dc3c1 | Paolo Bonzini | AioContext *ctx; |
34 | 4f999d05 | Kevin Wolf | QEMUBHFunc *cb; |
35 | 4f999d05 | Kevin Wolf | void *opaque;
|
36 | 4f999d05 | Kevin Wolf | QEMUBH *next; |
37 | 9b47b17e | Stefan Weil | bool scheduled;
|
38 | 9b47b17e | Stefan Weil | bool idle;
|
39 | 9b47b17e | Stefan Weil | bool deleted;
|
40 | 4f999d05 | Kevin Wolf | }; |
41 | 4f999d05 | Kevin Wolf | |
42 | f627aab1 | Paolo Bonzini | QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
|
43 | 4f999d05 | Kevin Wolf | { |
44 | 4f999d05 | Kevin Wolf | QEMUBH *bh; |
45 | 7267c094 | Anthony Liguori | bh = g_malloc0(sizeof(QEMUBH));
|
46 | 2f4dc3c1 | Paolo Bonzini | bh->ctx = ctx; |
47 | 4f999d05 | Kevin Wolf | bh->cb = cb; |
48 | 4f999d05 | Kevin Wolf | bh->opaque = opaque; |
49 | f627aab1 | Paolo Bonzini | bh->next = ctx->first_bh; |
50 | f627aab1 | Paolo Bonzini | ctx->first_bh = bh; |
51 | 4f999d05 | Kevin Wolf | return bh;
|
52 | 4f999d05 | Kevin Wolf | } |
53 | 4f999d05 | Kevin Wolf | |
54 | f627aab1 | Paolo Bonzini | int aio_bh_poll(AioContext *ctx)
|
55 | 4f999d05 | Kevin Wolf | { |
56 | 7887f620 | Kevin Wolf | QEMUBH *bh, **bhp, *next; |
57 | 4f999d05 | Kevin Wolf | int ret;
|
58 | 648fb0ea | Kevin Wolf | |
59 | f627aab1 | Paolo Bonzini | ctx->walking_bh++; |
60 | 4f999d05 | Kevin Wolf | |
61 | 4f999d05 | Kevin Wolf | ret = 0;
|
62 | f627aab1 | Paolo Bonzini | for (bh = ctx->first_bh; bh; bh = next) {
|
63 | 7887f620 | Kevin Wolf | next = bh->next; |
64 | 4f999d05 | Kevin Wolf | if (!bh->deleted && bh->scheduled) {
|
65 | 4f999d05 | Kevin Wolf | bh->scheduled = 0;
|
66 | 4f999d05 | Kevin Wolf | if (!bh->idle)
|
67 | 4f999d05 | Kevin Wolf | ret = 1;
|
68 | 4f999d05 | Kevin Wolf | bh->idle = 0;
|
69 | 4f999d05 | Kevin Wolf | bh->cb(bh->opaque); |
70 | 4f999d05 | Kevin Wolf | } |
71 | 4f999d05 | Kevin Wolf | } |
72 | 4f999d05 | Kevin Wolf | |
73 | f627aab1 | Paolo Bonzini | ctx->walking_bh--; |
74 | 648fb0ea | Kevin Wolf | |
75 | 4f999d05 | Kevin Wolf | /* remove deleted bhs */
|
76 | f627aab1 | Paolo Bonzini | if (!ctx->walking_bh) {
|
77 | f627aab1 | Paolo Bonzini | bhp = &ctx->first_bh; |
78 | 648fb0ea | Kevin Wolf | while (*bhp) {
|
79 | 648fb0ea | Kevin Wolf | bh = *bhp; |
80 | 648fb0ea | Kevin Wolf | if (bh->deleted) {
|
81 | 648fb0ea | Kevin Wolf | *bhp = bh->next; |
82 | 648fb0ea | Kevin Wolf | g_free(bh); |
83 | 648fb0ea | Kevin Wolf | } else {
|
84 | 648fb0ea | Kevin Wolf | bhp = &bh->next; |
85 | 648fb0ea | Kevin Wolf | } |
86 | 648fb0ea | Kevin Wolf | } |
87 | 4f999d05 | Kevin Wolf | } |
88 | 4f999d05 | Kevin Wolf | |
89 | 4f999d05 | Kevin Wolf | return ret;
|
90 | 4f999d05 | Kevin Wolf | } |
91 | 4f999d05 | Kevin Wolf | |
92 | 4f999d05 | Kevin Wolf | void qemu_bh_schedule_idle(QEMUBH *bh)
|
93 | 4f999d05 | Kevin Wolf | { |
94 | 4f999d05 | Kevin Wolf | if (bh->scheduled)
|
95 | 4f999d05 | Kevin Wolf | return;
|
96 | 4f999d05 | Kevin Wolf | bh->scheduled = 1;
|
97 | 4f999d05 | Kevin Wolf | bh->idle = 1;
|
98 | 4f999d05 | Kevin Wolf | } |
99 | 4f999d05 | Kevin Wolf | |
100 | 4f999d05 | Kevin Wolf | void qemu_bh_schedule(QEMUBH *bh)
|
101 | 4f999d05 | Kevin Wolf | { |
102 | 4f999d05 | Kevin Wolf | if (bh->scheduled)
|
103 | 4f999d05 | Kevin Wolf | return;
|
104 | 4f999d05 | Kevin Wolf | bh->scheduled = 1;
|
105 | 4f999d05 | Kevin Wolf | bh->idle = 0;
|
106 | 2f4dc3c1 | Paolo Bonzini | aio_notify(bh->ctx); |
107 | 4f999d05 | Kevin Wolf | } |
108 | 4f999d05 | Kevin Wolf | |
109 | 4f999d05 | Kevin Wolf | void qemu_bh_cancel(QEMUBH *bh)
|
110 | 4f999d05 | Kevin Wolf | { |
111 | 4f999d05 | Kevin Wolf | bh->scheduled = 0;
|
112 | 4f999d05 | Kevin Wolf | } |
113 | 4f999d05 | Kevin Wolf | |
114 | 4f999d05 | Kevin Wolf | void qemu_bh_delete(QEMUBH *bh)
|
115 | 4f999d05 | Kevin Wolf | { |
116 | 4f999d05 | Kevin Wolf | bh->scheduled = 0;
|
117 | 4f999d05 | Kevin Wolf | bh->deleted = 1;
|
118 | 4f999d05 | Kevin Wolf | } |
119 | 4f999d05 | Kevin Wolf | |
120 | 22bfa75e | Paolo Bonzini | static gboolean
|
121 | 22bfa75e | Paolo Bonzini | aio_ctx_prepare(GSource *source, gint *timeout) |
122 | 4f999d05 | Kevin Wolf | { |
123 | 22bfa75e | Paolo Bonzini | AioContext *ctx = (AioContext *) source; |
124 | 4f999d05 | Kevin Wolf | QEMUBH *bh; |
125 | 4f999d05 | Kevin Wolf | |
126 | f627aab1 | Paolo Bonzini | for (bh = ctx->first_bh; bh; bh = bh->next) {
|
127 | 4f999d05 | Kevin Wolf | if (!bh->deleted && bh->scheduled) {
|
128 | 4f999d05 | Kevin Wolf | if (bh->idle) {
|
129 | 4f999d05 | Kevin Wolf | /* idle bottom halves will be polled at least
|
130 | 4f999d05 | Kevin Wolf | * every 10ms */
|
131 | 22bfa75e | Paolo Bonzini | *timeout = 10;
|
132 | 4f999d05 | Kevin Wolf | } else {
|
133 | 4f999d05 | Kevin Wolf | /* non-idle bottom halves will be executed
|
134 | 4f999d05 | Kevin Wolf | * immediately */
|
135 | 4f999d05 | Kevin Wolf | *timeout = 0;
|
136 | f5022a13 | Paolo Bonzini | return true; |
137 | 4f999d05 | Kevin Wolf | } |
138 | 4f999d05 | Kevin Wolf | } |
139 | 4f999d05 | Kevin Wolf | } |
140 | e3713e00 | Paolo Bonzini | |
141 | f5022a13 | Paolo Bonzini | return false; |
142 | e3713e00 | Paolo Bonzini | } |
143 | e3713e00 | Paolo Bonzini | |
144 | e3713e00 | Paolo Bonzini | static gboolean
|
145 | e3713e00 | Paolo Bonzini | aio_ctx_check(GSource *source) |
146 | e3713e00 | Paolo Bonzini | { |
147 | e3713e00 | Paolo Bonzini | AioContext *ctx = (AioContext *) source; |
148 | e3713e00 | Paolo Bonzini | QEMUBH *bh; |
149 | e3713e00 | Paolo Bonzini | |
150 | e3713e00 | Paolo Bonzini | for (bh = ctx->first_bh; bh; bh = bh->next) {
|
151 | e3713e00 | Paolo Bonzini | if (!bh->deleted && bh->scheduled) {
|
152 | e3713e00 | Paolo Bonzini | return true; |
153 | e3713e00 | Paolo Bonzini | } |
154 | e3713e00 | Paolo Bonzini | } |
155 | e3713e00 | Paolo Bonzini | return aio_pending(ctx);
|
156 | e3713e00 | Paolo Bonzini | } |
157 | e3713e00 | Paolo Bonzini | |
158 | e3713e00 | Paolo Bonzini | static gboolean
|
159 | e3713e00 | Paolo Bonzini | aio_ctx_dispatch(GSource *source, |
160 | e3713e00 | Paolo Bonzini | GSourceFunc callback, |
161 | e3713e00 | Paolo Bonzini | gpointer user_data) |
162 | e3713e00 | Paolo Bonzini | { |
163 | e3713e00 | Paolo Bonzini | AioContext *ctx = (AioContext *) source; |
164 | e3713e00 | Paolo Bonzini | |
165 | e3713e00 | Paolo Bonzini | assert(callback == NULL);
|
166 | e3713e00 | Paolo Bonzini | aio_poll(ctx, false);
|
167 | e3713e00 | Paolo Bonzini | return true; |
168 | e3713e00 | Paolo Bonzini | } |
169 | e3713e00 | Paolo Bonzini | |
170 | 2f4dc3c1 | Paolo Bonzini | static void |
171 | 2f4dc3c1 | Paolo Bonzini | aio_ctx_finalize(GSource *source) |
172 | 2f4dc3c1 | Paolo Bonzini | { |
173 | 2f4dc3c1 | Paolo Bonzini | AioContext *ctx = (AioContext *) source; |
174 | 2f4dc3c1 | Paolo Bonzini | |
175 | 2f4dc3c1 | Paolo Bonzini | aio_set_event_notifier(ctx, &ctx->notifier, NULL, NULL); |
176 | 2f4dc3c1 | Paolo Bonzini | event_notifier_cleanup(&ctx->notifier); |
177 | 2f4dc3c1 | Paolo Bonzini | } |
178 | 2f4dc3c1 | Paolo Bonzini | |
179 | e3713e00 | Paolo Bonzini | static GSourceFuncs aio_source_funcs = {
|
180 | e3713e00 | Paolo Bonzini | aio_ctx_prepare, |
181 | e3713e00 | Paolo Bonzini | aio_ctx_check, |
182 | e3713e00 | Paolo Bonzini | aio_ctx_dispatch, |
183 | 2f4dc3c1 | Paolo Bonzini | aio_ctx_finalize |
184 | e3713e00 | Paolo Bonzini | }; |
185 | e3713e00 | Paolo Bonzini | |
186 | e3713e00 | Paolo Bonzini | GSource *aio_get_g_source(AioContext *ctx) |
187 | e3713e00 | Paolo Bonzini | { |
188 | e3713e00 | Paolo Bonzini | g_source_ref(&ctx->source); |
189 | e3713e00 | Paolo Bonzini | return &ctx->source;
|
190 | e3713e00 | Paolo Bonzini | } |
191 | a915f4bc | Paolo Bonzini | |
192 | 2f4dc3c1 | Paolo Bonzini | void aio_notify(AioContext *ctx)
|
193 | 2f4dc3c1 | Paolo Bonzini | { |
194 | 2f4dc3c1 | Paolo Bonzini | event_notifier_set(&ctx->notifier); |
195 | 2f4dc3c1 | Paolo Bonzini | } |
196 | 2f4dc3c1 | Paolo Bonzini | |
197 | f627aab1 | Paolo Bonzini | AioContext *aio_context_new(void)
|
198 | f627aab1 | Paolo Bonzini | { |
199 | 2f4dc3c1 | Paolo Bonzini | AioContext *ctx; |
200 | 2f4dc3c1 | Paolo Bonzini | ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext));
|
201 | 2f4dc3c1 | Paolo Bonzini | event_notifier_init(&ctx->notifier, false);
|
202 | 2f4dc3c1 | Paolo Bonzini | aio_set_event_notifier(ctx, &ctx->notifier, |
203 | 2f4dc3c1 | Paolo Bonzini | (EventNotifierHandler *) |
204 | 2f4dc3c1 | Paolo Bonzini | event_notifier_test_and_clear, NULL);
|
205 | 2f4dc3c1 | Paolo Bonzini | |
206 | 2f4dc3c1 | Paolo Bonzini | return ctx;
|
207 | e3713e00 | Paolo Bonzini | } |
208 | e3713e00 | Paolo Bonzini | |
209 | e3713e00 | Paolo Bonzini | void aio_context_ref(AioContext *ctx)
|
210 | e3713e00 | Paolo Bonzini | { |
211 | e3713e00 | Paolo Bonzini | g_source_ref(&ctx->source); |
212 | e3713e00 | Paolo Bonzini | } |
213 | e3713e00 | Paolo Bonzini | |
214 | e3713e00 | Paolo Bonzini | void aio_context_unref(AioContext *ctx)
|
215 | e3713e00 | Paolo Bonzini | { |
216 | e3713e00 | Paolo Bonzini | g_source_unref(&ctx->source); |
217 | f627aab1 | Paolo Bonzini | } |