DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
SCO OpenServer

spl(D3oddi)


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

Synopsis

int spl0();		int spl1();		int spl2();

int spl3(); int spl4(); int spl5();

int spl6(); int spl7(); int spltty();

#include <sys/stream.h>

int splstr();

int splx(int previous);

/* Routines provided for backwards compatibility - they will be retired in a later release. */

int splbuf(); int splcli(); int splhi();

int splni(); int splpp();

Description

The spl( ) functions block or allow servicing of interrupts on the processor on which the function is called. They are used in single-threaded drivers to protect critical code sections from specific levels of interrupts.

Arguments


previous
The previous spl level, returned by the other spl calls.

The spl* calls other than splx( ) do not take arguments.

Return values

spl0, spl1, spl2, spl3, spl4, spl5, splbuf, splcli, splhi, splni, splpp, splstr, and spltty return the previous spl value.

splx does not return a value.

Usage

The spl( ) calls set the processor priority level to protect critical code sections by preventing interrupts during the execution of the critical code. See ``Critical code section'' in HDK Technical Reference. Driver code sets the processor interrupt priority level so that interrupts less than or equal to the system priority level, spl, are disabled. Only higher numbered interrupts can then be received.

Note that, on multiprocessor systems, the spl( ) calls only set the priority level for the processor on which the code is executing. If it is possible for code executing on a different processor to access the same critical code, use spin locks to protect the resource; see ``Spin locks (ODDI)'' in HDK Technical Reference.


spl0
Permits all interrupts. Do not use this spl call in a driver, because it can undo a level previously set by a kernel process or routine calling your driver. Use splx( ) to restore a previously set level.

spl1, spl2, spl3, spl4
Prevents interrupts at spl levels 1, 2, 3, 4 (respectively) and below. These calls are seldom used in drivers.

spl5, splcli, splpp, splstr, spltty
Prevent interrupts at spl level 5 and below. Parallel, serial and disk device drivers, character list (clist) processing and STREAMS use spl level 5. Use spltty if you are writing a serial device driver, splstr if you are writing a STREAMS module; otherwise, use spl5.

Use spltty to prevent interrupts associated with character lists (clist structures that are used to buffer data). It is not necessary to use spltty before calling any of the cblock or clist routines (see the getc(D3oddi) and putc(D3oddi) manual pages) because they themselves raise and restore the system priority level around their critical sections.

Do not manipulate clists in an interrupt routine. A driver's poll(D2oddi) routine runs at spl level 6 and can preempt another driver while it is manipulating clists. If your xxpoll( ) routine manipulates clist structures, you should ensure that it was not entered at an spl level of 5 or higher, to avoid corrupting the cfreelist (the kernel list of free clist structures).


spl6, splbuf, splni
Prevent all interrupts at spl level 6 and below, including the system clock. Buffer caching, timeouts, and device driver poll(D2oddi) routines use spl level 6.

spl7, splhi
Prevent all levels of interrupts. Use these routines only for extremely short periods when updating critical data structures that could be accessed by a high priority device.

splx
Restores the interrupt level to the level specified by the argument previous.

Always store the previous priority level returned by an spl call and use splx to restore the previous level at the end of your critical code section (see ``Examples'' below).

Use of spl6, splbuf, splni, spl7 and splhi can cause the clock to lose time if the critical code section protected is too long. They also prevent other device drivers' poll( ) routines from being called. This may have an unpredictable effect on the behavior of other device drivers that require periodic execution of their poll( ) routines.

Be careful that code that executes in interrupt context does not drop the spl level below the level at which the interrupt occurred. This can corrupt the stack, which can cause loss of data or a system panic. The most common example of this is a driver's poll(D2oddi) foutine that manipulates clists. You should check the spl level at which poll( ) was called to guard against this (see ``Examples'' below).

Context and synchronization

Non-blockable, interrupt, initiator, or blockable context

Hardware applicability

The named spl functions are supported on all processors. Implementation of the numbered spl functions may vary across processors.

Version applicability

oddi: 1, 2, 3, 4, 5, 6

Differences between versions

On multiprocessor systems, the spl( ) calls only set the priority level for the processor on which the code is executing. If it is possible for code executing on a different processor to access the same critical code, use spin locks to protect the resource; see ``Spin locks (ODDI)'' in HDK Technical Reference.

With the high-precision system clock that is implemented in SCO OpenServer Release 5.0.6 and later, spl7( ) and splhi( ) do not disable the system clock as they do in earlier releases. See ``Clock, system'' in HDK Technical Reference for more information about the high-precision system clock.

Future directions

The following functions will be retired in a future release: splbuf( ), splcli( ), splhi( ), splni( ), splpp( ).

SVR5 DDI compatibility

Non-multiprocessing DDI versions support the spl functions documented on the spl(D3) manual page. Many of the names are different and numbered spl functions are not supported. In most cases, it is better to convert the driver to use a spin lock.

References

atomic(D3oddi), clockb(D3oddi), ilockb(D3oddi), lockb(D3oddi), MPSTR_QLOCK(D3str), MPSTR_STPLOCK(D3str), splstr(D3oddi), tc_tlock(D3oddi)

spl(D3)

``Synchronization primitives'' in HDK Technical Reference
``Critical code section'' in HDK Technical Reference

Examples

The following code fragment shows how to check an spl level in an xxpoll routine:
   #include <sys/ipl.h>
   

xxpoll(ps) { /* If we were at spl5 or higher before xxpoll was called, LEAVE! */ if (ps >= SPL5) return; }

The next code fragment demonstrates the use of spltty in a driver task-time routine:
   xxread(int dev);
   {
       /* set new spl and save old level in previous */
       int previous = spltty();
       .
       . /* perform clist operations */
       .
       /* restore saved spl */
       splx(previous);
       .
       .
       .
   }

19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 5 HDK - June 2005