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