<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml/DTD/xhtml1-strict.dtd">
<html lang="de" xml:lang="de" xmlns="http://www.w3.org/1999/xhtml">

  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
    <link rel="author" href="mailto:drepper@redhat.com"/>

    <style type="text/css">
html { background-color: #c0c0c0; }
blockquote { font-style: italic; }
    </style>

    <title>Requirements of the POSIX Signal Model</title>
  </head>

  <body>
    <h1>Requirements of the POSIX Signal Model</h1>

    <p>The following is a very brief description of the POSIX signal
    model and its requirements when implemented in the Linux kernel.
    Section 2.4 <q>Signal Concepts</q> of XSH in POSIX
    1003.1-2001.</p>

    <p>Signals can be generated for a specific thread or for the
    process:</p>

    <blockquote>
      <p>2.4.1 Signal Generation and Delivery</p>

      <p>[...]At the time of generation, a determination shall be made
      whether the signal has been generated for the process or for a
      specific thread within the process. Signals which are generated
      by some action attributable to a particular thread, such as a
      hardware fault, shall be generated for the thread that caused
      the signal to be generated. Signals that are generated in
      association with a process ID or process group ID or an
      asynchronous event, such as terminal activity, shall be
      generated for the process.</p>
    </blockquote>


    <p>The basic concept behind the POSIX signal model is that</p>

    <ul>
      <li>signal handlers are a process resources; and</li>

      <li>signal masks are a thread resources</li>
    </ul>


    <p>This means that for signals which have to be delivered to a
    thread not much changes from the single thread process model.  If
    the signal is not ignored it remains pending.  Otherwise it is
    delivered when possible.  Implementations don't have to look at
    the signal right away since</p>

    <blockquote>
      <p>2.4.1 Signal Generation and Delivery</p>

      <p>[...]The determination of which action is taken in response to a
      signal is made at the time the signal is delivered, allowing for
      any changes since the time of generation.</p>
    </blockquote>


    <h2>Signals For Threads</h2>

    <p>Some signals are intended for one thread only when generated in the
    usual way (not synthesized using kill(2) etc).  The list
    includes:</p>

    <ul>
      <li><tt>SIGBUS</tt></li>
      <li><tt>SIGILL</tt></li>
      <li><tt>SIGFPE</tt></li>
      <li><tt>SIGSEGV</tt></li>
      <li><tt>SIGTRAP</tt></li>
    </ul>


    <h2>Special Signals</h2>

    <p>The signal <tt>SIGSTOP</tt>, <tt>SIGTSTP</tt>,
    <tt>SIGTTIN</tt>, <tt>SIGTTOU</tt>, and <tt>SIGCONT</tt> must be
    treated speical.  They all effect the process and must be handled
    in the kernel.  All threads must be stopped on any of the stop
    signals.  After a <tt>SIGCONT</tt> all pending stop signals must
    be discarded (and vice versa).</p>


    <h2>Delivering a Signal to a Process</h2>

    <p>To determine whether a signal, which has to be delivered to the
    process, is blocked by all threads a <q>process signal mask</q>
    must be computed.  Note that no such thing exists.  It is the
    logical and combination of all the signal masks of the threads.
    Delays during signal delivery are not wanted so the process signal
    mask could perhaps have an actual representation in an
    implementation.  There are several possibilities.  Before we
    describe those one more fact:</p>

    <blockquote>
      <p>2.4.1 Signal Generation and Delivery</p>

      <p>[...]The signal mask for a thread shall be initialized from that
      of its parent or creating thread, or from the corresponding
      thread in the parent process if the thread was created as the
      result of a call to <tt>fork()</tt>.</p>
    </blockquote>

    <p>With this information an implementation of the process signal
    mask can be outlined:</p>

    <ul>
      <li>Represent the process signal mask with counters.  Every
      thread, which does not (or does?) block a signal increments the
      counter.  This makes it easy to create new threads (increment
      according to the parent's signal mask), destroy a thread
      (decrement according to the thread's own mask), or test (counter greater
      than zero).</li>

      <li>Define the process signal mask as a normal bitset.  This
      saves memory but requires more computation.  If a new thread is
      created the process mask doesn't change.  But recomputations are
      needed when the mask of a thread is changed or if a thread
      terminates (in the latter case only the bits for signals which
      are not blocked can change in the process signal mask).  When computing
      the process signal mask it is only necessary to find one thread
      which doesn't block the signal.  Once found the search can be
      stopped.</li>
    </ul>

    <p>In both cases is it still necessary at signal-delivery time to
    find a thread which can receive the signal.  In a good
    implementation the signal is not always delivered to the same
    thread if this would cause delays.  As long as there is a thread
    which does not block the signal the signal should be delivered
    right away.</p>

    <p><b>Example:</b> in realtime systems it is common to improve
    signal response time by creating multiple threads which normally
    do no work except calls to <tt>sigwait()</tt> to handle signals if
    they arrive.</p>

    <p>Note also that a call to <tt>sigwait()</tt> temporarily extends
    the threads's signal mask and therefore implicitly the process' signal
    mask.</p>

    <p>If all threads have the signal blocked and the action is not to
    ignore the signal, it remains pending.  If the signal is blocked
    the implementation is free to act on this whenever it wants:</p>

    <blockquote>
      <p>2.4.1 Signal Generation and Delivery</p>

      <p>[...] If the action associated with a blocked signal is to
      ignore the signal and if that signal is generated for the
      process, it is unspecified whether the signal is discarded
      immediately upon generation or remains pending.</p>
    </blockquote>
  </body>
</html>
