delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2007/10/05/14:37:01

X-Recipient: archive-cygwin AT delorie DOT com
X-Spam-Check-By: sourceware.org
Date: Fri, 5 Oct 2007 22:12:10 +0300
From: Oleg Volkov <oleg AT unicorn DOT kiev DOT ua>
X-Mailer: The Bat! (v2.00.6) Business
Reply-To: Oleg Volkov <oleg AT unicorn DOT kiev DOT ua>
Message-ID: <12529306160.20071005221210@unicorn.kiev.ua>
To: cygwin AT cygwin DOT com
Subject: Re: Cygwin speed
MIME-Version: 1.0
X-IsSubscribed: yes
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

I had come across with the following problem: after upgrading Cygwin from
version 1.5.19-4 to 1.5.24-2 my application (relational database)
began to function several times slower. The reason was a slowdown of
a function, which performs rebalancing of table index tree; this function
calls write() function very many times, at each call 4 bytes are updated
in index file (row number in tree node). To test performance of write()
function I created the following test program:

    #include <fcntl.h>
    #include <unistd.h>

    int main(int argc, char **argv)
    {
        char chunk[64]="";
        int i, fd;
        if ((fd=open("tst_chunks.bin",
                     O_CREAT|O_WRONLY|O_TRUNC,
                     0666))<0) return 1;
        for (i=0; i<1000000; i++)
            if (write(fd,chunk,sizeof(chunk))!=sizeof(chunk)) return 1;
        close(fd);
        return 0;
    }

When launched on Celeron 1.3MHz via "time -p", it works:

  on 1.5.24-2 : 48 seconds;
  on 1.5.19-4 : 18 seconds.

After investigating differences between 1.5.24-2 and 1.5.19-4 I have found
out, that the problem is in function sig_dispatch_pending(), which is
called in the beginning of writev() function, which is called from write().
In function sig_dispatch_pending() the following has been changed:

    void __stdcall
    sig_dispatch_pending (bool fast)
    {
         if (exit_state || &_my_tls == _sig_tls || !sigq.start.next)  // version 1.5.19-4
      // if (exit_state || &_my_tls == _sig_tls)                      // version 1.5.24-2
        {
          //...
          return;
        }

      //...
      sig_send (myself, fast ? __SIGFLUSHFAST : __SIGFLUSH);
    }

When make this modification in sources for 1.5.24-2 and rebuild cygwin1.dll,
my test program begins to work as fast as on 1.5.19-4. In message

  http://cygwin.com/ml/cygwin-developers/2006-07/msg00034.html

Brian Ford pointed to the following description of a change between
1.5.19-4 and 1.5.24-2:

  2006-02-24  Christopher Faylor  <cgf at timesys dot com>

        * sigproc.cc (sigheld): Define new variable.
->      (sig_dispatch_pending): Don't check sigq since that's racy.
        (sig_send): Set sigheld flag if __SIGHOLD is specified, reset it if
        __SIGNOHOLD is specified.  Ignore flush signals if we're holding
        signals.

I think, that maybe checking of sigq is a little bit racy, but it turns,
that getting rid of such a cheap check results in a great slowdown of
sig_dispatch_pending() function for most calls, when there are no pending
signals.

Maybe introducing a critical section or some other synchronization
mechanism would be a solution.

Oleg Volkov



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019