aboutsummaryrefslogtreecommitdiff
path: root/main-loop.c
diff options
context:
space:
mode:
authorAnthony Liguori <anthony@codemonkey.ws>2013-08-26 09:19:50 -0500
committerAnthony Liguori <anthony@codemonkey.ws>2013-08-26 09:19:50 -0500
commitf7ad538e1ea130c8b6f3abb06ad6c856242c799e (patch)
treebeed9203bd5083d854c4628eb0c9c29518f77d67 /main-loop.c
parente3f024aec29a2e3eff46138687e2ecba7631c645 (diff)
parentb10577df13fa4a1b38ea6c1ea7b66c6dfd90a07a (diff)
Merge remote-tracking branch 'stefanha/block' into staging
# By Alex Bligh (32) and others # Via Stefan Hajnoczi * stefanha/block: (42 commits) win32-aio: drop win32_aio_flush_cb() aio-win32: replace incorrect AioHandler->opaque usage with ->e aio / timers: remove dummy_io_handler_flush from tests/test-aio.c aio / timers: Remove legacy interface aio / timers: Switch entire codebase to the new timer API aio / timers: Add scripts/switch-timer-api aio / timers: Add test harness for AioContext timers aio / timers: convert block_job_sleep_ns and co_sleep_ns to new API aio / timers: Convert rtc_clock to be a QEMUClockType aio / timers: Remove main_loop_timerlist aio / timers: Rearrange timer.h & make legacy functions call non-legacy aio / timers: Add qemu_clock_get_ms and qemu_clock_get_ms aio / timers: Remove legacy qemu_clock_deadline & qemu_timerlist_deadline aio / timers: Remove alarm timers aio / timers: Add documentation and new format calls aio / timers: Use all timerlists in icount warp calculations aio / timers: Introduce new API timer_new and friends aio / timers: On timer modification, qemu_notify or aio_notify aio / timers: Convert mainloop to use timeout aio / timers: Convert aio_poll to use AioContext timers' deadline ... Message-id: 1377202298-22896-1-git-send-email-stefanha@redhat.com Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
Diffstat (limited to 'main-loop.c')
-rw-r--r--main-loop.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/main-loop.c b/main-loop.c
index 2d9774ef75..1c38ea2b93 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -131,10 +131,6 @@ int qemu_init_main_loop(void)
GSource *src;
init_clocks();
- if (init_timer_alarm() < 0) {
- fprintf(stderr, "could not initialize alarm timer\n");
- exit(1);
- }
ret = qemu_signal_init();
if (ret) {
@@ -155,10 +151,11 @@ static int max_priority;
static int glib_pollfds_idx;
static int glib_n_poll_fds;
-static void glib_pollfds_fill(uint32_t *cur_timeout)
+static void glib_pollfds_fill(int64_t *cur_timeout)
{
GMainContext *context = g_main_context_default();
int timeout = 0;
+ int64_t timeout_ns;
int n;
g_main_context_prepare(context, &max_priority);
@@ -174,9 +171,13 @@ static void glib_pollfds_fill(uint32_t *cur_timeout)
glib_n_poll_fds);
} while (n != glib_n_poll_fds);
- if (timeout >= 0 && timeout < *cur_timeout) {
- *cur_timeout = timeout;
+ if (timeout < 0) {
+ timeout_ns = -1;
+ } else {
+ timeout_ns = (int64_t)timeout * (int64_t)SCALE_MS;
}
+
+ *cur_timeout = qemu_soonest_timeout(timeout_ns, *cur_timeout);
}
static void glib_pollfds_poll(void)
@@ -191,7 +192,7 @@ static void glib_pollfds_poll(void)
#define MAX_MAIN_LOOP_SPIN (1000)
-static int os_host_main_loop_wait(uint32_t timeout)
+static int os_host_main_loop_wait(int64_t timeout)
{
int ret;
static int spin_counter;
@@ -204,7 +205,7 @@ static int os_host_main_loop_wait(uint32_t timeout)
* print a message to the screen. If we run into this condition, create
* a fake timeout in order to give the VCPU threads a chance to run.
*/
- if (spin_counter > MAX_MAIN_LOOP_SPIN) {
+ if (!timeout && (spin_counter > MAX_MAIN_LOOP_SPIN)) {
static bool notified;
if (!notified) {
@@ -214,19 +215,19 @@ static int os_host_main_loop_wait(uint32_t timeout)
notified = true;
}
- timeout = 1;
+ timeout = SCALE_MS;
}
- if (timeout > 0) {
+ if (timeout) {
spin_counter = 0;
qemu_mutex_unlock_iothread();
} else {
spin_counter++;
}
- ret = g_poll((GPollFD *)gpollfds->data, gpollfds->len, timeout);
+ ret = qemu_poll_ns((GPollFD *)gpollfds->data, gpollfds->len, timeout);
- if (timeout > 0) {
+ if (timeout) {
qemu_mutex_lock_iothread();
}
@@ -373,7 +374,7 @@ static void pollfds_poll(GArray *pollfds, int nfds, fd_set *rfds,
}
}
-static int os_host_main_loop_wait(uint32_t timeout)
+static int os_host_main_loop_wait(int64_t timeout)
{
GMainContext *context = g_main_context_default();
GPollFD poll_fds[1024 * 2]; /* this is probably overkill */
@@ -382,6 +383,7 @@ static int os_host_main_loop_wait(uint32_t timeout)
PollingEntry *pe;
WaitObjects *w = &wait_objects;
gint poll_timeout;
+ int64_t poll_timeout_ns;
static struct timeval tv0;
fd_set rfds, wfds, xfds;
int nfds;
@@ -419,12 +421,17 @@ static int os_host_main_loop_wait(uint32_t timeout)
poll_fds[n_poll_fds + i].events = G_IO_IN;
}
- if (poll_timeout < 0 || timeout < poll_timeout) {
- poll_timeout = timeout;
+ if (poll_timeout < 0) {
+ poll_timeout_ns = -1;
+ } else {
+ poll_timeout_ns = (int64_t)poll_timeout * (int64_t)SCALE_MS;
}
+ poll_timeout_ns = qemu_soonest_timeout(poll_timeout_ns, timeout);
+
qemu_mutex_unlock_iothread();
- g_poll_ret = g_poll(poll_fds, n_poll_fds + w->num, poll_timeout);
+ g_poll_ret = qemu_poll_ns(poll_fds, n_poll_fds + w->num, poll_timeout_ns);
+
qemu_mutex_lock_iothread();
if (g_poll_ret > 0) {
for (i = 0; i < w->num; i++) {
@@ -449,6 +456,7 @@ int main_loop_wait(int nonblocking)
{
int ret;
uint32_t timeout = UINT32_MAX;
+ int64_t timeout_ns;
if (nonblocking) {
timeout = 0;
@@ -462,13 +470,24 @@ int main_loop_wait(int nonblocking)
slirp_pollfds_fill(gpollfds);
#endif
qemu_iohandler_fill(gpollfds);
- ret = os_host_main_loop_wait(timeout);
+
+ if (timeout == UINT32_MAX) {
+ timeout_ns = -1;
+ } else {
+ timeout_ns = (uint64_t)timeout * (int64_t)(SCALE_MS);
+ }
+
+ timeout_ns = qemu_soonest_timeout(timeout_ns,
+ timerlistgroup_deadline_ns(
+ &main_loop_tlg));
+
+ ret = os_host_main_loop_wait(timeout_ns);
qemu_iohandler_poll(gpollfds, ret);
#ifdef CONFIG_SLIRP
slirp_pollfds_poll(gpollfds, (ret < 0));
#endif
- qemu_run_all_timers();
+ qemu_clock_run_all_timers();
return ret;
}