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_assert — lockmgr 関数ファミリ書式
#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, timo と prio を受け付けます。指定された値は、デフォルトのものを上書きしますが、それぞれ LK_WMESG_DEFAULT, LK_PRIO_DEFAULT と LK_TIMO_DEFAULT を渡すためにまだこれを使用することができます。
lockmgr_disown() 関数は、ロックが既に保持されているなら、 LK_KERNPROC になるように現在のスレッドから所有者を切り換えます。
lockmgr_printinfo() 関数は、ロックに関するデバッグ情報を印刷 (表示) します。それは、主に VOP_PRINT(9) 関数によって使用されます。
lockmgr_recursed() 関数は、ロックが再帰されているなら、真を返し、そうでなければ、0 を返します。
lockmgr_waiters() 関数は、ロックにウェートしているものがあるなら、真を返し、そうでなければ、0 を返します。
lockstatus() 関数は、現在のスレッドと関連しているロックの状態を返します。
options INVARIANTS と options 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_INTERLOCK が lockmgr() または lockmgr_rw() への flags 引数に渡されるなら、 ilk は、 lockmgr() または lockmgr_rw() を呼び出すために以前に保持されていなければならず、ロック解除されて返ります。現在、保持されているロックが失われる結果で失敗した更新の試み。また、排他的なロックを更新することが、無効で、 panic(9) が試みの結果となります。
関連項目
condvar(9), locking(9), mutex(9), rwlock(9), sleep(9), sx(9), mtx_assert(9), panic(9), VOP_PRINT(9)作者
このマニュアルページは、 <davidc@acns.ab.ca>によって書かれました。October 6, 2013 | FreeBSD |