2008年5月25日

LTSLEEP(9)和訳

NetBSD2.1のマニュアルページ; LTSLEEP(9) を和訳してみる。


LTSLEEP(9) NetBSD Kernel Developer's Manual


NAME
ltsleep, tsleep, wakeup - プロセスコンテキストのsleepとwakeup

SYNOPSIS
#include

int
ltsleep(const void *ident, int priority, const char *wmesg, int timo,
__volatile struct simplelock *slock);

int
tsleep(const void *ident, int priority, const char *wmesg, int timo);

void
wakeup(const void *ident);

DESCRIPTION
これらの関数は、自発的なコンテキストスイッチを実現する。ltsleep()とtsleep()は現在のコンテキストが以下の理由で継続できない場合で使用される。
・カレントプロセスが、ペンディングされたI/Oオペレーションの結果を待つ必要がある
・カレントプロセスが、一時的に使用不可になっている資源(メモリ等)を必要とする
・カレントプロセスが、他のプロセスによりロックされているデータ構造にアクセスしようとしている。
wakeup()関数は、sleep状態になっているプロセスに可能な状態を通知するのに使用される。典型的に、起こされたプロセスは、(コンテキストを再び得た後)、"ブロッキングされた"状態がクリアになっていることを確認するようなリトライ処理を行う。

ltsleep()関数は以下の引数を持つ。
ident カレントプロセスがウェイトを行うリソースを表す"ウェイトチャネル"の識別子。典型的に、プロセスが競う資源に関連したカーネルのデータ構造の仮想アドレスとなる。同じ識別子がwakeup()でプロセスが再開する際に使用される。identはNULLであってはならない。

priority プロセスが起こされる際に使用されランニングプロセスキューにプットされるプロセスの優先度。このメカニズムはカーネルモードで実行されるプロセスの"スループット"を最適化するのに使用される。もしPCATCHがpriorityに指定された場合、プロセスはsleepする前後に渡されたシグナルをチェックする。もしPNORELOCKがpriorityに指定された場合、slockはプロセスがレジュームされた際にロックされない。

wmesg プロセスがsleepしている理由を表すための文字列へのポインタ。カーネルはこの文字列は使用しないが、ps(1)等のユーザレベルのユーティリティにおいて(プロセス構造体のp_wmesgフィールドによって)用いられる。

timo もし非ゼロだった場合、プロセスは最大で timo/hz 秒スリープする。もしこの時間が経過し、wakeup(ident)が実行されず、シグナルも送られなかった(PCATCHがセットされている場合)ときには、tsleep()はEWOULDBLOCKが返る。

tsleep()マクロは、機能的に以下と同等である。
ltsleep(ident, priority, wmesg, timo, NULL)

wakeup()関数は、識別子identで現在スリープしている全てのプロセスにマークする。結局、各プロセスはカーネルコンテキストで実行を再開され、tsleep()から返る。wakeup()はブロックされた状態を変更する可能性を通知するために、プロセスがスリープから戻った場合は再度ブロック条件を評価するべきである。例えば、2つ以上のプロセスが排他アクセスするロック(see lock(9))を待っている場合、そのうちの一つだけが、ロックが開放されたときにロックを取得することが可能である。他の全ては再度sleep状態となって次の機会を待つ必要がある。

返り値
ltsleep()は、wakeup()の結果として0を返す。もしltsleep()がシグナルによって返る時は、返り値はERESTARTになり、そうで無い場合はEINTRとなる。タイムアウトによりltsleep()が返る時は、EWOULDBLOCKが返る。

SEE ALSO
sigaction(2), hz(9), lock(9)

歴史
sleep/wakeupのプロセス同期のメカニズムは非常に古い。これはUnixの非常に初期のバージョンで導入された。tsleep()は、4.4BSDで導入された。ltsleep()はNetBSD1.5で導入された。