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

名称

rwlock, rw_init, rw_init_flags, rw_destroy, rw_rlock, rw_wlock, rw_runlock, rw_wunlock, rw_unlock, rw_try_rlock, rw_try_upgrade, rw_try_wlock, rw_downgrade, rw_sleep, rw_initialized, rw_wowned, rw_assert, RW_SYSINITカーネル読み込み側/書き込み側 (reader/writer) ロック

書式

#include < sys/param.h>
#include < sys/lock.h>
#include < sys/rwlock.h>

void
rw_init( struct rwlock *rw, const char *name);

void
rw_init_flags( struct rwlock *rw, const char *name, int opts);

void
rw_destroy( struct rwlock *rw);

void
rw_rlock( struct rwlock *rw);

void
rw_wlock( struct rwlock *rw);

int
rw_try_rlock( struct rwlock *rw);

int
rw_try_wlock( struct rwlock *rw);

void
rw_runlock( struct rwlock *rw);

void
rw_wunlock( struct rwlock *rw);

void
rw_unlock( struct rwlock *rw);

int
rw_try_upgrade( struct rwlock *rw);

void
rw_downgrade( struct rwlock *rw);

int
rw_sleep( void *chan, struct rwlock *rw, int priority, const char *wmesg, int timo);

int
rw_initialized( const struct rwlock *rw);

int
rw_wowned( const struct rwlock *rw);


options INVARIANTS
options INVARIANT_SUPPORT
void
rw_assert( const struct rwlock *rw, int what);

#include < sys/kernel.h>

RW_SYSINIT( name, struct rwlock *rw, const char *desc);

解説

読み込み側/書き込み側 (reader/writer) ロックによって、複数のスレッドによって保護されたデータへの共有アクセスができるか、または単一のスレッドによって排他的なアクセスができます。共有アクセスがあるスレッドは、それらが保護されたデータを読み込めるだけであるので、 reader として知られています。排他的なアクセスがあるスレッドは、保護されたデータを変更することができるので、 writer として知られています。

読み込み側/書き込み側 (reader/writer) ロックは、 sx(9) ロックとよく似ているように見えますが、それらの使用法のパターンは異なっています。共有/排他的セマンティクスでミューテックス (mutex) ( mutex(9) を参照) として、読み込み側/書き込み側 (reader/writer) ロックを取りを扱うことができます。 sx(9) と異なって、非 spin ミューテックスを保持している間に rwlock をロックすることができ、スリープしている間に、 rwlock を保持することはできません。 rwlock ロックには、ミューテックスのような優先権伝播がありますが、優先権を書き込み側のみ伝播することができます。この制限は、読み込み側が匿名であるという事実によります。別の重要な特性は、読み込み側が、常に繰り返すことがができることであり、排他的ロックを選択的に繰り返すことができます。

マクロと関数

