aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--qemu-timer-ui.c32
-rw-r--r--qemu-timer.c35
-rw-r--r--qemu-timer.h1
-rw-r--r--vl-android.c35
4 files changed, 46 insertions, 57 deletions
diff --git a/qemu-timer-ui.c b/qemu-timer-ui.c
index 5a734b5..912e634 100644
--- a/qemu-timer-ui.c
+++ b/qemu-timer-ui.c
@@ -934,6 +934,12 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t)
#endif /* _WIN32 */
+static void alarm_timer_on_change_state_rearm(void *opaque, int running, int reason)
+{
+ if (running)
+ qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque);
+}
+
int init_timer_alarm(void)
{
struct qemu_alarm_timer *t = NULL;
@@ -971,28 +977,6 @@ void quit_timers(void)
int qemu_calculate_timeout(void)
{
- int timeout;
-
- {
- /* XXX: use timeout computed from timers */
- int64_t add;
- int64_t delta = 0;
- /* Advance virtual time to the next event. */
- {
- /* Wait for either IO to occur or the next
- timer event. */
- add = qemu_next_deadline();
- /* We advance the timer before checking for IO.
- Limit the amount we advance so that early IO
- activity won't get the guest too far ahead. */
- if (add > 10000000)
- add = 10000000;
- delta += add;
- timeout = delta / 1000000;
- if (timeout < 0)
- timeout = 0;
- }
- }
-
- return timeout;
+ /* Deliver user events at 30 Hz */
+ return 1000/30;
}
diff --git a/qemu-timer.c b/qemu-timer.c
index 402f567..0ed5ba9 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -589,7 +589,7 @@ static void qemu_run_timers(QEMUClock *clock)
{
QEMUTimer **ptimer_head, *ts;
int64_t current_time;
-
+
if (!clock->enabled)
return;
@@ -743,6 +743,15 @@ void qemu_run_all_timers(void)
qemu_run_timers(host_clock);
}
+static int timer_alarm_pending = 1;
+
+int qemu_timer_alarm_pending(void)
+{
+ int ret = timer_alarm_pending;
+ timer_alarm_pending = 0;
+ return ret;
+}
+
#ifdef _WIN32
static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
DWORD_PTR dwUser, DWORD_PTR dw1,
@@ -795,6 +804,7 @@ static void host_alarm_handler(int host_signum)
t->expired = alarm_has_dynticks(t);
t->pending = 1;
+ timer_alarm_pending = 1;
qemu_notify_event();
}
}
@@ -961,7 +971,7 @@ static int dynticks_start_timer(struct qemu_alarm_timer *t)
sigaction(SIGALRM, &act, NULL);
- /*
+ /*
* Initialize ev struct to 0 to avoid valgrind complaining
* about uninitialized data in timer_create call
*/
@@ -1181,6 +1191,8 @@ void quit_timers(void)
t->stop(t);
}
+extern int tcg_has_work(void);
+
int qemu_calculate_timeout(void)
{
#ifndef CONFIG_IOTHREAD
@@ -1188,7 +1200,24 @@ int qemu_calculate_timeout(void)
if (!vm_running)
timeout = 5000;
- else {
+ else if (tcg_has_work())
+ timeout = 0;
+ else if (!use_icount) {
+#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
+ } else {
/* XXX: use timeout computed from timers */
int64_t add;
int64_t delta;
diff --git a/qemu-timer.h b/qemu-timer.h
index 1494f79..e175809 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -36,6 +36,7 @@ void qemu_del_timer(QEMUTimer *ts);
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
int qemu_timer_pending(QEMUTimer *ts);
int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
+int qemu_timer_alarm_pending(void);
void qemu_run_all_timers(void);
int qemu_alarm_pending(void);
diff --git a/vl-android.c b/vl-android.c
index fce438e..d353c31 100644
--- a/vl-android.c
+++ b/vl-android.c
@@ -313,7 +313,6 @@ uint64_t node_cpumask[MAX_NODES];
static CPUState *cur_cpu;
static CPUState *next_cpu;
-static int timer_alarm_pending = 1;
static QEMUTimer *nographic_timer;
uint8_t qemu_uuid[16];
@@ -3063,9 +3062,9 @@ void main_loop_wait(int timeout)
}
}
- /* remove deleted IO handlers */
- pioh = &first_io_handler;
- while (*pioh) {
+ /* remove deleted IO handlers */
+ pioh = &first_io_handler;
+ while (*pioh) {
ioh = *pioh;
if (ioh->deleted) {
*pioh = ioh->next;
@@ -3086,27 +3085,6 @@ void main_loop_wait(int timeout)
#endif
charpipe_poll();
-#if 0
- /* rearm timer, if not periodic */
- if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
- alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
- qemu_rearm_alarm_timer(alarm_timer);
- }
-
- /* vm time timers */
- if (vm_running) {
- if (!cur_cpu || likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
- qemu_run_timers(&active_timers[QEMU_CLOCK_VIRTUAL],
- qemu_get_clock(vm_clock));
- }
-
- /* real time timers */
- qemu_run_timers(&active_timers[QEMU_CLOCK_REALTIME],
- qemu_get_clock(rt_clock));
-
- qemu_run_timers(&active_timers[QEMU_CLOCK_HOST],
- qemu_get_clock(host_clock));
-#endif
qemu_run_all_timers();
/* Check bottom-halves last in case any of the earlier events triggered
@@ -3175,8 +3153,7 @@ static void tcg_cpu_exec(void)
if (!vm_running)
break;
- if (timer_alarm_pending) {
- timer_alarm_pending = 0;
+ if (qemu_timer_alarm_pending()) {
break;
}
if (cpu_can_run(env))
@@ -3189,7 +3166,6 @@ static void tcg_cpu_exec(void)
}
}
-#if 0
static int cpu_has_work(CPUState *env)
{
if (env->stop)
@@ -3203,7 +3179,7 @@ static int cpu_has_work(CPUState *env)
return 0;
}
-static int tcg_has_work(void)
+int tcg_has_work(void)
{
CPUState *env;
@@ -3212,7 +3188,6 @@ static int tcg_has_work(void)
return 1;
return 0;
}
-#endif
static int vm_can_run(void)
{