スポンサーリンク

SPL(9) FreeBSD カーネル開発者マニュアル SPL(9)

名称

splbio, splclock, splhigh, splimp, splnet, splsoftclock, splsofttty, splstatclock, spltty, splvm, spl0, splx − 割り込み優先度の操作

書式

#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);

解説

この API は推奨されていません。データ構造を保護するためには、代わりに mutex を使用します。詳細情報は mutex(9) を参照してください。

spl() 関数ファミリは CPU の割り込み優先度の ‘‘レベル’’ を設定します。これ はブロックされた優先度レベルの割り込みハンドラの実行を抑制します。割り込 みハンドラによって調査あるいは修正されたであろうデータ領域を調査あるいは 修正するドライバの ‘‘synchronous’’ 部分(ユーザプロセスを代表して実行され る部分)で使用されます。

通常それぞれの割り込みを使用するドライバは、 config ファイルのキーワード によって 1 つの割り込み優先度グループに割り当てられます。例えば、

      device foo0 at isa? port 0x0815 irq 12 tty

は、割り込み 12 を ‘‘tty’’ 優先度グループに割り当てます。システムは自動的 に xxx グループの割り込みを優先度が splxxx () 以上の時に呼ばれるように準 備します。

splx() 関数は割り込み優先度レベルを絶対的な数値に設定します。これは別の割 り込みレベル関数が返した値をローカルの変数に保存して、後で元の優先度レベ ルに戻すために splx() を使用する事を意図しています。

spl0() 関数は全ての割り込みハンドラをブロックしない値に優先度を減少させま す。ただし、AST(非同期システムトラップ)はシステムがユーザモードに戻るまで の間はブロックされます。

いろいろなデバイスドライバの割り込み優先度グループの伝統的な割り当ては、 おおよそ次のように分類できます。

       splnet()

ネットワークインタフェースドライバのソフトウェア部分。

splimp()
全てのネットワークインタフェースドライバ。

splbio()
全ての バッファ入出力 (つまりディスクなど)のドライバ。

spltty()
基本的にはネットワーク以外の通信デバイスですが、事実上 はネットワークとディスク以外の全てのドライバ。

戻り値

splx() および spl0() 以外の全ての関数は、操作前の優先度の値を返します。

使用例

以下は、標準的な使用例です。

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)) {

/* 準備ができていません、待機しなければなりません */

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)

/* 誰かが我々を待っています、起こしてください */

wakeup(sc);

...

}
割り込みハンドラは 絶対に優先度レベルを減少させるべきではない、ということ に注意してください。自動的に、自分のレベルの割り込み優先度に増加させられ ます。すなわち、同じグループの全ての割り込みはブロックされます。

歴史

割り込み優先度レベルは早期のバージョンの UNIX で登場しました。伝統的には 名前ではなく数字が使われていて、そのレベルまでの全てを含んで (優先度 5 は レベル 5 までの全てをブロックします)いた事が知られています。これは FreeBSD にはあてはまりません。伝統的な名前 ‘level’ はいまだに文字 ‘l’ と してそれぞれの関数や変数の名前に反映されています。しかし、実際にはもはや レベルではなく、むしろ異なった(部分的に含まれた)関数群がシステムのある期 間ブロックされます。歴史的な番号による方法は単純で順番通りの割り込み優先 度レベルグループであるとみなす事ができます。

作者

このマニュアルページは Jörg Wunsch が書きました。

FreeBSD 10.0 July 21, 1996 FreeBSD 10.0

スポンサーリンク