diff options
author | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-04-24 18:03:29 +0000 |
---|---|---|
committer | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2009-04-24 18:03:29 +0000 |
commit | 50317c7fa709e4a0d9dc898c618334dfa3b343a2 (patch) | |
tree | a31a890e58d30a6eb4ca58f7421d9b8e85c5dce5 | |
parent | 3fcf7b6bedd94234cab2b9f0bececa7141c0ece3 (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.c | 156 |
1 files changed, 85 insertions, 71 deletions
@@ -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], |