rw_init( struct rwlock *rw, const char *name)
名前 name によって説明される、読み込み側/書き込み側 (reader/writer) ロックとして rw に位置する構造体を初期化します。説明は、もっぱらデバッグの目的に使用されます。この関数は、ロックにおいて任意の他の操作の前に呼び出されなければなりません。
rw_init_flags( struct rwlock *rw, const char *name, int opts)
ちょうど rw_init() 関数のような rw ロックを初期化しますが、 opts 引数を通して、 rw の振る舞いを変更するための 1 組のオプションのフラグの指定します。次のフラグの 1 つ以上を含みます:
RW_DUPOK
witness (目撃者) は、獲得される複製されたロックに関するメッセージをログ記録するべきではありません。
RW_NOPROFILE
このロックのプロファイルを行いません。
RW_NOWITNESS
このロックを無視するように witness(4) に指示します。
RW_QUIET
ktr(4) を通してこのロックのための任意の操作をログ記録しません。
RW_RECURSE
スレッドは、 rw のために排他的なロックを再帰的に獲得できます。
rw_rlock( struct rwlock *rw)
読み込み側 (reader) として rw をロックします。任意のスレッドが排他的にこのロックを保持するなら、現在のスレッドは、ブロックし、その優先権は、排他的な保持者に伝播されます。スレッドが rw で既に読み込み側 (reader) アクセスを取得しているとき、 rw_rlock() 関数を呼び出すことができます。これは、“ロックでの繰り返し” (recursing on a lock) と呼ばれます。
rw_wlock( struct rwlock *rw)
書き込み側 (writer) として rw をロックします。ロックの共有された所有者がいるなら、現在のスレッドは、ブロックします。 RW_RECURSE オプションが有効にされている状態で rw が初期化された場合にだけ、 rw_wlock() 関数を再帰的に呼び出すことができます。
rw_try_rlock( struct rwlock *rw)
読み込み側 (reader) として rw をロックしようとします。この関数は、操作が成功するなら、真を返し、そうでなければ、0 を返します。
rw_try_wlock( struct rwlock *rw)
書き込み側 (writer) として rw をロックしようとします。この関数は、操作が成功するなら、真を返し、そうでなければ、0 を返します。
rw_runlock( struct rwlock *rw)
この関数は、以前に rw_rlock() によって獲得された共有されたロックを解放します。
rw_wunlock( struct rwlock *rw)
この関数は、以前に rw_wlock() によって獲得された排他的なロックを解放します。
rw_unlock( struct rwlock *rw)
この関数は、以前に rw_rlock() によって獲得された共有ロックか、または以前に rw_wlock() によって獲得された排他的なロックを解放します。
rw_try_upgrade( struct rwlock *rw)
単一の共有されたロックを排他的なロックにアップグレードすることを試みます。現在のスレッドは、 rw の共有されたロックを保持していなければなりません。現在のスレッドが rw で共有されたロックのみを保持している場合にだけ、これは成功し、単一の共有されたロックのみを保持します。試みが成功するなら、 rw_try_upgrade() は、0 以外の値を返し、現在のスレッドは、排他的なロックを保持します。試みが失敗するなら、 rw_try_upgrade() は、0 を返し、現在のスレッドは、そのまま共有されたロックを保持します。
rw_downgrade( struct rwlock *rw)
排他的なロックを単一の共有されたロックに変換します。現在のスレッドは、 rw の排他的なロックを保持していなければなりません。
rw_sleep( void *chan, struct rwlock *rw, int priority, const char *wmesg, int timo)
イベントを待っている間に、不可分に rw を解放します。この関数へのパラメータに関するより詳しい情報については、 sleep(9) を参照してください。
rw_initialized( const struct rwlock *rw)
この関数は、 rw が初期化されたなら 0 以外を返し、そうでなければ、0 を返します。
rw_destroy( struct rwlock *rw)
この関数は、以前に rw_init() で初期化されたロックを破壊します。 rw ロックは、アンロックされていなければなりません。
rw_wowned( const struct rwlock *rw)
この関数は、現在のスレッドが rw で排他的なロックを所有しているなら、0 以外を返します。
rw_assert( const struct rwlock *rw, int what)
この関数によって、 what で指定されたアサーションを、 rw に関して行うことができます。アサーションが真でなく、カーネルが options INVARIANTSoptions INVARIANT_SUPPORT でコンパイルされているなら、カーネルは、パニックします。現在、次の基本的なアサーションがサポートされています:
RA_LOCKED
現在のスレッドが rw の共有されるか、または排他的なロックを保持しているかアサートします。
RA_RLOCKED
現在のスレッドが、 rw の共有されたロックを保持しているかアサートします。
RA_WLOCKED
現在のスレッドが、 rw の排他的なロックを保持しているかアサートします。
RA_UNLOCKED
現在のスレッドが、 rw の共有されたロックも排他的なロックも保持していないかアサートします。

さらに、次のオプションのフラグの 1 つは、 RA_LOCKED, RA_RLOCKED または RA_WLOCKED で指定されます:

RA_RECURSED
現在のスレッドが、 rw の再帰的なロックを保持することをアサートします。
RA_NOTRECURSED
現在のスレッドが、 rw の再帰的なロックを保持しないことをアサートします。

歴史

これらの関数は FreeBSD 7.0 で登場しました。

作者

rwlock 機能は John Baldwin によって書かれました。このマニュアルページは Gleb Smirnoff によって書かれました。

バグ

WITNESS がカーネルに含まれていないなら、現在のスレッドが読み込み側 (reader) ロックを保持しているか保持していないかをアサートすることは不可能です。 WITNESS がない場合には、 RA_LOCKEDRA_RLOCKED アサーションは、単に、いくつかのスレッドが、単に読み込み側 (reader) ロックを保持しているかをチェックします。

読み込み側/書き込み側 (reader/writer) は、ちょっとまずい名前です。また、お好みで、 rwlock は、“Robert Watson”ロックとも呼ばれます。

June 20, 2013 FreeBSD