spl(9)
NAME
- splbio, splclock, splhigh, splimp, splnet, splsoftclock,
- splsofttty,
 splstatclock, spltty, splvm, spl0, splx - manipulate inter
- rupt 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 spl() function family sets the interrupt priority ``lev
- el'' of the
 CPU. This prevents interrupt handlers of the blocked prior
- ity 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 han
- dlers.
- Each driver that uses interrupts is normally assigned to an
- interrupt
 priority group by a keyword in its config line. For exam
- ple:
 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 abso
- lute 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 or
- der 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 pri
- ority 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 ver
- sion 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 re
- flected in the
 letter `l' of the respective functions and variables, al
- though 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.
AUTHORS
- This manual page was written by Jorg Wunsch.
- BSD July 21, 1996