Commit 50317c7fa709e4a0d9dc898c618334dfa3b343a2

Authored by aliguori
1 parent 3fcf7b6b

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
Showing 1 changed file with 85 additions and 71 deletions
... ... @@ -928,15 +928,11 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
928 928 #define MIN_TIMER_REARM_US 250
929 929  
930 930 static struct qemu_alarm_timer *alarm_timer;
931   -#ifndef _WIN32
932   -static int alarm_timer_rfd, alarm_timer_wfd;
933   -#endif
934 931  
935 932 #ifdef _WIN32
936 933  
937 934 struct qemu_alarm_win32 {
938 935 MMRESULT timerId;
939   - HANDLE host_alarm;
940 936 unsigned int period;
941 937 } alarm_win32_data = {0, NULL, -1};
942 938  
... ... @@ -1305,6 +1301,8 @@ static int timer_load(QEMUFile *f, void *opaque, int version_id)
1305 1301 return 0;
1306 1302 }
1307 1303  
  1304 +static void qemu_event_increment(void);
  1305 +
1308 1306 #ifdef _WIN32
1309 1307 static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
1310 1308 DWORD_PTR dwUser, DWORD_PTR dw1,
... ... @@ -1350,13 +1348,7 @@ static void host_alarm_handler(int host_signum)
1350 1348 qemu_get_clock(rt_clock))) {
1351 1349 CPUState *env = next_cpu;
1352 1350  
1353   -#ifdef _WIN32
1354   - struct qemu_alarm_win32 *data = ((struct qemu_alarm_timer*)dwUser)->priv;
1355   - SetEvent(data->host_alarm);
1356   -#else
1357   - static const char byte = 0;
1358   - write(alarm_timer_wfd, &byte, sizeof(byte));
1359   -#endif
  1351 + qemu_event_increment();
1360 1352 alarm_timer->flags |= ALARM_FLAG_EXPIRED;
1361 1353  
1362 1354 if (env) {
... ... @@ -1645,24 +1637,6 @@ static void unix_stop_timer(struct qemu_alarm_timer *t)
1645 1637  
1646 1638 #endif /* !defined(_WIN32) */
1647 1639  
1648   -static void try_to_rearm_timer(void *opaque)
1649   -{
1650   - struct qemu_alarm_timer *t = opaque;
1651   -#ifndef _WIN32
1652   - ssize_t len;
1653   -
1654   - /* Drain the notify pipe */
1655   - do {
1656   - char buffer[512];
1657   - len = read(alarm_timer_rfd, buffer, sizeof(buffer));
1658   - } while ((len == -1 && errno == EINTR) || len > 0);
1659   -#endif
1660   -
1661   - if (t->flags & ALARM_FLAG_EXPIRED) {
1662   - alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
1663   - qemu_rearm_alarm_timer(alarm_timer);
1664   - }
1665   -}
1666 1640  
1667 1641 #ifdef _WIN32
1668 1642  
... ... @@ -1672,12 +1646,6 @@ static int win32_start_timer(struct qemu_alarm_timer *t)
1672 1646 struct qemu_alarm_win32 *data = t->priv;
1673 1647 UINT flags;
1674 1648  
1675   - data->host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);
1676   - if (!data->host_alarm) {
1677   - perror("Failed CreateEvent");
1678   - return -1;
1679   - }
1680   -
1681 1649 memset(&tc, 0, sizeof(tc));
1682 1650 timeGetDevCaps(&tc, sizeof(tc));
1683 1651  
... ... @@ -1700,14 +1668,10 @@ static int win32_start_timer(struct qemu_alarm_timer *t)
1700 1668  
1701 1669 if (!data->timerId) {
1702 1670 perror("Failed to initialize win32 alarm timer");
1703   -
1704 1671 timeEndPeriod(data->period);
1705   - CloseHandle(data->host_alarm);
1706 1672 return -1;
1707 1673 }
1708 1674  
1709   - qemu_add_wait_object(data->host_alarm, try_to_rearm_timer, t);
1710   -
1711 1675 return 0;
1712 1676 }
1713 1677  
... ... @@ -1717,8 +1681,6 @@ static void win32_stop_timer(struct qemu_alarm_timer *t)
1717 1681  
1718 1682 timeKillEvent(data->timerId);
1719 1683 timeEndPeriod(data->period);
1720   -
1721   - CloseHandle(data->host_alarm);
1722 1684 }
1723 1685  
1724 1686 static void win32_rearm_timer(struct qemu_alarm_timer *t)
... ... @@ -1745,7 +1707,6 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t)
1745 1707 perror("Failed to re-arm win32 alarm timer");
1746 1708  
1747 1709 timeEndPeriod(data->period);
1748   - CloseHandle(data->host_alarm);
1749 1710 exit(1);
1750 1711 }
1751 1712 }
... ... @@ -1757,25 +1718,6 @@ static int init_timer_alarm(void)
1757 1718 struct qemu_alarm_timer *t = NULL;
1758 1719 int i, err = -1;
1759 1720  
1760   -#ifndef _WIN32
1761   - int fds[2];
1762   -
1763   - err = pipe(fds);
1764   - if (err == -1)
1765   - return -errno;
1766   -
1767   - err = fcntl_setfl(fds[0], O_NONBLOCK);
1768   - if (err < 0)
1769   - goto fail;
1770   -
1771   - err = fcntl_setfl(fds[1], O_NONBLOCK);
1772   - if (err < 0)
1773   - goto fail;
1774   -
1775   - alarm_timer_rfd = fds[0];
1776   - alarm_timer_wfd = fds[1];
1777   -#endif
1778   -
1779 1721 for (i = 0; alarm_timers[i].name; i++) {
1780 1722 t = &alarm_timers[i];
1781 1723  
... ... @@ -1789,20 +1731,11 @@ static int init_timer_alarm(void)
1789 1731 goto fail;
1790 1732 }
1791 1733  
1792   -#ifndef _WIN32
1793   - qemu_set_fd_handler2(alarm_timer_rfd, NULL,
1794   - try_to_rearm_timer, NULL, t);
1795   -#endif
1796   -
1797 1734 alarm_timer = t;
1798 1735  
1799 1736 return 0;
1800 1737  
1801 1738 fail:
1802   -#ifndef _WIN32
1803   - close(fds[0]);
1804   - close(fds[1]);
1805   -#endif
1806 1739 return err;
1807 1740 }
1808 1741  
... ... @@ -3718,11 +3651,86 @@ void qemu_notify_event(void)
3718 3651 }
3719 3652 }
3720 3653  
3721   -static int qemu_init_main_loop(void)
  3654 +#ifndef _WIN32
  3655 +static int io_thread_fd = -1;
  3656 +
  3657 +static void qemu_event_increment(void)
