Statistics
| Branch: | Revision:

root / qemu-coroutine.c @ 992aeb8e

History | View | Annotate | Download (1.6 kB)

1 00dccaf1 Kevin Wolf
/*
2 00dccaf1 Kevin Wolf
 * QEMU coroutines
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 00dccaf1 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
#include "trace.h"
16 00dccaf1 Kevin Wolf
#include "qemu-common.h"
17 737e150e Paolo Bonzini
#include "block/coroutine.h"
18 737e150e Paolo Bonzini
#include "block/coroutine_int.h"
19 00dccaf1 Kevin Wolf
20 00dccaf1 Kevin Wolf
Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
21 00dccaf1 Kevin Wolf
{
22 00dccaf1 Kevin Wolf
    Coroutine *co = qemu_coroutine_new();
23 00dccaf1 Kevin Wolf
    co->entry = entry;
24 00dccaf1 Kevin Wolf
    return co;
25 00dccaf1 Kevin Wolf
}
26 00dccaf1 Kevin Wolf
27 00dccaf1 Kevin Wolf
static void coroutine_swap(Coroutine *from, Coroutine *to)
28 00dccaf1 Kevin Wolf
{
29 00dccaf1 Kevin Wolf
    CoroutineAction ret;
30 00dccaf1 Kevin Wolf
31 00dccaf1 Kevin Wolf
    ret = qemu_coroutine_switch(from, to, COROUTINE_YIELD);
32 00dccaf1 Kevin Wolf
33 00dccaf1 Kevin Wolf
    switch (ret) {
34 00dccaf1 Kevin Wolf
    case COROUTINE_YIELD:
35 00dccaf1 Kevin Wolf
        return;
36 00dccaf1 Kevin Wolf
    case COROUTINE_TERMINATE:
37 00dccaf1 Kevin Wolf
        trace_qemu_coroutine_terminate(to);
38 00dccaf1 Kevin Wolf
        qemu_coroutine_delete(to);
39 00dccaf1 Kevin Wolf
        return;
40 00dccaf1 Kevin Wolf
    default:
41 00dccaf1 Kevin Wolf
        abort();
42 00dccaf1 Kevin Wolf
    }
43 00dccaf1 Kevin Wolf
}
44 00dccaf1 Kevin Wolf
45 00dccaf1 Kevin Wolf
void qemu_coroutine_enter(Coroutine *co, void *opaque)
46 00dccaf1 Kevin Wolf
{
47 00dccaf1 Kevin Wolf
    Coroutine *self = qemu_coroutine_self();
48 00dccaf1 Kevin Wolf
49 00dccaf1 Kevin Wolf
    trace_qemu_coroutine_enter(self, co, opaque);
50 00dccaf1 Kevin Wolf
51 00dccaf1 Kevin Wolf
    if (co->caller) {
52 00dccaf1 Kevin Wolf
        fprintf(stderr, "Co-routine re-entered recursively\n");
53 00dccaf1 Kevin Wolf
        abort();
54 00dccaf1 Kevin Wolf
    }
55 00dccaf1 Kevin Wolf
56 00dccaf1 Kevin Wolf
    co->caller = self;
57 00dccaf1 Kevin Wolf
    co->entry_arg = opaque;
58 00dccaf1 Kevin Wolf
    coroutine_swap(self, co);
59 00dccaf1 Kevin Wolf
}
60 00dccaf1 Kevin Wolf
61 00dccaf1 Kevin Wolf
void coroutine_fn qemu_coroutine_yield(void)
62 00dccaf1 Kevin Wolf
{
63 00dccaf1 Kevin Wolf
    Coroutine *self = qemu_coroutine_self();
64 00dccaf1 Kevin Wolf
    Coroutine *to = self->caller;
65 00dccaf1 Kevin Wolf
66 00dccaf1 Kevin Wolf
    trace_qemu_coroutine_yield(self, to);
67 00dccaf1 Kevin Wolf
68 00dccaf1 Kevin Wolf
    if (!to) {
69 00dccaf1 Kevin Wolf
        fprintf(stderr, "Co-routine is yielding to no one\n");
70 00dccaf1 Kevin Wolf
        abort();
71 00dccaf1 Kevin Wolf
    }
72 00dccaf1 Kevin Wolf
73 00dccaf1 Kevin Wolf
    self->caller = NULL;
74 00dccaf1 Kevin Wolf
    coroutine_swap(self, to);
75 00dccaf1 Kevin Wolf
}