aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2009-04-24 18:03:29 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2009-04-24 18:03:29 +0000
commit50317c7fa709e4a0d9dc898c618334dfa3b343a2 (patch)
treea31a890e58d30a6eb4ca58f7421d9b8e85c5dce5
parent3fcf7b6bedd94234cab2b9f0bececa7141c0ece3 (diff)
qemu: factor out event notification / rearm alarm timer on main_loop_wait (Marcelo Tosatti)
Special events that have no particular event descriptor (either fd for UNIX or HANDLE for Windows) associated with make use of an artificial one. Factor the alarm timer notification so that it can be used for other events, and move dyntick timer rearm to main_loop_wait. aliguori: made sure to return a value in qemu_event_init() on win32 Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@7240 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--vl.c156
1 files changed, 85 insertions, 71 deletions
diff --git a/vl.c b/vl.c
index dbdbefb759..3d1cde65a2 100644
--- a/vl.c
+++ b/vl.c
@@ -928,15 +928,11 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
#define MIN_TIMER_REARM_US 250
static struct qemu_alarm_timer *alarm_timer;
-#ifndef _WIN32
-static int alarm_timer_rfd, alarm_timer_wfd;
-#endif
#ifdef _WIN32
struct qemu_alarm_win32 {
MMRESULT timerId;
- HANDLE host_alarm;
unsigned int period;
} alarm_win32_data = {0, NULL, -1};
@@ -1305,6 +1301,8 @@ static int timer_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
+static void qemu_event_increment(void);
+
#ifdef _WIN32
static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
DWORD_PTR dwUser, DWORD_PTR dw1,
@@ -1350,13 +1348,7 @@ static void host_alarm_handler(int host_signum)
qemu_get_clock(rt_clock))) {
CPUState *env = next_cpu;
-#ifdef _WIN32
- struct qemu_alarm_win32 *data = ((struct qemu_alarm_timer*)dwUser)->priv;
- SetEvent(data->host_alarm);
-#else
- static const char byte = 0;
- write(alarm_timer_wfd, &byte, sizeof(byte));
-#endif
+ qemu_event_increment();
alarm_timer->flags |= ALARM_FLAG_EXPIRED;
if (env) {
@@ -1645,24 +1637,6 @@ static void unix_stop_timer(struct qemu_alarm_timer *t)
#endif /* !defined(_WIN32) */
-static void try_to_rearm_timer(void *opaque)
-{
- struct qemu_alarm_timer *t = opaque;
-#ifndef _WIN32
- ssize_t len;
-
- /* Drain the notify pipe */
- do {
- char buffer[512];
- len = read(alarm_timer_rfd, buffer, sizeof(buffer));
- } while ((len == -1 && errno == EINTR) || len > 0);
-#endif
-
- if (t->flags & ALARM_FLAG_EXPIRED) {
- alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
- qemu_rearm_alarm_timer(alarm_timer);
- }
-}
#ifdef _WIN32
@@ -1672,12 +1646,6 @@ static int win32_start_timer(struct qemu_alarm_timer *t)
struct qemu_alarm_win32 *data = t->priv;
UINT flags;
- data->host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (!data->host_alarm) {
- perror("Failed CreateEvent");
- return -1;
- }
-
memset(&tc, 0, sizeof(tc));
timeGetDevCaps(&tc, sizeof(tc));
@@ -1700,14 +1668,10 @@ static int win32_start_timer(struct qemu_alarm_timer *t)
if (!data->timerId) {
perror("Failed to initialize win32 alarm timer");
-
timeEndPeriod(data->period);
- CloseHandle(data->host_alarm);
return -1;
}
- qemu_add_wait_object(data->host_alarm, try_to_rearm_timer, t);
-
return 0;
}
@@ -1717,8 +1681,6 @@ static void win32_stop_timer(struct qemu_alarm_timer *t)
timeKillEvent(data->timerId);
timeEndPeriod(data->period);
-
- CloseHandle(data->host_alarm);
}
static void win32_rearm_timer(struct qemu_alarm_timer *t)
@@ -1745,7 +1707,6 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t)
perror("Failed to re-arm win32 alarm timer");
timeEndPeriod(data->period);
- CloseHandle(data->host_alarm);
exit(1);
}
}
@@ -1757,25 +1718,6 @@ static int init_timer_alarm(void)
struct qemu_alarm_timer *t = NULL;
int i, err = -1;
-#ifndef _WIN32
- int fds[2];
-
- err = pipe(fds);
- if (err == -1)
- return -errno;
-
- err = fcntl_setfl(fds[0], O_NONBLOCK);
- if (err < 0)
- goto fail;
-
- err = fcntl_setfl(fds[1], O_NONBLOCK);
- if (err < 0)
- goto fail;
-
- alarm_timer_rfd = fds[0];
- alarm_timer_wfd = fds[1];
-#endif
-
for (i = 0; alarm_timers[i].name; i++) {
t = &alarm_timers[i];
@@ -1789,20 +1731,11 @@ static int init_timer_alarm(void)
goto fail;
}
-#ifndef _WIN32
- qemu_set_fd_handler2(alarm_timer_rfd, NULL,
- try_to_rearm_timer, NULL, t);
-#endif
-
alarm_timer = t;
return 0;
fail:
-#ifndef _WIN32
- close(fds[0]);
- close(fds[1]);
-#endif
return err;
}
@@ -3718,11 +3651,86 @@ void qemu_notify_event(void)
}
}
-static int qemu_init_main_loop(void)
+#ifndef _WIN32
+static int io_thread_fd = -1;
+
+static void qemu_event_increment(void)
{
+ static const char byte = 0;
+
+ if (io_thread_fd == -1)
+ return;
+
+ write(io_thread_fd, &byte, sizeof(byte));
+}
+
+static void qemu_event_read(void *opaque)
+{
+ int fd = (unsigned long)opaque;
+ ssize_t len;
+
+ /* Drain the notify pipe */
+ do {
+ char buffer[512];
+ len = read(fd, buffer, sizeof(buffer));
+ } while ((len == -1 && errno == EINTR) || len > 0);
+}
+
+static int qemu_event_init(void)
+{
+ int err;
+ int fds[2];
+
+ err = pipe(fds);
+ if (err == -1)
+ return -errno;
+
+ err = fcntl_setfl(fds[0], O_NONBLOCK);
+ if (err < 0)
+ goto fail;
+
+ err = fcntl_setfl(fds[1], O_NONBLOCK);
+ if (err < 0)
+ goto fail;
+
+ qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
+ (void *)(unsigned long)fds[0]);
+
+ io_thread_fd = fds[1];
+fail:
+ close(fds[0]);
+ close(fds[1]);
+ return err;
+}
+#else
+HANDLE qemu_event_handle;
+
+static void dummy_event_handler(void *opaque)
+{
+}
+
+static int qemu_event_init(void)
+{
+ qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (!qemu_event_handle) {
+ perror("Failed CreateEvent");
+ return -1;
+ }
+ qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
return 0;
}
+static void qemu_event_increment(void)
+{
+ SetEvent(qemu_event_handle);
+}
+#endif
+
+static int qemu_init_main_loop(void)
+{
+ return qemu_event_init();
+}
+
#ifdef _WIN32
static void host_main_loop_wait(int *timeout)
{
@@ -3850,6 +3858,12 @@ void main_loop_wait(int timeout)
}
#endif
+ /* 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 && likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],