After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 728486 - g_poll problems on windows
g_poll problems on windows
Status: RESOLVED OBSOLETE
Product: glib
Classification: Platform
Component: win32
2.40.x
Other Windows
: Normal major
: ---
Assigned To: gtk-win32 maintainers
gtk-win32 maintainers
Depends on:
Blocks:
 
 
Reported: 2014-04-18 09:00 UTC by Stanislav Vorobiov
Modified: 2018-05-24 16:27 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Stanislav Vorobiov 2014-04-18 09:00:34 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)
Comment 1 Paolo Bonzini 2014-04-27 09:26:29 UTC
> 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.
Comment 2 Stanislav Vorobiov 2014-04-28 06:05:42 UTC
>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)
Comment 3 GNOME Infrastructure Team 2018-05-24 16:27:13 UTC
-- 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.