Mail Archives: cygwin/2007/10/05/14:37:01
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 -