Museum

Home

Lab Overview

Retrotechnology Articles

Online Manuals

⇒ spl(K) — System V/386 Software Development System 3.2.2b

Media Vault

Software Library

Restoration Projects

Artifacts Sought



     SPL(K)                    UNIX System V                    SPL(K)



     Name
          spl: spl0, spl1, spl2, spl3, spl4, spl5, spl6, spl7, splbuf,
          splcli, splhi, splni, splpp, spltty, splx - block/permit
          interrupts

     Syntax
          int              int             int              int
          spl0()           spl4()          splbuf()         splpp()

          int              int             int              int
          spl1()           spl5()          splcli()         spltty()

          int              int             int
          spl2()           spl6()          splhi()

          int              int             int
          spl3()           spl7()          splni()


          int
          splx(oldspl)
          int oldspl;

     Description
          In many drivers, a need exists to protect sections of code
          from an interrupt occuring and causing a context switch.
          Protecting code sections ensures the integrity of the kernel
          and its data structures.  The spl1, spl2, spl3, spl4, spl5,
          spl6, spl7, splbuf, splcli, splni, splpp and spltty routines
          prevent specific levels of interrupts from occuring.  The
          following table describes each of the spl routines:

     _________________________________________________________________________
    | Routine|  IPL|  Description                                            |
    |________|_____|_________________________________________________________|
    | spl0   |   0 |  Permit all interrupts to occur                         |
    |________|_____|_________________________________________________________|
    | spl1   |   1 |  Prevent interrupts from context and process switches   |
    |________|_____|_________________________________________________________|
    | spl2   |   2 |  Prevent priority level 2 interrupts                    |
    |________|_____|_________________________________________________________|
    | spl3   |   3 |  Prevent priority level 3 interrupts                    |
    |________|_____|_________________________________________________________|
    | spl4   |   4 |  Prevent character device interrupts                    |
    |________|_____|_________________________________________________________|
    | spl5   |   5 |  Prevent interrupts from character devices,             |
    | splcli |     |  from a ports card, and from tty devices.               |
    | splpp  |     |                                                         |
    |________|_____|_________________________________________________________|
    | spl6   |   6 |  Prevent interrupts from block devices, network devices,|
    | splbuf |     |  and the clock.                                         |
    | splni  |     |                                                         |
    |________|_____|_________________________________________________________|
    | spltty |   7 |  Prevent tty interrupts (and the clock)                 |
    |________|_____|_________________________________________________________|
    | spl7   |   8 |  Prevent all interrupts                                 |
    | splhi  |     |                                                         |
    |________|_____|_________________________________________________________|
    | splx   |   - |  Restore interrupt level to a former level              |
    |________|_____|_________________________________________________________|

          IPL stands for interrupt priority level.  The IPL value for
          a device is set on its card.

          spl0 permits all interrupts to occur.  splx restores the
          interrupt level to that specified by its argument oldspl.
          Use of spl0 is not encouraged because by restoring all
          interrupts, you may undo a previously set level by a kernel
          process or routine calling your driver.  Use splx whenever
          possible to restore a previously set level.  When coding an
          interrupt routine, only use splx.

          The spl5 and splcli routines prevent interrupts associated
          with tty devices and those that use character lists (clists)
          to buffer data. spl5 is provided for backward compatibility
          only.  If you are writing a serial device driver, use splcli
          whenever possible.  splcli should be used to protect
          critical sections of code which manipulate clist structures
          or pointers.  It is possible that a device driver's xxpoll
          routine will preempt another driver while it is manipulating
          clists.  If your xxpoll routine manipulates clist
          structures, you should exercise care to make sure that your
          routine was not entered at an spl level higher than 5.

          Otherwise you may corrupt the kernel cfreelist.  Do not
          manipulate clists in an interrupt routine.  It is not
          necessary to use splcli before calling  any of the cblock or
          clist routines  (the routines on the getc(K) and putc(K)
          manual pages) because these routines raise the system
          priority level before entering their critical sections and
          then restore it to its previous value before they return.
          It is only necessary for you to use splcli if you are
          directly manipulating fields in a clist structure or the
          freelist. You should only do this if you have extensive
          experience with character device drivers.

          The spl6, splni, and splbuf routines mask all interrupts
          except for those from the serial device. These routines
          prevents block device interrupts from occuring.  These
          routines block the system clock and should be used sparingly
          because if the code it is protecting takes longer than two
          clock ticks to execute, the system clock is degraded.

          The spltty routine blocks interrupts from a serial device.

          The spl7 and splhi routines disable all interrupts.  Use
          this routine only for extremely short periods when updating
          critical data structures that could be accessed by a high
          priority device.  These routines also block the system clock
          and should not be allowed to execute longer than a single
          clock tick.

          The splx routine restores a previously set interrupt
          priority level.

     Parameters
          The integer oldspl specifies a previous spl level, it should
          only be set by the return value of a previous spl routine.

     Warnings
          The interrupt priority level in an interrupt routine must
          not be dropped below the level at which the interrupt
          occurred or the stack may become corrupted causing a system
          panic or loss of data.  Use of spl0 is not recommended as it
          can lower previously set priority levels used by other
          kernel processes.  Always store the previous priority level
          returned by the spl call and use splx to restore the
          previous level at the end of your critical code section.
          The spl7 and splhi routines block all interrupts.  While
          these routines are in effect, the following happens:

           +   Clock interrupts do not occur.

           +   Characters are not echoed back to the console.

           +   The capslock, numlock, and scrolllock indicators do not
               work.

           +   Multi-screens cannot be switched.

           +   If your driver hangs during this interval, the machine
               must be power-cycled to regain control.

     Return Value
          The previous spl value is returned.  It should be saved and
          used to restore the spl level by a subsequent call to splx.

     Notes
          Use of spl6, spl7, and splhi can cause the software clock to
          lose time and prevents other device drivers' xxpoll routines
          from being called.  This may have an unpredictable effect on
          the behavior of other device drivers that require periodic
          execution of their xxpoll routines.

     Example
          The following code fragments show how to check an spl level
          in an xxpoll routine and demonstrate the use of splcli in a
          task time routine.

          /*
           * This macro tells us if the previous spl level was "lev"
           * or higher. PS_PRIMASK is defined in sys/param.h.
           */
          #define ATSPL(lev,ps) ((ps) >= lev)

          xxpoll(ps)
          {
          /*
           * If we were at spl5 or higher before the clock tick, leave!
           */
                  if (ATSPL(5,ps)) {
                          return;
                  }
          /*
          ** end xxpoll fragment.
          */

          /*
           * xxread(), xxwrite(), xxopen(), xxclose, and
           * xxioctl() are all examples of task time routines
           */
          xxread(dev)
          int dev;
          {
              int oldspl;

              /* set new spl and save old level in oldspl */
              oldspl = splcli();
              .
              .   /* perform clist operations */
              .
              /* restore saved spl */
              splx(oldspl);
              .
              .
              .
          /*
          ** end task time fragment.
          */
          }

                                                      (printed 7/7/89)



Typewritten Software • bear@typewritten.org • Edmonds, WA 98026