EN JA
LOCK(9)
LOCK(9) FreeBSD Kernel Developer's Manual LOCK(9)

名称

lockinit, lockdestroy, lockmgr, lockmgr_args, lockmgr_args_rw, lockmgr_disown, lockmgr_printinfo, lockmgr_recursed, lockmgr_rw, lockmgr_waiters, lockstatus, lockmgr_assertlockmgr 関数ファミリ

書式

#include < sys/types.h>
#include < sys/lock.h>
#include < sys/lockmgr.h>

void
lockinit( struct lock *lkp, int prio, const char *wmesg, int timo, int flags);

void
lockdestroy( struct lock *lkp);

int
lockmgr( struct lock *lkp, u_int flags, struct mtx *ilk);

int
lockmgr_args( struct lock *lkp, u_int flags, struct mtx *ilk, const char *wmesg, int prio, int timo);

int
lockmgr_args_rw( struct lock *lkp, u_int flags, struct rwlock *ilk, const char *wmesg, int prio, int timo);

void
lockmgr_disown( struct lock *lkp);

void
lockmgr_printinfo( const struct lock *lkp);

int
lockmgr_recursed( const struct lock *lkp);

int
lockmgr_rw( struct lock *lkp, u_int flags, struct rwlock *ilk);

int
lockmgr_waiters( const struct lock *lkp);

int
lockstatus( const struct lock *lkp);


options INVARIANTS
options INVARIANT_SUPPORT
void
lockmgr_assert( const struct lock *lkp, int what);

解説

lockinit() 関数は、ロックを初期化するために使用されます。これは、ロックに関する実行されることが可能なあらゆる操作の前に、呼び出されなければなりません。引数は、次の通りです:
lkp
初期化されるべきロックへのポインタです。
prio
sleep(9) に渡される優先度です。
wmesg
ロックのメッセージです。これは、デバッグ出力と sleep(9) の両方のために使用されます。
timo
sleep(9) に渡されるタイムアウト値です。
flags
ロックのフラグは、次で初期化されます:
LK_ADAPTIVE
カーネルが ADAPTIVE_LOCKMGRS オプションでコンパイルされているなら、このロックに適応できるスピニング (spinning) を有効にします。
LK_CANRECURSE
排他的なロックで再帰を許可します。
LK_NOPROFILE
このロックのためのロックプロファイルを無効にします。
LK_NOSHARE
排他的なロックのみを許可します。
LK_NOWITNESS
このロックを無視するように witness(4) に指示します。
LK_NODUP
witness(4) は、獲得される複製のロックに関するメッセージをログ記録するべきです。
LK_QUIET
このロックのための ktr(4) ログ記録を無効にします。
LK_TIMELOCK
スリープの間に、 timo を使用します。そうでなければ、0 が使用されます。

lockdestroy() 関数は、ロックを破壊するために使用され、カーネル内のいくつかの場所で呼び出されますが、現在は、何もしません。

lockmgr() と lockmgr_rw() 関数は、共有ロックと排他ロック、および再帰のサポートを含んで、カーネル内部の一般的なロックの機能を取り扱います。 lockmgr() と lockmgr_rw() は、ロックのアップグレードとダウングレードも可能です。

それらの引数は、次の通りです:

lkp
操作するべきロックへのポインタです。
flags
行なわれるべき操作を示しているフラグです。
LK_SHARED
共有ロックを獲得します。現在、排他的ロックが保持されているなら、 EDEADLK が返されます。
LK_EXCLUSIVE
排他的なロックを獲得します。既に排他的なロックが保持され、 LK_CANRECURSE が設定されていないなら、システムは、 panic(9) となります。
LK_DOWNGRADE
排他的なロックを共有ロックにダウングレードします。共有ロックのダウングレードは、許可されていません。排他的ロックが再帰的に処理されているなら、システムは、 panic(9) となります。
LK_UPGRADE
排他ロックへの共有ロックを更新します。この呼び出しが失敗するなら、たとえ LK_NOWAIT フラグが指定されても、共有ロックは、失われます。更新の間に、共有ロックは、一時的に落ちるかもしれません。排他ロックを更新する試みは、 panic(9) を引き起こします。
LK_TRYUPGRADE
共有ロックを排他的ロックに更新するように試みます。更新の失敗は、共有ロックの所有権を落す結果となりません。
LK_RELEASE
ロックを解放します。保持していないロックの解放は、 panic(9) を引き起こすことがあります。
LK_DRAIN
ロック上の全ての行動の終了を待ち、それから役割を終えた印を付けます。今にも解放されようとしているメモリの一部分のロックを解放する前に使用されます。 ( < sys/lockmgr.h> に解説されています。)
LK_SLEEPFAIL
操作がスリープした場合には、失敗します。
LK_NOWAIT
この呼び出しがスリープすることを認めません。これは、ロックをテストするために使用することが可能です。
LK_NOWITNESS
このインスタンスのための witness(4) チェックをスキップします。
LK_CANRECURSE
排他的なロックで繰り返しを許可します。それぞれのロックごとに、それらは、解放されなければなりません。
LK_INTERLOCK
(既にロックされるべき) 相互ロックをアンロックします。
ilk
ロックへのグループアクセスを制御するための相互ロックミューテックス (mutex)。 LK_INTERLOCK が指定されるなら、 lockmgr() と lockmgr_rw() は、 ilk が、現在所有されていて再帰していないと仮定し、ロック解除されて返ります。 mtx_assert(9) を参照してください。

