GNOME Bugzilla – Bug 728486
g_poll problems on windows
Last modified: 2018-05-24 16:27:13 UTC
g_poll has problems on windows when using timeouts < 10ms, in glib/gpoll.c: /* First check if one or several of them are immediately * available */ retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, 0); /* 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 in particular causes significant performance degradation in qemu starting from branch 1.7 where small timeout values are used frequently. Timeout values passed to g_poll mean "at least", i.e. g_poll MUST wait AT LEAST this time, it's allowed to wait more, but it's not allowed to wait less. Another problem with g_poll is that it first calls poll_rest with 0 and then calls poll_rest with non-0. What it means is that it'll first collect timed out handles and then it'll wait for a single handle until timeout. But by that time other handles might also get signaled and g_poll doesn't check for that. Thus, it'll make more sense to make this other way around - first wait for timeout and then loop and collect all the timed out handles (i.e. wait with timeout=0)
> Thus, it'll make more sense to make this other way around - first wait for > timeout and then loop and collect all the timed out handles (i.e. wait with > timeout=0) I'm not sure I understand this. I'll note that small timeouts do matter on QEMU because it uses timeBeginPeriod and timeEndPeriod to increase the frequency of the Windows scheduler tick.
>I'm not sure I understand this. Currently g_poll does this: 1. poll_rest(..., timeout=0) - this calls WaitForMultipleObjects(..., timeout=0) in a loop and collects all already timed out handles 2. poll_rest(..., timeout=actual_timeout) - this calls WaitForMultipleObjects(..., timeout=actual_timeout) once and possibly adds one more handle to the resulting set but what if during step #2 more handles became ready, g_poll doesn't check for that, so the caller will have to call g_poll again and then he'll collect these handles with step #1. It makes more sense to make this other way around, i.e. first step #2 and then step #1. >I'll note that small timeouts do matter on QEMU because it uses timeBeginPeriod >and timeEndPeriod to increase the frequency of the Windows scheduler tick. And that's where the problem in g_poll comes in (see the first part of this ticket, i.e. timeout >= 10 part)
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/glib/issues/859.