diff --git a/Makefile.target b/Makefile.target index 1d6bad8d09..fefd7acd6e 100644 --- a/Makefile.target +++ b/Makefile.target @@ -154,7 +154,7 @@ endif #CONFIG_BSD_USER # System emulator target ifdef CONFIG_SOFTMMU -obj-y = vl.o monitor.o pci.o machine.o gdbstub.o +obj-y = vl.o async.o monitor.o pci.o machine.o gdbstub.o # virtio has to be here due to weird dependency between PCI and virtio-net. # need to fix this properly obj-y += virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o virtio-pci.o diff --git a/async.c b/async.c new file mode 100644 index 0000000000..60c1cb37da --- /dev/null +++ b/async.c @@ -0,0 +1,130 @@ +/* + * QEMU System Emulator + * + * Copyright (c) 2003-2008 Fabrice Bellard + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu-common.h" + +/***********************************************************/ +/* bottom halves (can be seen as timers which expire ASAP) */ + +struct QEMUBH { + QEMUBHFunc *cb; + void *opaque; + int scheduled; + int idle; + int deleted; + QEMUBH *next; +}; + +static QEMUBH *first_bh = NULL; + +QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque) +{ + QEMUBH *bh; + bh = qemu_mallocz(sizeof(QEMUBH)); + bh->cb = cb; + bh->opaque = opaque; + bh->next = first_bh; + first_bh = bh; + return bh; +} + +int qemu_bh_poll(void) +{ + QEMUBH *bh, **bhp; + int ret; + + ret = 0; + for (bh = first_bh; bh; bh = bh->next) { + if (!bh->deleted && bh->scheduled) { + bh->scheduled = 0; + if (!bh->idle) + ret = 1; + bh->idle = 0; + bh->cb(bh->opaque); + } + } + + /* remove deleted bhs */ + bhp = &first_bh; + while (*bhp) { + bh = *bhp; + if (bh->deleted) { + *bhp = bh->next; + qemu_free(bh); + } else + bhp = &bh->next; + } + + return ret; +} + +void qemu_bh_schedule_idle(QEMUBH *bh) +{ + if (bh->scheduled) + return; + bh->scheduled = 1; + bh->idle = 1; +} + +void qemu_bh_schedule(QEMUBH *bh) +{ + if (bh->scheduled) + return; + bh->scheduled = 1; + bh->idle = 0; + /* stop the currently executing CPU to execute the BH ASAP */ + qemu_notify_event(); +} + +void qemu_bh_cancel(QEMUBH *bh) +{ + bh->scheduled = 0; +} + +void qemu_bh_delete(QEMUBH *bh) +{ + bh->scheduled = 0; + bh->deleted = 1; +} + +void qemu_bh_update_timeout(int *timeout) +{ + QEMUBH *bh; + + for (bh = first_bh; bh; bh = bh->next) { + if (!bh->deleted && bh->scheduled) { + if (bh->idle) { + /* idle bottom halves will be polled at least + * every 10ms */ + *timeout = MIN(10, *timeout); + } else { + /* non-idle bottom halves will be executed + * immediately */ + *timeout = 0; + break; + } + } + } +} + diff --git a/qemu-common.h b/qemu-common.h index 768e749feb..3e73bf9523 100644 --- a/qemu-common.h +++ b/qemu-common.h @@ -105,6 +105,7 @@ void qemu_bh_schedule_idle(QEMUBH *bh); void qemu_bh_cancel(QEMUBH *bh); void qemu_bh_delete(QEMUBH *bh); int qemu_bh_poll(void); +void qemu_bh_update_timeout(int *timeout); uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c); diff --git a/vl.c b/vl.c index eb2744e594..18a2405505 100644 --- a/vl.c +++ b/vl.c @@ -3080,110 +3080,6 @@ void qemu_service_io(void) qemu_notify_event(); } -/***********************************************************/ -/* bottom halves (can be seen as timers which expire ASAP) */ - -struct QEMUBH { - QEMUBHFunc *cb; - void *opaque; - int scheduled; - int idle; - int deleted; - QEMUBH *next; -}; - -static QEMUBH *first_bh = NULL; - -QEMUBH *qemu_bh_new(QEMUBHFunc *cb, void *opaque) -{ - QEMUBH *bh; - bh = qemu_mallocz(sizeof(QEMUBH)); - bh->cb = cb; - bh->opaque = opaque; - bh->next = first_bh; - first_bh = bh; - return bh; -} - -int qemu_bh_poll(void) -{ - QEMUBH *bh, **bhp; - int ret; - - ret = 0; - for (bh = first_bh; bh; bh = bh->next) { - if (!bh->deleted && bh->scheduled) { - bh->scheduled = 0; - if (!bh->idle) - ret = 1; - bh->idle = 0; - bh->cb(bh->opaque); - } - } - - /* remove deleted bhs */ - bhp = &first_bh; - while (*bhp) { - bh = *bhp; - if (bh->deleted) { - *bhp = bh->next; - qemu_free(bh); - } else - bhp = &bh->next; - } - - return ret; -} - -void qemu_bh_schedule_idle(QEMUBH *bh) -{ - if (bh->scheduled) - return; - bh->scheduled = 1; - bh->idle = 1; -} - -void qemu_bh_schedule(QEMUBH *bh) -{ - if (bh->scheduled) - return; - bh->scheduled = 1; - bh->idle = 0; - /* stop the currently executing CPU to execute the BH ASAP */ - qemu_notify_event(); -} - -void qemu_bh_cancel(QEMUBH *bh) -{ - bh->scheduled = 0; -} - -void qemu_bh_delete(QEMUBH *bh) -{ - bh->scheduled = 0; - bh->deleted = 1; -} - -static void qemu_bh_update_timeout(int *timeout) -{ - QEMUBH *bh; - - for (bh = first_bh; bh; bh = bh->next) { - if (!bh->deleted && bh->scheduled) { - if (bh->idle) { - /* idle bottom halves will be polled at least - * every 10ms */ - *timeout = MIN(10, *timeout); - } else { - /* non-idle bottom halves will be executed - * immediately */ - *timeout = 0; - break; - } - } - } -} - /***********************************************************/ /* machine registration */