]> git.proxmox.com Git - qemu.git/blob - qemu-coroutine.c
block-migration: fix blk_mig_save_dirty_block() return value checking
[qemu.git] / qemu-coroutine.c
1 /*
2 * QEMU coroutines
3 *
4 * Copyright IBM, Corp. 2011
5 *
6 * Authors:
7 * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
8 * Kevin Wolf <kwolf@redhat.com>
9 *
10 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
11 * See the COPYING.LIB file in the top-level directory.
12 *
13 */
14
15 #include "trace.h"
16 #include "qemu-common.h"
17 #include "block/coroutine.h"
18 #include "block/coroutine_int.h"
19
20 Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
21 {
22 Coroutine *co = qemu_coroutine_new();
23 co->entry = entry;
24 return co;
25 }
26
27 static void coroutine_swap(Coroutine *from, Coroutine *to)
28 {
29 CoroutineAction ret;
30
31 ret = qemu_coroutine_switch(from, to, COROUTINE_YIELD);
32
33 switch (ret) {
34 case COROUTINE_YIELD:
35 return;
36 case COROUTINE_TERMINATE:
37 trace_qemu_coroutine_terminate(to);
38 qemu_coroutine_delete(to);
39 return;
40 default:
41 abort();
42 }
43 }
44
45 void qemu_coroutine_enter(Coroutine *co, void *opaque)
46 {
47 Coroutine *self = qemu_coroutine_self();
48
49 trace_qemu_coroutine_enter(self, co, opaque);
50
51 if (co->caller) {
52 fprintf(stderr, "Co-routine re-entered recursively\n");
53 abort();
54 }
55
56 co->caller = self;
57 co->entry_arg = opaque;
58 coroutine_swap(self, co);
59 }
60
61 void coroutine_fn qemu_coroutine_yield(void)
62 {
63 Coroutine *self = qemu_coroutine_self();
64 Coroutine *to = self->caller;
65
66 trace_qemu_coroutine_yield(self, to);
67
68 if (!to) {
69 fprintf(stderr, "Co-routine is yielding to no one\n");
70 abort();
71 }
72
73 self->caller = NULL;
74 coroutine_swap(self, to);
75 }