Revision 4f999d05

b/Makefile.target
154 154
# System emulator target
155 155
ifdef CONFIG_SOFTMMU
156 156

  
157
obj-y = vl.o monitor.o pci.o machine.o gdbstub.o
157
obj-y = vl.o async.o monitor.o pci.o machine.o gdbstub.o
158 158
# virtio has to be here due to weird dependency between PCI and virtio-net.
159 159
# need to fix this properly
160 160
obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o virtio-pci.o
b/async.c
1
/*
2
 * QEMU System Emulator
3
 *
4
 * Copyright (c) 2003-2008 Fabrice Bellard
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

  
25
#include "qemu-common.h"
26

  
27
/***********************************************************/
28
/* bottom halves (can be seen as timers which expire ASAP) */
29

  
30
struct QEMUBH {
31
    QEMUBHFunc *cb;
32
    void *opaque;
33
    int scheduled;
34
    int idle;
35
    int deleted;
36
    QEMUBH *next;
37
};
38

  
39
static QEMUBH *first_bh = NULL;
40

  
41
QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
42
{
43
    QEMUBH *bh;
44
    bh = qemu_mallocz(sizeof(QEMUBH));
45
    bh->cb = cb;
46
    bh->opaque = opaque;
47
    bh->next = first_bh;
48
    first_bh = bh;
49
    return bh;
50
}
51

  
52
int qemu_bh_poll(void)
53
{
54
    QEMUBH *bh, **bhp;
55
    int ret;
56

  
57
    ret = 0;
58
    for (bh = first_bh; bh; bh = bh->next) {
59
        if (!bh->deleted && bh->scheduled) {
60
            bh->scheduled = 0;
61
            if (!bh->idle)
62
                ret = 1;
63
            bh->idle = 0;
64
            bh->cb(bh->opaque);
65
        }
66
    }
67

  
68
    /* remove deleted bhs */
69
    bhp = &first_bh;
70
    while (*bhp) {
71
        bh = *bhp;
72
        if (bh->deleted) {
73
            *bhp = bh->next;
74
            qemu_free(bh);
75
        } else
76
            bhp = &bh->next;
77
    }
78

  
79
    return ret;
80
}
81

  
82
void qemu_bh_schedule_idle(QEMUBH *bh)
83
{
84
    if (bh->scheduled)
85
        return;
86
    bh->scheduled = 1;
87
    bh->idle = 1;
88
}
89

  
90
void qemu_bh_schedule(QEMUBH *bh)
91
{
92
    if (bh->scheduled)
93
        return;
94
    bh->scheduled = 1;
95
    bh->idle = 0;
96
    /* stop the currently executing CPU to execute the BH ASAP */
97
    qemu_notify_event();
98
}
99

  
100
void qemu_bh_cancel(QEMUBH *bh)
101
{
102
    bh->scheduled = 0;
103
}
104

  
105
void qemu_bh_delete(QEMUBH *bh)
106
{
107
    bh->scheduled = 0;
108
    bh->deleted = 1;
109
}
110

  
111
void qemu_bh_update_timeout(int *timeout)
112
{
113
    QEMUBH *bh;
114

  
115
    for (bh = first_bh; bh; bh = bh->next) {
116
        if (!bh->deleted && bh->scheduled) {
117
            if (bh->idle) {
118
                /* idle bottom halves will be polled at least
119
                 * every 10ms */
120
                *timeout = MIN(10, *timeout);
121
            } else {
122
                /* non-idle bottom halves will be executed
123
                 * immediately */
124
                *timeout = 0;
125
                break;
126
            }
127
        }
128
    }
129
}
130

  
b/qemu-common.h
105 105
void qemu_bh_cancel(QEMUBH *bh);
106 106
void qemu_bh_delete(QEMUBH *bh);
107 107
int qemu_bh_poll(void);
108
void qemu_bh_update_timeout(int *timeout);
108 109

  
109 110
uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
110 111

  
b/vl.c
3081 3081
}
3082 3082

  
3083 3083
/***********************************************************/
3084
/* bottom halves (can be seen as timers which expire ASAP) */
3085

  
3086
struct QEMUBH {
3087
    QEMUBHFunc *cb;
3088
    void *opaque;
3089
    int scheduled;
3090
    int idle;
3091
    int deleted;
3092
    QEMUBH *next;
3093
};
3094

  
3095
static QEMUBH *first_bh = NULL;
3096

  
3097
QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque)
3098
{
3099
    QEMUBH *bh;
3100
    bh = qemu_mallocz(sizeof(QEMUBH));
3101
    bh->cb = cb;
3102
    bh->opaque = opaque;
3103
    bh->next = first_bh;
3104
    first_bh = bh;
3105
    return bh;
3106
}
3107

  
3108
int qemu_bh_poll(void)
3109
{
3110
    QEMUBH *bh, **bhp;
3111
    int ret;
3112

  
3113
    ret = 0;
3114
    for (bh = first_bh; bh; bh = bh->next) {
3115
        if (!bh->deleted && bh->scheduled) {
3116
            bh->scheduled = 0;
3117
            if (!bh->idle)
3118
                ret = 1;
3119
            bh->idle = 0;
3120
            bh->cb(bh->opaque);
3121
        }
3122
    }
3123

  
3124
    /* remove deleted bhs */
3125
    bhp = &first_bh;
3126
    while (*bhp) {
3127
        bh = *bhp;
3128
        if (bh->deleted) {
3129
            *bhp = bh->next;
3130
            qemu_free(bh);
3131
        } else
3132
            bhp = &bh->next;
3133
    }
3134

  
3135
    return ret;
3136
}
3137

  
3138
void qemu_bh_schedule_idle(QEMUBH *bh)
3139
{
3140
    if (bh->scheduled)
3141
        return;
3142
    bh->scheduled = 1;
3143
    bh->idle = 1;
3144
}
3145

  
3146
void qemu_bh_schedule(QEMUBH *bh)
3147
{
3148
    if (bh->scheduled)
3149
        return;
3150
    bh->scheduled = 1;
3151
    bh->idle = 0;
3152
    /* stop the currently executing CPU to execute the BH ASAP */
3153
    qemu_notify_event();
3154
}
3155

  
3156
void qemu_bh_cancel(QEMUBH *bh)
3157
{
3158
    bh->scheduled = 0;
3159
}
3160

  
3161
void qemu_bh_delete(QEMUBH *bh)
3162
{
3163
    bh->scheduled = 0;
3164
    bh->deleted = 1;
3165
}
3166

  
3167
static void qemu_bh_update_timeout(int *timeout)
3168
{
3169
    QEMUBH *bh;
3170

  
3171
    for (bh = first_bh; bh; bh = bh->next) {
3172
        if (!bh->deleted && bh->scheduled) {
3173
            if (bh->idle) {
3174
                /* idle bottom halves will be polled at least
3175
                 * every 10ms */
3176
                *timeout = MIN(10, *timeout);
3177
            } else {
3178
                /* non-idle bottom halves will be executed
3179
                 * immediately */
3180
                *timeout = 0;
3181
                break;
3182
            }
3183
        }
3184
    }
3185
}
3186

  
3187
/***********************************************************/
3188 3084
/* machine registration */
3189 3085

  
3190 3086
static QEMUMachine *first_machine = NULL;

Also available in: Unified diff