qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] timer: fix qemu_poll_ns early timeout on window


From: Sangho Park
Subject: Re: [Qemu-devel] [PATCH] timer: fix qemu_poll_ns early timeout on windows
Date: Fri, 18 Apr 2014 11:11:32 +0900

Hi, maintainers. 
Could you check this patch?
http://www.mail-archive.com/address@hidden/msg227161.html

Thanks

ps)
We've checked the http://wiki.qemu.org/Contribute/SubmitAPatch. Yet, if we
made any violation or mistake, let us know. We will appreciate your favor.

-----Original Message-----
From: Stanislav Vorobiov [mailto:address@hidden 
Sent: Thursday, April 17, 2014 6:08 PM
To: address@hidden
Cc: address@hidden; address@hidden
Subject: Re: [Qemu-devel] [PATCH] timer: fix qemu_poll_ns early timeout on
windows

Hi, everyone

Any comments on this one ? This patch fixes pretty serious performance
issues on windows, it would be great to have this in 2.0.0

On 04/15/2014 12:41 PM, Stanislav Vorobiov wrote:
> From: Sangho Park <address@hidden>
> 
> g_poll has a problem on windows when using timeouts < 10ms, in 
> glib/gpoll.c:
> 
> /* If not, and we have a significant timeout, poll again with
>  * timeout then. Note that this will return indication for only
>  * one event, or only for messages. We ignore timeouts less than
>  * ten milliseconds as they are mostly pointless on Windows, the
>  * MsgWaitForMultipleObjectsEx() call will timeout right away
>  * anyway.
>  */
> if (retval == 0 && (timeout == INFINITE || timeout >= 10))
>   retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, 
> timeout);
> 
> so whenever g_poll is called with timeout < 10ms it does a quick poll 
> instead of wait, this causes significant performance degradation of 
> qemu, thus we should use WaitForMultipleObjectsEx directly
> 
> Signed-off-by: Stanislav Vorobiov <address@hidden>
> ---
>  qemu-timer.c |   91
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 91 insertions(+)
> 
> diff --git a/qemu-timer.c b/qemu-timer.c index e15ce47..9fb92cb 100644
> --- a/qemu-timer.c
> +++ b/qemu-timer.c
> @@ -315,6 +315,97 @@ int qemu_poll_ns(GPollFD *fds, guint nfds, int64_t
timeout)
>          ts.tv_nsec = timeout % 1000000000LL;
>          return ppoll((struct pollfd *)fds, nfds, &ts, NULL);
>      }
> +#elif defined(_WIN32)
> +    guint i;
> +    HANDLE handles[MAXIMUM_WAIT_OBJECTS];
> +    gint nhandles = 0;
> +    int num_completed = 0;
> +    gint timeout_ms = qemu_timeout_ns_to_ms(timeout);
> +
> +    for (i = 0; i < nfds; i++) {
> +        gint j;
> +
> +        if (fds[i].fd <= 0) {
> +            continue;
> +        }
> +
> +        /* don't add same handle several times
> +         */
> +        for (j = 0; j < nhandles; j++) {
> +            if (handles[j] == (HANDLE)fds[i].fd) {
> +                break;
> +            }
> +        }
> +
> +        if (j == nhandles) {
> +            if (nhandles == MAXIMUM_WAIT_OBJECTS) {
> +                fprintf(stderr, "Too many handles to wait for!\n");
> +                break;
> +            } else {
> +                handles[nhandles++] = (HANDLE)fds[i].fd;
> +            }
> +        }
> +    }
> +
> +    for (i = 0; i < nfds; ++i) {
> +        fds[i].revents = 0;
> +    }
> +
> +    if (timeout_ms == -1) {
> +        timeout_ms = INFINITE;
> +    }
> +
> +    if (nhandles == 0) {
> +        if (timeout_ms == INFINITE) {
> +            return -1;
> +        } else {
> +            SleepEx(timeout_ms, TRUE);
> +            return 0;
> +        }
> +    }
> +
> +    while (1) {
> +        DWORD res;
> +        gint j;
> +
> +        res = WaitForMultipleObjectsEx(nhandles, handles, FALSE,
> +            timeout_ms, TRUE);
> +
> +        if (res == WAIT_FAILED) {
> +            for (i = 0; i < nfds; ++i) {
> +                fds[i].revents = 0;
> +            }
> +
> +            return -1;
> +        } else if ((res == WAIT_TIMEOUT) || (res == WAIT_IO_COMPLETION)
||
> +                   ((int)res < WAIT_OBJECT_0) ||
> +                   (res >= (WAIT_OBJECT_0 + nhandles))) {
> +            break;
> +        }
> +
> +        for (i = 0; i < nfds; ++i) {
> +            if (handles[res - WAIT_OBJECT_0] == (HANDLE)fds[i].fd) {
> +                fds[i].revents = fds[i].events;
> +            }
> +        }
> +
> +        ++num_completed;
> +
> +        if (nhandles <= 1) {
> +            break;
> +        }
> +
> +        /* poll the rest of the handles
> +         */
> +        for (j = res - WAIT_OBJECT_0 + 1; j < nhandles; j++) {
> +            handles[j - 1] = handles[j];
> +        }
> +        --nhandles;
> +
> +        timeout_ms = 0;
> +    }
> +
> +    return num_completed;
>  #else
>      return g_poll(fds, nfds, qemu_timeout_ns_to_ms(timeout));  #endif
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]