This is the mail archive of the
cygwin-developers
mailing list for the Cygwin project.
Re: Can you undo change in sig_dispatch_pending() ?
- From: Oleg Volkov <oleg at unicorn dot kiev dot ua>
- To: cygwin-developers at cygwin dot com
- Date: Thu, 1 Nov 2007 18:01:59 +0200
- Subject: Re: Can you undo change in sig_dispatch_pending() ?
- References: <1616499095.20071030163505@unicorn.kiev.ua> <20071031114857.GA25626@ednor.casa.cgf.cx> <1687937283.20071031170617@unicorn.kiev.ua> <20071031181706.GA26474@ednor.casa.cgf.cx> <Pine.CYG.4.58.0710311337300.2628@PC1163-8460-XP.flightsafety.com> <20071031185645.GA30243@ednor.casa.cgf.cx> <Pine.CYG.4.58.0710311625170.2628@PC1163-8460-XP.flightsafety.com> <20071031223201.GA13688@ednor.casa.cgf.cx>
- Reply-to: Oleg Volkov <oleg at unicorn dot kiev dot ua>
Christopher Faylor wrote:
> However, if you think that this check can be put back then it seems like
> the next logical step is to remove the sig_dispatch_pending from readv
> and writev.
Perhaps subsequent steps will be to remove sig_dispatch_pending() from
other syscalls. It doesn't seem to me these steps are logical.
> If you have tests for this then you can either try removing the
> sig_dispatch_pending entirely and see how that works or you can generate
> data showing how often the sigq.start.next test is triggered and report
> the results here.
>
>> I'd like to understand what you meant by that more. Did you mean how
>> often does it avoid the needless thread ping pong, or how often does it
>> actually invoke it? I assume the latter as the performance data clearly
>> indicates the former is very frequent.
>
> I mean how many times
>
> if (!sigq.next)
> return;
>
> /* this code */
>
> is executed.
I have prepared a test, which shows that `sigq.start.next' can be zero and
non-zero when sig_dispatch_pending() is called from writev(). This test is
for cygwin1.dll version 1.5.24-2. To run this test you first need to ensure
that DEBUGGING macro is defined, modify the line in sig_dispatch_pending(),
so `sigq.start.next' will be checked:
if (exit_state || &_my_tls == _sig_tls || !sigq.start.next)
and add the following line in writev() before the call to
sig_dispatch_pending():
syscall_printf ("writev (%d, %p, %d): entry", fd, iov, iovcnt);
Test program is given below.
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <w32api/windows.h> // for Sleep()
void sighndlr(int sig)
{
}
int main(int argc, char **argv)
{
char c=0;
int fd, pid=getpid();
time_t tstart;
sigset_t sset;
struct sigaction act;
if ((fd=open("tstsig.bin",
O_CREAT|O_WRONLY|O_TRUNC,
0666))<0) {
perror("open()");
return 1;
}
sigemptyset(&sset);
act.sa_handler=sighndlr;
act.sa_mask=sset;
act.sa_flags=SA_NOMASK;
sigaction(SIGUSR1,&act,0);
if (fork()==-1) {
perror("fork()");
return 1;
}
tstart=time(0);
while (time(0)<tstart+5) { // repeat for ~5 secs in
kill(pid,SIGUSR1); // child and parent
write(fd,&c,1);
Sleep(0);
}
return 0;
}
Invoke this program using `strace test_program >dump' command.
Then use commands:
grep -c "sig_dispatch_pending:" dump
# to see the total number of calls to sig_dispatch_pending();
# on my computer it is ~3000; this number includes calls from
# both write() and kill();
grep -c flushing dump
# to see the number of calls to sig_dispatch_pending() when
# `sigq.start.next' is non-zero; on my computer it is ~450;
grep -B1 flushing dump | less
# to ensure that sig_dispatch_pending() sometimes flushes
# signals when is called from writev();
grep -B1 sigq | less
# to ensure that there are calls to sig_dispatch_pending()
# from writev() when `sigq.start.next' is zero.