From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mout.kundenserver.de (mout.kundenserver.de [212.227.126.133]) by sourceware.org (Postfix) with ESMTPS id EC8A53851C17 for ; Thu, 2 Sep 2021 08:17:48 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org EC8A53851C17 Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=cygwin.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=cygwin.com Received: from calimero.vinschen.de ([24.134.7.25]) by mrelayeu.kundenserver.de (mreue011 [212.227.15.167]) with ESMTPSA (Nemesis) id 1MacjC-1mxVhp15Uw-00c9oq for ; Thu, 02 Sep 2021 10:17:47 +0200 Received: by calimero.vinschen.de (Postfix, from userid 500) id B7A19A80D89; Thu, 2 Sep 2021 10:17:46 +0200 (CEST) Date: Thu, 2 Sep 2021 10:17:46 +0200 From: Corinna Vinschen To: cygwin-developers@cygwin.com Subject: Re: cygrunsrv + sshd + rsync = 20 times too slow -- throttled? Message-ID: Reply-To: cygwin-developers@cygwin.com Mail-Followup-To: cygwin-developers@cygwin.com References: <20210901080220.ee4a5bfbea62cc1ae0a9598e@nifty.ne.jp> <20210901091652.6bf3cccbcaed4a22f6ffa6b0@nifty.ne.jp> <20210901172339.1039604b7067e0492534a20f@nifty.ne.jp> <24138e20-aa97-cfea-bf48-198fc67755ea@cornell.edu> <9ba687eb-f4a0-18f8-b10b-76e7e51e123e@cornell.edu> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <9ba687eb-f4a0-18f8-b10b-76e7e51e123e@cornell.edu> X-Provags-ID: V03:K1:uqzeJ5w+DJhYL3SdFuk+2PASvGgGXyQM331jS0PwpzB0RfEMRKr htclUdyqpGk74vOjCMED/dFWTCjf+CaeQLWt7dVFM11wihGH7mTVH9qa/6TjTEnklQoSTiM ZImWol2OjFFELv2fZFoVcG0A7V0CSqM34R8gRJja562pP4sf2XeaRHQDYrdyGOXsr+znnlX r/2+GWwM/YjlHrQYbUmhQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:uw/zJoBonn8=:NZwnJzcOVg8HH/UYn52OfO qJ3tXCN8B0Go4W9do2UVv3iv+u1U9ypnCBX+hBZva+TUSeUej/Ndq26f8SRMDOdlGJuXFmTY1 xFTFGo8FSStCzmK3QXnpBm+M5M9Oxi93fk/t881BsMoj+AvY6QDw1qmsK486dZzPgPobCmS67 OSd3f2jyxTV/PMOR1s/lzbTbOXjv/Ycupw7YtLWauwD6xVKaBOD4NMrKp3iQne5FQtSCA9mjB Z3/JonPjsBYNAYTG/Ah/6NRzt4FWcaUdYb0HaYuRR5nKgn4hWRHNlk1c7pxSFd0wzn6HwHLA+ flW/ODTOpHhjHcfRxRAuhOtkFyAzcTPeB9r45umK+wYUEdb+j304rLItJ1irT4zKaFsYl9LW4 abezGPJi8hPzd5k3xTksERC0hLV3IiwweEwIWVbdB2R8Vl7Vz0tV/mrV2pnitIUt0vb7TR+Uc Baxp+M9jt5keJo4SfbkBJR8BO6SbC5gZUFsLYCwLr1C4zulOSIw+jW6XdSeRKI0oLh4F0BkGo pPs7Sb0ynFc+YgWdB2NST6npt2YwT+VLwY4XF9B4KFksPemdUUA1Qa/VNwhmSjZzj5dCMFE+0 Bjpr0MWwGHik3bvDO2MwWvDZNzQ3Q593dEV7ktEJY0/XAupqTdBV9Ub2ya/rKq6xm4YU5J4XF vU3hczWbnFoFQlQb93dDhrBeNHMKeS5utpwqN4gvuKTPrRO/Pw65XW7Og+DQxy8eheJGfGj8D XGcijkGzeOQ/bTPanGezxFGz39eYDV3jpFjUwSoRBmfnwRHb8ZcVcyWA5cI= X-Spam-Status: No, score=-99.7 required=5.0 tests=BAYES_00, GOOD_FROM_CORINNA_CYGWIN, JMQ_SPF_NEUTRAL, KAM_DMARC_NONE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NEUTRAL, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: cygwin-developers@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin core component developers mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Sep 2021 08:17:59 -0000 On Sep 1 19:02, Ken Brown wrote: > On 9/1/2021 9:52 AM, Corinna Vinschen wrote: > > Great idea that. What we need would be some semaphore upside down. > > One that can be used to count items and which is signalled if it's > > down to zero. > > Here's an idea (untested), based on https://stackoverflow.com/questions/6559854/is-there-something-opposite-to-semaphore: > > We create an ordinary Windows semaphore and use it to count the readers: It > starts at 0, we increment it by calling ReleaseSemaphore when a reader is > opened (by fhandler_pipe::create, fork/exec, dup), and we decrement it by > calling WFSO when a reader closes. When we decrement it, we test whether > it's been reduced to 0. We do this by calling ReleaseSemaphore and using > its lpPreviousCount argument. > > We also create an event that we can use to make WFMO return during a > blocking write. We signal this event if a reader closes and we've > discovered that there are no more readers. In this case we cancel the > pending write [*] and return an error. > > I'm sure I've overlooked something, but does this seem feasible? It could work, but the problem with all these approaches is that they are tricky and bound to fail as soon as a process is killed or crashes. > [*] I don't know offhand if Windows provides a way to cancel a pending > write. If not, we could use query_hdl to drain the pipe. There's a CancelIoEx function to cancel all async IO on a handle. In a lucid moment tonight, I had another idea. First of all, scratch my patch. Also, revert select to check only for WriteQuotaAvailable. Next, for sanity, let's assume that non-blocking reads don't change WriteQuotaAvailable. So the only important case is the blocking read, which reduces WriteQuotaAvailable by the number of requested bytes. Next, fact is, we're only interested in WriteQuotaAvailable > 0. And we have a buffersize of 64K. We can also safely assume that we only have a very small number of readers, typically only one. So here's the crazily simple idea: What if the readers never request more than, say, 50 or even 25% of the available buffer space? Our buffer is 64K and there's no guarantee that any read > PIPE_BUF (== 4K) is atomic anyway. This can work without having to check the other side of the pipe. Something like this, ignoring border cases: pipe::create() { [...] mutex = CreateMutex(); } pipe::raw_read(char *buf, size_t num_requested) { if (blocking) { WFSO(mutex); NtQueryInformationFile(FilePipeLocalInformation); if (!fpli.ReadDataAvailable && num_requested > fpli.InboundQuota / 4) num_requested = fpli.InboundQuota / 4; NtReadFile(pipe, buf, num_requested); ReleaseMutex(mutex); } } It's not entirely foolproof, but it should fix 99% of the cases. Corinna