Provided by: freebsd-manpages_9.2+1-1_all bug

NAME

       splbio,  splclock,  splhigh, splimp, splnet, splsoftclock, splsofttty, splstatclock, spltty, splvm, spl0,
       splx — manipulate interrupt priorities

SYNOPSIS

       #include <sys/types.h>
       #include <sys/systm.h>

       intrmask_t
       splbio(void);

       intrmask_t
       splclock(void);

       intrmask_t
       splhigh(void);

       intrmask_t
       splimp(void);

       intrmask_t
       splnet(void);

       intrmask_t
       splsoftclock(void);

       intrmask_t
       splsofttty(void);

       intrmask_t
       splstatclock(void);

       intrmask_t
       spltty(void);

       void
       spl0(void);

       void
       splx(intrmask_t ipl);

DESCRIPTION

       This API is deprecated.  Use  mutexes  to  protect  data  structures  instead.   See  mutex(9)  for  more
       information.   The  API  is  now  a complete NOP.  This man page documents historical behavior so you can
       understand the code locking that the spl did when converting code from versions of the  kernel  prior  to
       FreeBSD  5.0.   The  examples  in this man page are also obsolete and should not be viewed as documenting
       FreeBSD 5.0 and newer.

       The spl() function family sets the interrupt priority  “level”  of  the  CPU.   This  prevents  interrupt
       handlers  of  the  blocked  priority  level  from being run.  This is used in the “synchronous” part of a
       driver (the part that runs on behalf of the user process) to examine or modify data areas that  might  be
       examined or modified by interrupt handlers.

       Each  driver that uses interrupts is normally assigned to an interrupt priority group by a keyword in its
       config line.  For example:

             device foo0 at isa? port 0x0815 irq 12 tty

       assigns interrupt 12 to the “tty” priority group.  The system automatically arranges  for  interrupts  in
       the xxx group to be called at a priority >= splxxx()

       The  function  splx()  sets  the  interrupt  priority to an absolute value.  The intent is that the value
       returned by the other functions should be saved in a local variable, and later passed to splx() in  order
       to restore the previous priority.

       The  function  spl0() lowers the priority to a value where all interrupt handlers are unblocked, but ASTs
       (asynchronous system traps) remain blocked until the system is about to return to user mode.

       The traditional assignment of the various device drivers to the interrupt priority groups can be  roughly
       classified as:

       splnet()          Software part of the network interface drivers.

       splimp()          All network interface drivers.

       splbio()          All buffered IO (i.e., disk and the like) drivers.

       spltty()          Basically, all non-network communications devices, but effectively used for all drivers
                         that are neither network nor disks.

RETURN VALUES

       All functions except splx() and spl0() return the previous priority value.

EXAMPLES

       This is a typical example demonstrating the usage:

       struct foo_softc {
               ...
               int flags;
       #define FOO_ASLEEP      1
       #define FOO_READY       2

       } foo_softc[NFOO];

       int
       foowrite(...)
       {
               struct foo_softc *sc;
               int s, error;

               ...
               s = spltty();
               if (!(sc->flags & FOO_READY)) {
                       /* Not ready, must sleep on resource. */
                       sc->flags |= FOO_ASLEEP;
                       error = tsleep(sc, PZERO, "foordy", 0);
                       sc->flags &= ~FOO_ASLEEP;
               }
               sc->flags &= ~FOO_READY;
               splx(s);

               ...
       }

       void
       foointr(...)
       {
               struct foo_softc *sc;

               ...
               sc->flags |= FOO_READY;
               if (sc->flags & FOO_ASLEEP)
                       /* Somebody was waiting for us, awake him. */
                       wakeup(sc);
               ...
       }

       Note that the interrupt handler should never reduce the priority level.  It is automatically called as it
       had  raised the interrupt priority to its own level, i.e., further interrupts of the same group are being
       blocked.

HISTORY

       The interrupt priority levels appeared in a very early version of Unix.   They  have  been  traditionally
       known  by  number  instead of by names, and were inclusive up to higher priority levels (i.e., priority 5
       has been blocking everything up to level 5).  This is no longer the case  in  FreeBSD.   The  traditional
       name  ‘level’  for  them  is still reflected in the letter ‘l’ of the respective functions and variables,
       although they are not really levels anymore, but rather different (partially inclusive) sets of functions
       to be blocked during some periods of the life of  the  system.   The  historical  number  scheme  can  be
       considered as a simple linearly ordered set of interrupt priority groups.

       FreeBSD  5.0  eliminated  spl  entirely  in  favor  of  locking  primitives  which scale to more than one
       processor.

AUTHORS

       This manual page was written by Jörg Wunsch.

Debian                                            July 21, 1996                                           SPL(9)