lockmgr_args() と lockmgr_args_rw() 関数は、 lockmgr() と lockmgr_rw() のように動作しますが、インスタンスベース毎に wmesg, timoprio を受け付けます。指定された値は、デフォルトのものを上書きしますが、それぞれ LK_WMESG_DEFAULT, LK_PRIO_DEFAULTLK_TIMO_DEFAULT を渡すためにまだこれを使用することができます。

lockmgr_disown() 関数は、ロックが既に保持されているなら、 LK_KERNPROC になるように現在のスレッドから所有者を切り換えます。

lockmgr_printinfo() 関数は、ロックに関するデバッグ情報を印刷 (表示) します。それは、主に VOP_PRINT(9) 関数によって使用されます。

lockmgr_recursed() 関数は、ロックが再帰されているなら、真を返し、そうでなければ、0 を返します。

lockmgr_waiters() 関数は、ロックにウェートしているものがあるなら、真を返し、そうでなければ、0 を返します。

lockstatus() 関数は、現在のスレッドと関連しているロックの状態を返します。

options INVARIANTSoptions INVARIANT_SUPPORT でコンパイルされるとき、 lockmgr_assert() 関数は、 what で指定されたアサーションのために lkp をテストし、それらに会わないなら、パニックします。次のアサーションの 1 つを指定しなければなりません:

KA_LOCKED
現在のスレッドには、最初の引数によって指された lkp ロックで共有ロックまたは排他ロックのいずれかがあるか、アサートします。
KA_SLOCKED
現在のスレッドには、最初の引数によって指された lkp ロックで共有ロックがあるか、アサートします。
KA_XLOCKED
現在のスレッドには、最初の引数によって指された lkp ロックで排他ロックがあるか、アサートします。
KA_UNLOCKED
現在のスレッドには、最初の引数によって指された lkp ロックでロックがまったくないか、アサートします。

さらに、 KA_LOCKED, KA_SLOCKED または KA_XLOCKED アサーションのいずれかで次のオプションのアサーションの 1 つを使用することができます:

KA_RECURSED
現在のスレッドには、 lkp で再帰的なロックがあるか、アサートします。
KA_NOTRECURSED
現在のスレッドが lkp で再帰的なロックがないか、アサートします。

戻り値

lockmgr() と lockmgr_rw() 関数は、成功すれば 0 を、失敗すれば 0 以外を返します。

lockstatus() 関数は、次の値を返します:

LK_EXCLUSIVE
排他ロックが現在のスレッドによって保持されています。
LK_EXCLOTHER
排他ロックが現在のスレッドではない他の誰かによって保持されています。
LK_SHARED
共有ロックが保持されています。
0
ロックを、だれも保持していません。

エラー

lockmgr() と lockmgr_rw() は、次の場合に失敗します:
[ EBUSY]
LK_FORCEUPGRADE が要求され、別のスレッドが既にロックの更新を要求していました。
[ EBUSY]
LK_NOWAIT が設定され、スリープが要求されたか、または LK_TRYUPGRADE 操作が、ロックを更新することができませんでした。
[ ENOLCK]
LK_SLEEPFAIL が設定され、 lockmgr() または lockmgr_rw() が、スリープしていました。
[ EINTR]
PCATCH がロックの優先度で設定され、シグナルが、スリープしている間に配信されました。下記の ERESTART エラーに注意してください。
[ ERESTART]
PCATCH がロックの優先度で設定され、シグナルが、スリープしている間に配信され、システムコールが、再開されることになっている。
[ EWOULDBLOCK]
0 でないタイムアウトが与えられ、タイムアウトが満了しました。

ロック

LK_INTERLOCKlockmgr() または lockmgr_rw() への flags 引数に渡されるなら、 ilk は、 lockmgr() または lockmgr_rw() を呼び出すために以前に保持されていなければならず、ロック解除されて返ります。

現在、保持されているロックが失われる結果で失敗した更新の試み。また、排他的なロックを更新することが、無効で、 panic(9) が試みの結果となります。

作者

このマニュアルページは、 Chad David <davidc@acns.ab.ca>によって書かれました。
October 6, 2013 FreeBSD