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
Copyright © 2010-2024 Platon Technologies, s.r.o.           Home | Man pages | tLDP | Documents | Utilities | About
Design by styleshout