int qemu_calculate_timeout(void) { int timeout; if (!vm_running) timeout = 5000; else if (tcg_has_work()) timeout = 0; else { #ifdef WIN32 /* This corresponds to the case where the emulated system is * totally idle and waiting for i/o. The problem is that on * Windows, the default value will prevent Windows user events * to be delivered in less than 5 seconds. * * Upstream contains a different way to handle this, for now * this hack should be sufficient until we integrate it into * our tree. */ timeout = 1000/15; /* deliver user events every 15/th of second */ #else timeout = 5000; #endif int64_t timeout_ns = (int64_t)timeout * 1000000LL; timeout_ns = qemu_soonest_timeout( timeout_ns, timerlistgroup_deadline_ns(&main_loop_tlg)); timeout = (int)((timeout_ns + 999999LL) / 1000000LL); } return timeout; }
int64_t aio_compute_timeout(AioContext *ctx) { int64_t deadline; int timeout = -1; QEMUBH *bh; for (bh = ctx->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 = 10000000; } else { /* non-idle bottom halves will be executed * immediately */ return 0; } } } deadline = timerlistgroup_deadline_ns(&ctx->tlg); if (deadline == 0) { return 0; } else { return qemu_soonest_timeout(timeout, deadline); } }
static gboolean aio_ctx_check(GSource *source) { AioContext *ctx = (AioContext *) source; QEMUBH *bh; for (bh = ctx->first_bh; bh; bh = bh->next) { if (!bh->deleted && bh->scheduled) { return true; } } return aio_pending(ctx) || (timerlistgroup_deadline_ns(&ctx->tlg) == 0); }
int main_loop_wait(int nonblocking) { int ret; uint32_t timeout = UINT32_MAX; int64_t timeout_ns; if (nonblocking) { timeout = 0; } /* poll any events */ g_array_set_size(gpollfds, 0); /* reset for new iteration */ /* XXX: separate device handlers from system ones */ #ifdef CONFIG_SLIRP slirp_update_timeout(&timeout); slirp_pollfds_fill(gpollfds); #endif qemu_iohandler_fill(gpollfds); 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_clock_run_all_timers(); return ret; }
int main_loop_wait(int nonblocking) { int ret; uint32_t timeout = UINT32_MAX; int64_t timeout_ns; if (nonblocking) { timeout = 0; } /* poll any events */ g_array_set_size(gpollfds, 0); /* reset for new iteration */ /* XXX: separate device handlers from system ones */ #ifdef CONFIG_SLIRP slirp_pollfds_fill(gpollfds, &timeout); #endif 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); #ifdef CONFIG_SLIRP slirp_pollfds_poll(gpollfds, (ret < 0)); #endif /* CPU thread can infinitely wait for event after missing the warp */ qemu_clock_warp(QEMU_CLOCK_VIRTUAL); qemu_clock_run_all_timers(); return ret; }