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,15 +928,11 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
928 #define MIN_TIMER_REARM_US 250 928 #define MIN_TIMER_REARM_US 250
929 929
930 static struct qemu_alarm_timer *alarm_timer; 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 #ifdef _WIN32 932 #ifdef _WIN32
936 933
937 struct qemu_alarm_win32 { 934 struct qemu_alarm_win32 {
938 MMRESULT timerId; 935 MMRESULT timerId;
939 - HANDLE host_alarm;  
940 unsigned int period; 936 unsigned int period;
941 } alarm_win32_data = {0, NULL, -1}; 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,6 +1301,8 @@ static int timer_load(QEMUFile *f, void *opaque, int version_id)
1305 return 0; 1301 return 0;
1306 } 1302 }
1307 1303
  1304 +static void qemu_event_increment(void);
  1305 +
1308 #ifdef _WIN32 1306 #ifdef _WIN32
1309 static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg, 1307 static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
1310 DWORD_PTR dwUser, DWORD_PTR dw1, 1308 DWORD_PTR dwUser, DWORD_PTR dw1,
@@ -1350,13 +1348,7 @@ static void host_alarm_handler(int host_signum) @@ -1350,13 +1348,7 @@ static void host_alarm_handler(int host_signum)
1350 qemu_get_clock(rt_clock))) { 1348 qemu_get_clock(rt_clock))) {
1351 CPUState *env = next_cpu; 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 alarm_timer->flags |= ALARM_FLAG_EXPIRED; 1352 alarm_timer->flags |= ALARM_FLAG_EXPIRED;
1361 1353
1362 if (env) { 1354 if (env) {
@@ -1645,24 +1637,6 @@ static void unix_stop_timer(struct qemu_alarm_timer *t) @@ -1645,24 +1637,6 @@ static void unix_stop_timer(struct qemu_alarm_timer *t)
1645 1637
1646 #endif /* !defined(_WIN32) */ 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 #ifdef _WIN32 1641 #ifdef _WIN32
1668 1642
@@ -1672,12 +1646,6 @@ static int win32_start_timer(struct qemu_alarm_timer *t) @@ -1672,12 +1646,6 @@ static int win32_start_timer(struct qemu_alarm_timer *t)
1672 struct qemu_alarm_win32 *data = t->priv; 1646 struct qemu_alarm_win32 *data = t->priv;
1673 UINT flags; 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 memset(&tc, 0, sizeof(tc)); 1649 memset(&tc, 0, sizeof(tc));
1682 timeGetDevCaps(&tc, sizeof(tc)); 1650 timeGetDevCaps(&tc, sizeof(tc));
1683 1651
@@ -1700,14 +1668,10 @@ static int win32_start_timer(struct qemu_alarm_timer *t) @@ -1700,14 +1668,10 @@ static int win32_start_timer(struct qemu_alarm_timer *t)
1700 1668
1701 if (!data->timerId) { 1669 if (!data->timerId) {
1702 perror("Failed to initialize win32 alarm timer"); 1670 perror("Failed to initialize win32 alarm timer");
1703 -  
1704 timeEndPeriod(data->period); 1671 timeEndPeriod(data->period);
1705 - CloseHandle(data->host_alarm);  
1706 return -1; 1672 return -1;
1707 } 1673 }
1708 1674
1709 - qemu_add_wait_object(data->host_alarm, try_to_rearm_timer, t);  
1710 -  
1711 return 0; 1675 return 0;
1712 } 1676 }
1713 1677
@@ -1717,8 +1681,6 @@ static void win32_stop_timer(struct qemu_alarm_timer *t) @@ -1717,8 +1681,6 @@ static void win32_stop_timer(struct qemu_alarm_timer *t)
1717 1681
1718 timeKillEvent(data->timerId); 1682 timeKillEvent(data->timerId);
1719 timeEndPeriod(data->period); 1683 timeEndPeriod(data->period);
1720 -  
1721 - CloseHandle(data->host_alarm);  
1722 } 1684 }
1723 1685
1724 static void win32_rearm_timer(struct qemu_alarm_timer *t) 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,7 +1707,6 @@ static void win32_rearm_timer(struct qemu_alarm_timer *t)
1745 perror("Failed to re-arm win32 alarm timer"); 1707 perror("Failed to re-arm win32 alarm timer");
1746 1708
1747 timeEndPeriod(data->period); 1709 timeEndPeriod(data->period);
1748 - CloseHandle(data->host_alarm);  
1749 exit(1); 1710 exit(1);
1750 } 1711 }
1751 } 1712 }
@@ -1757,25 +1718,6 @@ static int init_timer_alarm(void) @@ -1757,25 +1718,6 @@ static int init_timer_alarm(void)
1757 struct qemu_alarm_timer *t = NULL; 1718 struct qemu_alarm_timer *t = NULL;
1758 int i, err = -1; 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 for (i = 0; alarm_timers[i].name; i++) { 1721 for (i = 0; alarm_timers[i].name; i++) {
1780 t = &alarm_timers[i]; 1722 t = &alarm_timers[i];
1781 1723
@@ -1789,20 +1731,11 @@ static int init_timer_alarm(void) @@ -1789,20 +1731,11 @@ static int init_timer_alarm(void)
1789 goto fail; 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 alarm_timer = t; 1734 alarm_timer = t;
1798 1735
1799 return 0; 1736 return 0;
1800 1737
1801 fail: 1738 fail:
1802 -#ifndef _WIN32  
1803 - close(fds[0]);  
1804 - close(fds[1]);  
1805 -#endif  
1806 return err; 1739 return err;
1807 } 1740 }
1808 1741
@@ -3718,11 +3651,86 @@ void qemu_notify_event(void) @@ -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 return 0; 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 #ifdef _WIN32 3734 #ifdef _WIN32
3727 static void host_main_loop_wait(int *timeout) 3735 static void host_main_loop_wait(int *timeout)
3728 { 3736 {
@@ -3850,6 +3858,12 @@ void main_loop_wait(int timeout) @@ -3850,6 +3858,12 @@ void main_loop_wait(int timeout)
3850 } 3858 }
3851 #endif 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 /* vm time timers */ 3867 /* vm time timers */
3854 if (vm_running && likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER))) 3868 if (vm_running && likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
3855 qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], 3869 qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],