Abolishing sleeps in issignal()

Jeff Roberson jroberson at chesapeake.net
Tue Oct 9 18:23:26 PDT 2007


On Tue, 9 Oct 2007, Matthew Dillon wrote:

>    I think it's a bad idea to have SIGSTOP generate an EINTR-like event.
>    The two have totally different mechanics and the system call behavior
>    will be different because there are some system calls which simply cannot
>    be restarted even if you wanted to.  System calls which loop on UIO's,
>    for example, cannot be restarted.  EINTR and STOP have two totally
>    different behaviors for such calls and there is nothing you can do about
>    it.  Basically any system call which maintains state through multiple
>    blocking events cannot be restarted after having returned unless no
>    cumulative operations have been performed.
>
>    For example, if read()ing from a socket the read() is restartable ONLY
>    if no data has yet been read.  But if some data HAS been read and EINTR
>    occurs, the system call will simply terminate early and return a
>    short-read, and NOT restart.  That same system call when presented with
>    a STOP, however, will not terminate early.  Instead it (in FreeBSD now)
>    stops in tsleep and when it is CONTed again the system call resumes.
>    It's simply not possible (without a LOT of work) to have such a system
>    call return all the way to userland or even return to the kernel syscall
>    trap layer and be able to restart it.

Sure, however, we already deal with interrupting these system calls now 
either with short reads or syscall restart.  The question is whether 
changing the behavior to the same for SIGSTOP is a big enough change to 
break things.  I will see what posix has to say about it soon.


>
>    The restart code only works if no cumulative events have occured... for
>    example, if a UIO has not been filled at all (0 bytes read or written).
>    ERESTART literally moves the program counter back to the start of the
>    system call and causes userland to re-execute it.
>
>    The best compromise that I found, which I implemented for Dragonfly a
>    while back, was to ignore SIGSTOP in the kernel entirely and process
>    the event in userret() instead.  Except for certain process control
>    cases like the debugger, SIGSTOP is handled asynchronously anyway. e.g.
>    when you signal a SIGSTOP the kill() system call will return before
>    the target process(es) have actually stopped.  It's just that the window
>    of opportunity is fairly small when SIGSTOP is handled in tsleep, and
>    somewhat bigger when it is handled in userret.  That's the only hangup.

Yes this is a very good idea.  However, it's also a change in behavior. 
The question is, which is more disruptive?  Causing restart behavior or 
allowing the syscalls to continue further than they original would've.  I 
will consult posix and see what Linux and Solaris do in more detail.

Thanks,
Jeff


>
> 						-Matt
>


More information about the freebsd-arch mailing list