This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Cygwin select() issues and improvements


[I Originally sent this last week, but it bounced.]

Various issues with Cygwin's select() annoyed me, and I've spent some
time gnawing on them.

* With 1-byte reads, select() on Windows Console input would forget
about unread input data stored in the fhandler's readahead buffer.
Hitting F1 would send only the first ESC character, until you released
the key and another Windows event was generated.  (one-line fix, though
I'm not sure it's appropriate/correct)

* On Windows, select() timeouts have coarse 10-16ms granularity (not
fixed-- must use clock_setres(), which has its own issues)

This issue hurts Mosh pretty badly, since it often uses select() with
1-20ms timeouts. Running Mosh on localhost on Cygwin has around 80ms of
extra latency for typing, which is pretty noticeable. Using
clock_setres() mostly cures this.

Older Unix systems used to have this issue too, but modern OS X, FreeBSD
and Linux all do much better.

* select() uses old millisecond-granularity Windows timeouts-- I changed
this to microsecond granularity.  Any actual improvement from this is
small, since Windows doesn't seem to handle timers on a less than 500us
granularity, even when you do use clock_setres().  One thing this does
fix is that selects > 43 days now work, though this is not a big issue
in actual practice, or a POSIX requirement.

* Newer versions of Windows may return early on timers, causing select()
to return early. (fixed, but other timers in Cygwin still have this problem)

* The main loop in select() has some pretty tangled logic.  I improved
that some.  There's room for more improvement but that would need
changing fhandlers and related functions.

* During testing, I discovered that if the system is at 100% CPU load
from other processes, select() will wait exactly 10 seconds on its first
invocation even though your timeout is much shorter.  But curiously,
this doesn't happen with usleep(), even though Cygwin's internal code is
very similar.  This is not a new bug; my best guess is that it's an, um,
feature of the Windows process/thread scheduler-- possibly it adjusts
priorities at that 10 second mark.  It'd be nice to figure this out, I
think it may be affecting the Mosh test suite.

Windows scheduling in general seems to be rather poor for Cygwin
processes, and there are scheduling differences between processes run in
Windows console (which are seen as interactive by the scheduler) and
processes run in mintty (which are not).  There doesn't seem to be any
priority promotion for I/O as you see on most Unix schedulers.

I've attached plausible patches; they're also available on
<https://github.com/cgull/newlib-cygwin>, branch 'microsecond-select'.
I think it's all Windows XP compatible.  I've put some test programs up
at <https://github.com/cgull/cygwin-timeouts> too.

regards,

  --jh


Attachment: 0001-Make-buffered-console-characters-visible-to-select.patch
Description: Text document

Attachment: 0002-Use-high-resolution-timebases-for-select.patch
Description: Text document

Attachment: 0003-Move-get_nonascii_key-into-fhandler_console.patch
Description: Text document

Attachment: 0004-Debug-printfs.patch
Description: Text document

Attachment: 0005-Improve-select-implementation.patch
Description: Text document

Attachment: 0006-Regress-to-undocumented-Nt-Timer-calls.patch
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]