cygrunsrv + sshd + rsync = 20 times too slow -- throttled?

Corinna Vinschen corinna-cygwin@cygwin.com
Fri Sep 3 15:37:13 GMT 2021


On Sep  3 21:22, Takashi Yano wrote:
> On Fri, 3 Sep 2021 13:41:45 +0200
> Corinna Vinschen wrote:
> > Oh, wait.  Do you mean, if we only request less than len bytes, but
> > after NtReadFile there's still data in the buffer, we should try to
> > deplete the buffer up to len bytes in a subsequent NtReadFile?
> 
> Yes. I am sorry, my intent was not clear because I did more than
> necessary in the previous patch. Please see attached patch revised.
> 
> > I thought this is unnecessary, actually, because of POSIX:
> > 
> >    The standard developers considered adding atomicity requirements  to  a
> >    pipe  or FIFO, but recognized that due to the nature of pipes and FIFOs
> >    there could be no guarantee of atomicity of reads of {PIPE_BUF} or  any
> >    other size that would be an aid to applications portability.
> 
> POSIX says:
>     The value returned may be less than nbyte if the number of bytes left
>     in the file is less than nbyte, if the read() request was interrupted
>     by a signal, or if the file is a pipe or FIFO or special file and has
>                                                                       ~~~
>     fewer than nbyte bytes immediately available for reading.
>     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> https://pubs.opengroup.org/onlinepubs/009604599/functions/read.html
> 
> If it is turned over, read() should read all data immediately available,
> I think.

Hmm, I see the point, but we might have another problem with that.

We can't keep the mutex while waiting on the pending read, and there
could be more than one pending read running at the time.  if so,
chances are extremly high, that the data written to the buffer gets
split like this:

   reader 1		               reader 2

   calls read(65536)                   calls read(65536)

   calls NtReadFile(16384 bytes)
                                       calls NtReadFile(16384 bytes)

writer writes 65536 bytes

   wakes up and gets 16384 bytes
                                       wakes up and gets 16384 bytes
   gets the mutex, calls
   NtReadFile(32768) which 
   returns immediately with
   32768 bytes added to the
   caller's buffer.

so the buffer returned to reader 1 is 49152 bytes, with 16384 bytes
missing in the middle of it, *without* the reader knowing about that
fact.  If reader 1 gets the first 16384 bytes, the 16384 bytes have
been read in a single call, at least, so the byte order is not
unknowingly broken on the application level.

Does that make sense?


Corinna


More information about the Cygwin-developers mailing list