Statistics
| Branch: | Revision:

root / qemu-coroutine.h @ 2542bfd5

History | View | Annotate | Download (4.2 kB)

1
/*
2
 * QEMU coroutine implementation
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
#ifndef QEMU_COROUTINE_H
16
#define QEMU_COROUTINE_H
17

    
18
#include <stdbool.h>
19
#include "qemu-queue.h"
20

    
21
/**
22
 * Coroutines are a mechanism for stack switching and can be used for
23
 * cooperative userspace threading.  These functions provide a simple but
24
 * useful flavor of coroutines that is suitable for writing sequential code,
25
 * rather than callbacks, for operations that need to give up control while
26
 * waiting for events to complete.
27
 *
28
 * These functions are re-entrant and may be used outside the global mutex.
29
 */
30

    
31
/**
32
 * Mark a function that executes in coroutine context
33
 *
34
 * Functions that execute in coroutine context cannot be called directly from
35
 * normal functions.  In the future it would be nice to enable compiler or
36
 * static checker support for catching such errors.  This annotation might make
37
 * it possible and in the meantime it serves as documentation.
38
 *
39
 * For example:
40
 *
41
 *   static void coroutine_fn foo(void) {
42
 *       ....
43
 *   }
44
 */
45
#define coroutine_fn
46

    
47
typedef struct Coroutine Coroutine;
48

    
49
/**
50
 * Coroutine entry point
51
 *
52
 * When the coroutine is entered for the first time, opaque is passed in as an
53
 * argument.
54
 *
55
 * When this function returns, the coroutine is destroyed automatically and
56
 * execution continues in the caller who last entered the coroutine.
57
 */
58
typedef void coroutine_fn CoroutineEntry(void *opaque);
59

    
60
/**
61
 * Create a new coroutine
62
 *
63
 * Use qemu_coroutine_enter() to actually transfer control to the coroutine.
64
 */
65
Coroutine *qemu_coroutine_create(CoroutineEntry *entry);
66

    
67
/**
68
 * Transfer control to a coroutine
69
 *
70
 * The opaque argument is passed as the argument to the entry point when
71
 * entering the coroutine for the first time.  It is subsequently ignored.
72
 */
73
void qemu_coroutine_enter(Coroutine *coroutine, void *opaque);
74

    
75
/**
76
 * Transfer control back to a coroutine's caller
77
 *
78
 * This function does not return until the coroutine is re-entered using
79
 * qemu_coroutine_enter().
80
 */
81
void coroutine_fn qemu_coroutine_yield(void);
82

    
83
/**
84
 * Get the currently executing coroutine
85
 */
86
Coroutine *coroutine_fn qemu_coroutine_self(void);
87

    
88
/**
89
 * Return whether or not currently inside a coroutine
90
 *
91
 * This can be used to write functions that work both when in coroutine context
92
 * and when not in coroutine context.  Note that such functions cannot use the
93
 * coroutine_fn annotation since they work outside coroutine context.
94
 */
95
bool qemu_in_coroutine(void);
96

    
97

    
98

    
99
/**
100
 * CoQueues are a mechanism to queue coroutines in order to continue executing
101
 * them later. They provide the fundamental primitives on which coroutine locks
102
 * are built.
103
 */
104
typedef struct CoQueue {
105
    QTAILQ_HEAD(, Coroutine) entries;
106
} CoQueue;
107

    
108
/**
109
 * Initialise a CoQueue. This must be called before any other operation is used
110
 * on the CoQueue.
111
 */
112
void qemu_co_queue_init(CoQueue *queue);
113

    
114
/**
115
 * Adds the current coroutine to the CoQueue and transfers control to the
116
 * caller of the coroutine.
117
 */
118
void coroutine_fn qemu_co_queue_wait(CoQueue *queue);
119

    
120
/**
121
 * Restarts the next coroutine in the CoQueue and removes it from the queue.
122
 *
123
 * Returns true if a coroutine was restarted, false if the queue is empty.
124
 */
125
bool qemu_co_queue_next(CoQueue *queue);
126

    
127
/**
128
 * Checks if the CoQueue is empty.
129
 */
130
bool qemu_co_queue_empty(CoQueue *queue);
131

    
132

    
133
/**
134
 * Provides a mutex that can be used to synchronise coroutines
135
 */
136
typedef struct CoMutex {
137
    bool locked;
138
    CoQueue queue;
139
} CoMutex;
140

    
141
/**
142
 * Initialises a CoMutex. This must be called before any other operation is used
143
 * on the CoMutex.
144
 */
145
void qemu_co_mutex_init(CoMutex *mutex);
146

    
147
/**
148
 * Locks the mutex. If the lock cannot be taken immediately, control is
149
 * transferred to the caller of the current coroutine.
150
 */
151
void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex);
152

    
153
/**
154
 * Unlocks the mutex and schedules the next coroutine that was waiting for this
155
 * lock to be run.
156
 */
157
void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex);
158

    
159
#endif /* QEMU_COROUTINE_H */