3722 3658 {
  3659 + static const char byte = 0;
  3660 +
  3661 + if (io_thread_fd == -1)
  3662 + return;
  3663 +
  3664 + write(io_thread_fd, &byte, sizeof(byte));
  3665 +}
  3666 +
  3667 +static void qemu_event_read(void *opaque)
  3668 +{
  3669 + int fd = (unsigned long)opaque;
  3670 + ssize_t len;
  3671 +
  3672 + /* Drain the notify pipe */
  3673 + do {
  3674 + char buffer[512];
  3675 + len = read(fd, buffer, sizeof(buffer));
  3676 + } while ((len == -1 && errno == EINTR) || len > 0);
  3677 +}
  3678 +
  3679 +static int qemu_event_init(void)
  3680 +{
  3681 + int err;
  3682 + int fds[2];
  3683 +
  3684 + err = pipe(fds);
  3685 + if (err == -1)
  3686 + return -errno;
  3687 +
  3688 + err = fcntl_setfl(fds[0], O_NONBLOCK);
  3689 + if (err < 0)
  3690 + goto fail;
  3691 +
  3692 + err = fcntl_setfl(fds[1], O_NONBLOCK);
  3693 + if (err < 0)
  3694 + goto fail;
  3695 +
  3696 + qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
  3697 + (void *)(unsigned long)fds[0]);
  3698 +
  3699 + io_thread_fd = fds[1];
  3700 +fail:
  3701 + close(fds[0]);
  3702 + close(fds[1]);
  3703 + return err;
  3704 +}
  3705 +#else
  3706 +HANDLE qemu_event_handle;
  3707 +
  3708 +static void dummy_event_handler(void *opaque)
  3709 +{
  3710 +}
  3711 +
  3712 +static int qemu_event_init(void)
  3713 +{
  3714 + qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
  3715 + if (!qemu_event_handle) {
  3716 + perror("Failed CreateEvent");
  3717 + return -1;
  3718 + }
  3719 + qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
3723 3720 return 0;
3724 3721 }
3725 3722  
  3723 +static void qemu_event_increment(void)
  3724 +{
  3725 + SetEvent(qemu_event_handle);
  3726 +}
  3727 +#endif
  3728 +
  3729 +static int qemu_init_main_loop(void)
  3730 +{
  3731 + return qemu_event_init();
  3732 +}
  3733 +
3726 3734 #ifdef _WIN32
3727 3735 static void host_main_loop_wait(int *timeout)
3728 3736 {
... ... @@ -3850,6 +3858,12 @@ void main_loop_wait(int timeout)
3850 3858 }
3851 3859 #endif
3852 3860  
  3861 + /* rearm timer, if not periodic */
  3862 + if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
  3863 + alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
  3864 + qemu_rearm_alarm_timer(alarm_timer);
  3865 + }
  3866 +
3853 3867 /* vm time timers */
3854 3868 if (vm_running && likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
3855 3869 qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
... ...