diff options
-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], |