日本語 man コマンド類 (ja-man-1.1j_5) と日本語 man ドキュメント (ja-man-doc-5.4 (5.4-RELEASE 用) など) をインストールすると、以下のような man コマンド閲覧、キーワード検索が コンソールからできるようになります。
4.11-RELEASE-K, 5.4-RELEASE-K, 5.5-RELEASE-K, 6.0-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K, 12.1-RELEASE-K は、 プライベート版 (小金丸が編集してまとめたもの) ですが、 より多くの翻訳したファイルが含まれています。 (5.4-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.4-RELEASE-K, 8.0-RELEASE-K から 8.4-RELEASE-K, 9.0-RELEASE-K から 9.3-RELEASE-K, 10.0-RELEASE-K から 10.3-RELEASE-K, 11.0-RELEASE-K から 11.4-RELEASE-K, 12.0-RELEASE-K から 12.3-RELEASE-K, 13.0-RELEASE-K から 13.2-RELEASE-K は、全翻訳済み)
13.3-STABLE-K, 15.0-CURRENT-K は現在、作成中で日々更新されています。
Table of Contents
MUTEX(9) FreeBSD カーネル開発者マニュアル MUTEX(9) 名称 mutex, mtx_init, mtx_destroy, mtx_lock, mtx_lock_spin, mtx_lock_flags, mtx_lock_spin_flags, mtx_trylock, mtx_trylock_flags, mtx_trylock_spin, mtx_trylock_spin_flags, mtx_unlock, mtx_unlock_spin, mtx_unlock_flags, mtx_unlock_spin_flags, mtx_sleep, mtx_initialized, mtx_owned, mtx_recursed, mtx_assert, MTX_SYSINIT -- カーネル同期プリミティブ (基本関 数) 書式 #include <sys/param.h> #include <sys/lock.h> #include <sys/mutex.h> void mtx_init(struct mtx *mutex, const char *name, const char *type, int opts); void mtx_destroy(struct mtx *mutex); void mtx_lock(struct mtx *mutex); void mtx_lock_spin(struct mtx *mutex); void mtx_lock_flags(struct mtx *mutex, int flags); void mtx_lock_spin_flags(struct mtx *mutex, int flags); int mtx_trylock(struct mtx *mutex); int mtx_trylock_flags(struct mtx *mutex, int flags); void mtx_trylock_spin(struct mtx *mutex); int mtx_trylock_spin_flags(struct mtx *mutex, int flags); void mtx_unlock(struct mtx *mutex); void mtx_unlock_spin(struct mtx *mutex); void mtx_unlock_flags(struct mtx *mutex, int flags); void mtx_unlock_spin_flags(struct mtx *mutex, int flags); int mtx_sleep(void *chan, struct mtx *mtx, int priority, const char *wmesg, int timo); int mtx_initialized(const struct mtx *mutex); int mtx_owned(const struct mtx *mutex); int mtx_recursed(const struct mtx *mutex); options INVARIANTS options INVARIANT_SUPPORT void mtx_assert(const struct mtx *mutex, int what); #include <sys/kernel.h> MTX_SYSINIT(name, struct mtx *mtx, const char *description, int opts); 解説 ミューテックスは、スレッド同期の最も基本的で主要な方法です。ミューテック スのための重要な設計の検討項目は、次の通りです: 1. 取得して解放する競合しないミューテックスは、できるだけ安く (リソース 等を必要としない) あるべきです。 2. それらは、優先権の伝播をサポートする情報と記憶域空間がなければなりま せん。 3. スレッドは、ミューテックスが再帰をサポートするために初期化されること 提供する、ミューテックスを繰り返し獲得できなければなりません。 現在、ミューテックスがブロックされるとき、コンテキストスイッチするもの と、そうしない、2 つの特色があるミューテックスがあります。 デフォルトで、MTX_DEF ミューテックスは、それらが既に保持されるとき、コン テキストスイッチします。最適化として、それらは、コンテキストスイッチの前 に若干の時間スピンするかもしれません。スレッドがいつでもプリエンプション (先取り) されるかもしれないので、ミューテックスを取得することによって導入 される起こり得るコンテキストスイッチが既に壊れていないものを壊さないよう に保証されることを覚えていることは重要です。 コンテキストスイッチを行わないミューテックスは、MTX_SPIN ミューテックスで す。これらは、主要な割り込みコードで共有されたデータを保護するためにだけ 使用されるべきです。これは、割り込みフィルタと低レベルスケジューリング コードを含んでいます。すべてのアーキテクチャで、競争しないスピンミュー テックスの取得と解放は、非スピンミューテックスでの同じ操作より、より高価 です。それ自体に対してブロックする割り込みサービスルーチンを保護するため に、すべての割り込みは、スピンロックを保持している間に、プロセッサ上でブ ロックされるか延期されます。複数のスピンミューテックスを保持していること は許されます。 いったんスピンミューテックスが取得されると、ブロッキングミューテックスを 取得するのは許されていません。 ミューテックスを実装するために必要な記憶域は、struct mtx によって提供され ます。一般的に、これは、不透明なオブジェクトとして取り扱われて、ミュー テックスプリミティブでのみ参照されるべきです。 mtx_init() 関数は、他のミューテックス関数のどれかに渡す前にミューテックス を初期化するのに使用されなければなりません。name オプションは、デバッグ出 力などでロックを識別するために使用されます。type オプションは、ロックの順 序をチェックするとき、ミューテックスを区別するために、証言 (witness) コー ドによって使用されます。type が NULL であるなら、name は、その場所に使用 されます。name と type として渡されたポインタは、それが指されたデータより むしろ保存されます。ミューテックスが破壊されるまで、指されたデータは、安 定した状態を保たなければなりません。opts 引数は、ミューテックスのタイプを 設定するために使用されます。それは、MTX_DEF または MTX_SPIN のいずれかを 含みますが、両方ではありません。カーネルが option INVARIANTS でコンパイル されたなら、mtx_init() は、mutex が、MTX_NEW オプションが指定されないな ら、介在されている mtx_destroy() への呼び出しなしで、何度も初期化されてい ないことをアサートします。追加の初期化オプションについては、下記を参照し てください。 mtx_lock() 関数は、現在実行しているカーネルスレッドの代わりに MTX_DEF 相 互排除ロックを獲得します。別のカーネルスレッドがミューテックスを保持して いるなら、ミューテックスが利用可能になるまで (すなわち、それは、ブロック している)、呼び出し側は CPU から切り離されます。 mtx_lock_spin() 関数は、現在実行しているカーネルスレッドの代わりに MTX_SPIN 相互排除ロックを獲得します。別のカーネルスレッドがミューテックス を保持しているなら、ミューテックスが利用可能になるまで、呼び出し側は、ス ピンします。割り込みは、スピンの間、無効にされ、次のロックの獲得は、無効 のまま残ります。 MTX_RECURSE ビットがミューテックスの初期化の間に、mtx_init() に渡されたな らば、同じスレッドは、悪影響なしでミューテックスを再帰的に取得することは 可能です。 mtx_lock_flags() と mtx_lock_spin_flags() 関数は、それぞれ MTX_DEF または MTX_SPIN ロックを獲得して、また、flags 引数を受け付けます。いずれにして も、ロックの獲得のために現在利用可能な唯一のフラグは、MTX_QUIET と MTX_RECURSE です。MTX_QUIET ビットが flags 引数でオンに変えられるなら、そ して KTR_LOCK トレースが完了していたなら、それは、ロックの獲得の間に、沈 黙します。MTX_RECURSE ビットが flags 引数でオンにされるなら、ミューテック を再帰的に獲得することができます。 mtx_trylock() と mtx_trylock_spin() 関数は、mutex によって指された、それ ぞれ MTX_DEF または MTX_SPIN ミューテックスを獲得することを試みます。 ミューテックスが直ちに獲得することができないなら、関数は、0 を返し、そう でなければ、ミューテックスは、獲得され、0 以外の値が返されます。 mtx_trylock_flags() と mtx_trylock_spin_flags() 関数は、それぞれ mtx_trylock() と mtx_trylock_spin() と同じ振る舞いを行いますが、呼び出し 側が、flags 値で渡すことを望んでいるとき、使用されるべきです。現在、 mtx_trylock() と mtx_trylock_spin() の場合の唯一の有効な値は、MTX_QUIET であり、その効果は、上記の mtx_lock() で説明されたものと同じです。 mtx_unlock() 関数は、MTX_DEF 相互排除ロックを解放します。より高い優先順位 のスレッドがミューテックスを待っているなら、現在のスレッドは、先取り (preempt) されるかもしれません。 mtx_unlock_spin() 関数は、MTX_SPIN 相互排除ロックを解放します。 mtx_unlock_flags() と mtx_unlock_spin_flags() 関数は、上記の標準のミュー テックスアンロックルーチンが行うのと全く同じ様に振る舞い、さらに、 MTX_QUIET を指定する flags 引数も許されます。MTX_QUIET の振る舞いは、 ミューテックスロックルーチンの振る舞いと同じです。 mtx_destroy() 関数は、mutex を破壊するのに使用されます、それで、それに関 連しているデータは、解放されるか、またはそうでなければ上書きされます。破 壊されるすべてのミューテックスは、以前に、mtx_init() で初期化されていなけ ればなりません。それが破壊されるとき、ミューテックスでの単一の保持カウン トがあることは許されます。それが破壊されるとき、再帰的にミューテックスを 保持するか、ミューテックスでのブロックされた別のスレッドがあることは許さ れていません。 mtx_sleep() 関数は、イベントを待っている間に不可分に mtx を解放するために 使用されます。この関数のパラメータに関するより詳しい情報については、 sleep(9) を参照してください。 mtx_initialized() 関数は、mutex が初期化されていれば 0 以外を返し、そうで なければ、0 を返します。 mtx_owned() 関数は、現在のスレッドが mutex を保持しているなら、0 以外を返 します。現在のプロセスが mutex を保持していないなら、0 が返されます。 mtx_recursed() 関数は、mutex が再呼び出しされたなら、0 以外を返します。こ のチェックは、実行しているスレッドが既に mutex を所有している場合にだけ、 行われるべきです。 mtx_assert() 関数によって、what で指定されたアサーションを mutex に関して 行うことができます。アサーションが真でなく、カーネルが options INVARIANTS と options INVARIANT_SUPPORT でコンパイルされるなら、カーネルは、パニック します。現在、次のアサーションがサポートされています: MA_OWNED 現在のスレッドが、最初の引数によって指されたミューテック スを保持するアサート。 MA_NOTOWNED 現在のスレッドが、最初の引数によって指されたミューテック スを保持しないアサート。 MA_RECURSED 現在のスレッドが、最初の引数によって指されたミューテック スを再呼び出ししているアサート。このアサーションは、 MA_OWNED に関連しているときのみ有効です。 MA_NOTRECURSED 現在のスレッドが、最初の引数によって指されたミューテック スを再呼び出ししていないアサート。このアサーションは、 MA_OWNED に関連しているときのみ有効です。 MTX_SYSINIT() マクロは、与えられたミューテックスロックを初期化するために システム起動で mtx_sysinit() ルーチンへの呼び出しを生成するために使用され ます。パラメータは、mtx_init() と同じですが、ロックと sysinit ルーチンと 関連している関連構造体のためにユニークな変数名を生成で使用される、追加の 引数 name があります。 デフォルトのミューテックスタイプ ほとんどのカーネルコードは、デフォルトのロックタイプ MTX_DEF を使用するべ きです。デフォルトロックタイプは、ロックが別のスレッドによって既に保持さ れているなら、CPU からスレッドを切り離すことができます。この実装は、いく つかの状況で短期間のスピンロックとしてロックを取り扱うことができます。し かしながら、同じ CPU 上で割り込まれたスレッド対してデッドロックの恐れなし で、割り込みスレッドのこれらの形式のロックを使用することは常に安全です。 スピンミューテックスタイプ MTX_SPIN ミューテックスは、すぐに要求されたロックを取得できないとき、CPU を放棄しませんが、ミューテックスが別の CPU によって解放されるのを待って、 ロープします。別のスレッドが、ミューテックスを保持して、次にミューテック スを取得しようとしたスレッドが割り込まれたなら、これは、デッドロックの結 果となることもあり得ます。この理由で、スピンロックは、ローカル CPU で、す べての割り込みを無効にします。 スピンロックは、非常に短い期間に保持されることを目的としているかなり特殊 化したロックです。それらの第一の目的は、デフォルトのミューテックスや、ス レッドスケジューリングや、割り込みスレッドのような他の同期基本関数を実装 するコードの部分を保護することです。 初期化オプション mtx_init() の opts 引数で渡されたオプションは、ミューテックスタイプを指定 します。MTX_DEF または MTX_SPIN オプションの 1 つが、必要とされ、それらの 2 つのオプションの 1 つだけを指定することもできます。あり得るのは、次の通 りです: MTX_DEF デフォルトのミューテックス。サスペンドされる現在のスレッド は、常に、割り込みスレッドに対してデッドロック状態を避ける ことができます。このロックタイプの実装は、現在のスレッドが サスペンドされる前の少しの間スピンします。 MTX_SPIN スピンミューテックス。CPU を決して放棄しません。すべての割 り込みは、任意のスピンロックが保持されている間、ローカル CPU で無効にされます。 MTX_RECURSE 初期化されたミューテックスが再呼び出しを許されることを指定 します。このビットは、ミューテックスが再呼び出しすることが 許可されるなら、存在していなければなりません。 mtx_trylock() も mtx_trylock_spin() のいずれも再帰をサポー トしないことに注意してください。すなわち、すでに所有されて いるミューテックスを獲得する試みは、失敗します。 MTX_QUIET このロックのためにミューテックス操作を何もログ記録しませ ん。 MTX_NOWITNESS このロックを無視するように witness(4) に指示します。 MTX_DUPOK witness は、獲得される複製ロックに関するメッセージをログ記 録するべきではありません。 MTX_NOPROFILE このロックのプロファイルを行いません。 MTX_NEW 2 つの初期化 (double-init) のためのチェック行いません。 ロックとアンロックフラグ mtx_lock_flags(), mtx_lock_spin_flags(), mtx_unlock_flags() と mtx_unlock_spin_flags() 関数に渡されたフラグは、呼び出し側にいくつかの基 本的なオプションを提供し、ロックを変更するか、または振る舞いをアンロック するために特有の状況下でのみ、しばしば使用されます。標準のロックとアン ロックは、mtx_lock(), mtx_lock_spin(), mtx_unlock() と mtx_unlock_spin() 関数で実行されるべきです。フラグが要求される場合にだけ、対応するフラグ受 け付けルーチンは、使用されるべきです。 ミューテックスの振る舞いを変更するオプションは、次の通りです: MTX_QUIET このオプションは、個々のミューテックス操作の間にメッセージのロ グ記録を行わないようにするために使用されます。これは、デバッグ 目的のために余分なログ記録メッセージを削減するために使用するこ とができます。 Giant Giant を獲得しなければならないなら、他のミューテックスを獲得する前に、そ れは、獲得されなければなりません。言い換えれば: 別のミューテックスを保持 している間に Giant を非再帰的に獲得することは不可能です。Giant を保持して いる間に、他のミューテックスを獲得することは可能で、他のミューテックスを 保持している間に、Giant を再帰的に獲得することは可能です。 スリープ (Giant を除いて) ミューテックスを保持している間のスリープは、決して安全で なく、避けられるべきです。これが試みられるなら、失敗する多数のアサーショ ンがあります。 ユーザ空間のメモリにアクセスする関数 (Giant を除いて) ミューテックスは、copyin(9), copyout(9), uiomove(9), fuword(9), などのように、ユーザ空間でメモリにアクセスする関数にわたって保 持されるべきではありません。これらの関数を呼び出すとき、ロックは、必要で はありません。 関連項目 condvar(9), LOCK_PROFILING(9), locking(9), mtx_pool(9), panic(9), rwlock(9), sema(9), sleep(9), sx(9) 歴史 これらの関数は、BSD/OS 4.1 と FreeBSD 5.0 で登場しました。 mtx_trylock_spin() 関数は、FreeBSD 11.1 で追加されました。 FreeBSD 11.2 May 24, 2017 FreeBSD 11.2