.\" Copyright (c) 2002 Packet Design, LLC. .\" All rights reserved. .\" .\" Subject to the following obligations and disclaimer of warranty, .\" use and redistribution of this software, in source or object code .\" forms, with or without modifications are expressly permitted by .\" Packet Design; provided, however, that: .\" .\" (i) Any and all reproductions of the source or object code .\" must include the copyright notice above and the following .\" disclaimer of warranties; and .\" (ii) No rights are granted, in any manner or form, to use .\" Packet Design trademarks, including the mark "PACKET DESIGN" .\" on advertising, endorsements, or otherwise except as such .\" appears in the above copyright notice or in the software. .\" .\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND .\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO .\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING .\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED .\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, .\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE, .\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS .\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, .\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE .\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE .\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT, .\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL .\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF .\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF .\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF .\" THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF .\" THE POSSIBILITY OF SUCH DAMAGE. .\" .\" %FreeBSD: src/lib/libc/sys/kse.2,v 1.13.2.2 2005/02/28 03:32:34 brueffer Exp % .\" .\" $FreeBSD$ .\" .Dd September 10, 2002 .Dt KSE 2 .Os .Sh 名称 .Nm kse .Nd ユーザスレッドのためのカーネルサポート .Sh ライブラリ .Lb libc .Sh 書式 .In sys/types.h .In sys/kse.h .Ft int .Fn kse_create "struct kse_mailbox *mbx" "int newgroup" .Ft int .Fn kse_exit void .Ft int .Fn kse_release "struct timespec *timeout" .Ft int .Fn kse_switchin "mcontext_t *mcp" "long val" "long *loc" .Ft int .Fn kse_thr_interrupt "struct kse_thr_mailbox *tmbx" .Ft int .Fn kse_wakeup "struct kse_mailbox *mbx" .Sh 解説 これらのシステムコールはマルチスレッド化されたプロセスのための カーネルサポートを実装しています。 .\" .Ss 概要 .\" 伝統的にユーザスレッディングは、 次の 2 つの方法のうちのどちらか一方で実装されてきました。 まず全てのスレッドはユーザ空間で管理され、 カーネルはスレッディングを全く認識しない方法 .Dq ( "N 対 1" としても知られています)。 そして、個々のスレッドに対して 共通のメモリ空間を共有する別々のプロセスが生成される方法 .Dq ( "N 対 N" としても知られています)。 これらのアプローチは長所と短所を持っています: .Bl -column "- システムコールのラッピング必須" "+ システムコールのラッピング不要" .It Sy "ユーザスレッディング カーネルスレッディング" .It "+ 軽量 - 重量" .It "+ ユーザ制御スケジューリング - カーネル制御スケジューリング" .It "- システムコールのラッピング必須 + システムコールのラッピング不要" .It "- マルチ CPU の有効活用不可 + マルチ CPU の有効活用可能" .El .Pp KSE システムはユーザスレッディングおよびカーネルスレッディングの両方の 長所を生かす複合型アプローチです。 KSE システムの根本的な哲学は、スケジューリングを決定するための ユーザスレッディングライブラリの能力を全く減じることなく、 ユーザスレッディングのためのカーネルサポートを実現することです。 スケジューリングの決定が必要になった時に ユーザスレッディングライブラリに制御を渡すために、 カーネルからユーザスレッドへの upcall 機構を使用します。 任意の数のユーザスレッドが、 カーネルによって供給される固定数の仮想 CPU 上に多重化されます。 これは .Dq "N 対 M" スレッディング機構と考えることができます。 .Pp このアプローチが暗に意味する一般的な特性としては以下のものがあります: .Bl -bullet .It ユーザプロセスはマルチプロセッサマシン上で複数のスレッドを 同時に実行することが可能です。 カーネルは、プロセスに対して自由にスケジュールできる仮想 CPU 群を提供します。 これらは、複数の実 CPU 上で同時に実行できます。 .It スレッドがブロックされた際にユーザプロセスが 他のスレッドをスケジュールできるよう、 カーネル内でブロックする全ての操作は非同期になります。 .It 同じプロセス内に複数のスレッドスケジューラが存在可能で、 それらは互いに独立して動くことができます。 .El .\" .Ss 定義 .\" KSE はユーザプロセスが複数の .Sy スレッド を同時に実行できるようにします。 スレッドのうちの幾つかは、 その他のスレッドがユーザ空間で実行中またはブロックされている間であっても、 カーネル内でブロックさせて構いません。 .Sy カーネルスケジューリングの実体 (kernel scheduling entity, KSE) はスレッドの実行のためにプロセスに供された .Dq "仮想 CPU" です。 現在実行されているスレッドは、 ユーザ空間またはカーネルのどちらで実行されていても、 厳密に 1 つの KSE に常に関連付けられています。 KSE はスレッドに .Sy 割り当てられている といえます。 .Pp ある KSE が関連付けられた .Sy メールボックス (下記参照) を持ち、そのスレッドが関連付けられた .Sy スレッドメールボックス (これも下記参照) を持ち、さらに以下のどれかが発生したとき、その KSE は .Sy 割り当てられていない 状態になり、関連付けられたスレッドは中断されます: .Bl -bullet .It そのスレッドがブロックを伴うシステムコールを実行した。 .It スレッドがカーネルがすぐには満たすことができない要求を行った。 例えばディスクからデータを読み出す必要があるメモリページにアクセスし ページフォルトを起こした。 .It カーネル内で先にブロックされていた他のスレッドが、 カーネル内の作業を完了し (または .Sy 割り込まれ ) ユーザ空間へ戻れるようになり、 さらに現在のスレッドがユーザ空間に戻っている最中だった。 .It シグナルがプロセスに配信され、 この KSE がそのシグナルを配信するために選択された。 .El .Pp 言い換えると、スケジューリングの決定が行われようとするとき、 その KSE は割り当てられていない状態になります。 なぜならば、カーネルはそのプロセスの他のどの実行可能なスレッドを スケジュールするべきか推定しないからです。 割り当てられていない KSE は常に可能な限り早く、 ユーザプロセスがその KSE を次にどのように利用するかを決定できる .Sy upcall 機構 (後述) を介してユーザ空間に戻ります。 KSE は常に、割り当てが解除される前に、 カーネル内で可能な限り多くの作業を完了させます。 .Pp .Sy "KSE グループ" は均等にスケジュールされ、 その KSE グループに関連付けられた同一のスレッドプールへのアクセスを共有する KSE の集合です。 KSE グループはカーネルスケジューリングの優先度が割り当てられる 最小の実体です。 プロセスのスケジューリングとアカウンティングの目的には、 それぞれの KSE グループは 伝統的なスレッド化されていないプロセスと同様にみなされます。 KSE グループの中の個々の KSE は実際上、見分けがつきません。 また、KSE グループの中のすべての KSE は、その KSE グループに 関連付けられた (カーネル内の) どの実行可能なスレッドに対してでも カーネルによって割り当てられえます。 実際問題として、カーネルはキャッシュの動作を最適化するために、 スレッドと実際の CPU 群との密接な関係を保存しようと試みますが、 これはユーザプロセスには不可視です (密接な関係はまだ実装されていません)。 .Pp それぞれの KSE はユーザプロセスによって供給される独自の .Sy "KSE メールボックス" を持っています。 メールボックスは .Sy "upcall 関数" へのポインタとユーザスタックを含む制御構造体で構成されています。 KSE は割り当てを解除されると必ずこの関数を実行します。 カーネルはこの構造体の、実行可能になっているスレッド、およびそれぞれの upcall の前に配信されていたシグナルについての情報を更新します。 upcall はクリティカルセクションの間は、ユーザスレッドの スケジューリングコードによって一時的にブロックされることがあります。 .Pp 同様にそれぞれのユーザスレッドは独自の .Sy "スレッドメールボックス" を持っています。 カーネルとユーザスレッドスケジューラが通信するときに、 スレッドはこれらのメールボックスへのポインタを通して参照されます。 それぞれの KSE のメールボックスは、その KSE が現在実行している ユーザスレッドのメールボックスへのポインタを含んでいます。 このポインタはカーネル内でスレッドがブロックするときに、保存されます。 .Pp カーネル内でブロックされていたスレッドがユーザ空間に戻る準備ができたときには そのスレッドは必ず、KSE グループの .Sy 完了した スレッドのリストに追加されます。 このリストはスレッドメールボックスのリンクされたリストとして、 次の upcall でユーザコードに提示されます。 .Pp カーネル内で同時にブロックされる KSE グループ中の スレッド数には、カーネルに起因する制限があります (現在、この数はユーザには 不可視です)。 この制限に達したとき、スレッドの 1 つが完了するまでの間 (または シグナルが配信されるまでの間)、upcall はブロックされ、 その KSE グループのための作業は何も実行されません。 .\" .Ss KSE の管理 .\" マルチスレッドで動くためには、プロセスは初めに .Fn kse_create を実行しなければなりません。 .Fn kse_create システムコールは新しい KSE を 作成します (本当に最初の実行を除く、下記参照)。 その KSE は .Fa mbx によって指されるメールボックスと関連付けられます。 .Fa newgroup が 0 ではない場合には、その KSE を含む新しい KSE グループも作成されます。 そうでない場合には、その新しい KSE は現在の KSE グループに追加されます。 新しく作成される KSE は最初は割り当てられていません。 そのため、それらの KSE は直ちに upcall します。 .Pp それぞれのプロセスは初めは 1 つのユーザスレッドを 実行する 1 つの KSE グループの中に 1 つの KSE を持っています。 その KSE は関連付けられたメールボックスを持っていないため、 そのスレッドに割り当てられたままでなければならず、 upcall を全く実行しません。 この結果は伝統的で、スレッド化されていない形態での処理です。 そのため、特別な場合として、この最初のスレッドによる .Fa newgroup が 0 である .Fn kse_create の最初の呼び出しは、新しい KSE を作成しません。 代わりに、単に現在の KSE を与えられた KSE メールボックスに関連付け、 直後の upcall は起こしません。 しかしながら、次にそのスレッドがブロックし必要とされる条件がそろったときには、 upcall が引き起こされます。 .Pp カーネルは 1 つの KSE グループの中にシステムの物理的な CPU の数 (この数は .Xr sysctl 3 変数 .Va hw.ncpu として取得可能です) より多い KSE の存在を許可しません。 CPU より多い数の KSE を持つことは、その追加の KSE が単に その他の KSE と実 CPU 群へのアクセスを競合するだけであるため、 ユーザプロセスにとって全く価値を増やさないでしょう。 そのため、余分な KSE は常に脇に追いやられ、その結果アプリケーションは より少ない KSE を持っていることと全く同じになるでしょう。 しかし、アプリケーションのユーザスレッドを利用可能な KSE へマッピングする ユーザスレッドスケジューラの数までは、 任意の数のユーザスレッドが存在しても構いません。 .Pp .Fn kse_exit システムコールは、現在実行しているスレッドに割り当てられている KSE を破棄します。 この KSE がこの KSE グループの中の最後の 1 つの場合には、 その KSE グループに関連付けられているスレッドが、 カーネル内でブロックされたまま残っていてはなりません。 このシステムコールはエラーがない限り、戻りません。 .Pp 特別な場合として、最後に残っている KSE グループの中の最後に残っている KSE が このシステムコールを実行する場合には、その KSE は破棄されません。 代わりに、その KSE はそのメールボックスとの関連付けを失うだけで、 .Fn kse_exit は正常に戻ります。 これはそのプロセスを元のスレッド化されていない状態に戻します。 .Pp .Fn kse_release システムコールは、現在実行しているスレッドに関連付けられている KSE が必要でなくなったときに、 .Dq 一時保管 するために使用します。 例えば、実行可能なユーザスレッドよりも利用可能な KSE の方が多い場合です。 そのスレッドは upcall へ転向しますが、 新しくスケジュールする理由ができるまではそのようにされることはありません。 例えば、以前にブロックされていたスレッドが実行可能になる、 またはタイムアウトが発生するといった場合です。 成功した場合には、 .Fn kse_release は呼び出し側に戻りません。 .Pp .Fn kse_switchin システムコールは、UTS (ユーザスレッドスケジューラ) が スレッドのコンテキストを切り替える選択を新たにした際に使用できます。 .Fn kse_switchin の使用はマシンに依存します。 あるプラットフォームでは新しいコンテキストへの切り替えにシステムコールを 必要としませんが、別のプラットフォームでは特にこの場面で要求されます。 .Pp .Fn kse_wakeup システムコールは .Fn kse_release の反対です。 .Fa mbx によって指されているメールボックスに関連付けられた (一時保管された) KSE を起こして upcall させます。 その KSE がすでに他の理由で起こされていた場合には、 このシステムコールは何の効果もありません。 .Fa mbx 引数に .Dv NULL を指定すると .Dq "現在の KSE グループの中のどの KSE でもよい" という指定になります。 .Pp .Fn kse_thr_interrupt システムコールは、現在ブロックされているスレッドを一時停止させます。 そのスレッドはカーネル内でブロックされているか、 KSE に割り当てられて (つまり実行中) いるか、どちらかでなければなりません。 その後、そのスレッドには割り込まれたという印が付けられます。 スレッドが割り込み可能なステムコールを実行するとできるだけ早く (または、スレッドがカーネル内ですでにブロックされてる場合には直ちに)、 カーネル処理が完了していない可能性があるかにかかわらず そのスレッドは再度実行可能にされます。 割り込まれたシステムコール上でのこの効果は、 すでにシグナルによって割り込まれていた場合と同様です。 通常、これは .Va errno に .Er EINTR を設定してエラーを返したことを意味します。 .\" .Ss シグナル .\" .Pp 現在の実装は特別なシグナルスレッドを作成します。 プロセス内のカーネルスレッド (KSE) はすべてのシグナルをマスクし、 シグナルスレッドだけがプロセスへ配信されるシグナルを待ち受けます。 シグナルスレッドはユーザスレッドへのシグナルの ディスパッチに対して責任を持ちます。 .\" responsible for = 《be 〜》〜に対して責任がある、〜に関与する .Pp この弱点は、多重スレッドが .Fn execve システムコールを呼び出した場合、そのシグナルマスクとペンディングシグナルは カーネルで利用できないかもしれないことです。 それらはユーザランドで格納され、 カーネルはどこからそれを得ればよいかわかりません。 しかしながら、 .Tn POSIX ではそれらを復元して、新しいプロセスに渡すことを求めています。 スレッドが .Fn execve を呼び出す前にマスクを行うだけでは、 元のプロセスがブロックしていたペンディングシグナルを カーネルに再び戻すことができず、またマスクを設定したあと .Fn execve が呼ばれる間にプロセスにシグナルが配信されるウィンドウの発生を 許してしまうため、よく似た近似にしかなりません。 .Pp 今のところ、この問題は .Fn kse_thr_interrupt システムコールに .Fn kse_thr_interrupt Ns / Ns Fn execve の特別な組み合わせモードを追加することにより解決されています。 .Fn kse_thr_interrupt システムコールにはサブコマンド .Dv KSE_INTR_EXECVE があり、それは .Vt kse_execv_args 構造体を受け付けて、シグナルを調整した後に不可分に .Fn execve 呼び出しへ変換できるようにします。 .\" 原文: .Fn execve() は .Fn execve の誤り。HEAD, RELENG_6では修正済 このようにして追加のペンディングシグナルと正しいシグナルマスクを カーネルに渡すことができます。 .\" in this way = かくのごとく、こういう調子に、このような方法で、このように(して)、 スレッドライブラリは、 .Fn execve システムコールを上書きし、多重スレッドが .Fn exec を行う前にペンディングシグナルと正しいシグナルマスクを復元できるよう、 .Fn kse_intr_interrupt 呼び出しに変換します。 この問題の解決法は変更されるかもしれません。 .\" .Ss KSE メールボックス .\" それぞれの KSE は .In sys/kse.h で定義されているユーザとカーネルの通信のために独自のメールボックスを持ちます。 フィールドの一部は次の通りです: .Pp .Va km_version はこの構造体のバージョンを表し、 .Dv KSE_VER_0 と等しくなければなりません。 .Va km_udata はカーネルには無視される不透明なポインタです。 .Pp .Va km_func はその KSE の upcall 関数を指します。 これは、その KSE の生存期間を通して有効であり続けなければならない .Va km_stack を使用して実行されます。 .Pp .Va km_curthread はもし現在この KSE に割り当てられているスレッドがあればそれを、 なければ .Dv NULL を指しています。 このフィールドは、 カーネルとユーザプロセスの両方によって以下のように更新されます。 .Pp .Va km_curthread が .Dv NULL ではないときには、 それは現在実行中のスレッドのメールボックスを指しているものとみなされ、 割り当て解除可能です。 例えば、スレッドがカーネル内でブロックする場合です。 その後、カーネルはブロックされたスレッドの .Va km_curthread の内容を保存して .Va km_curthread を .Dv NULL に設定し、 .Fn km_func を実行するために upcall します。 .Pp .Va km_curthread が .Dv NULL のときには、カーネルはこの KSE の upcall を決して実行しません。 言いかえると、KSE はたとえブロックしたとしても、 そのスレッドに割り当てられたままとなります。 KSE が upcall が間にはいることによって混乱を起こすような危ない ユーザスレッドスケジューラのコードを実行している間、特に .Fn km_func それ自身を実行している間は、 .Va km_curthread は .Dv NULL でなければなりません。 .Pp どのような upcall であれ、 .Fn km_func を実行する前に、カーネルは常に .Va km_curthread を .Dv NULL に設定します。 一度ユーザスレッドスケジューラが実行すべき新しいスレッドを選んだら、 .Va km_curthread がそのスレッドのメールボックスを指すようにし、 upcall を再度有効化し、それからそのスレッドを再開するべきです。 .Em 注意 : ユーザスレッドスケジューラによる .Va km_curthread の変更は、 新しいスレッドのコンテキストのロードを不可分に行わなければなりません。 依然として有効な情報がそこから読み出し可能なときに ブロッキング非同期操作によってスレッドのコンテキスト領域が 変更されえる状況を避けるためです。 .Pp .Va km_completed は最後に実行された upcall 以降にカーネル内での処理を終えたユーザスレッドの リンクされたリストを指しています。 ユーザスレッドスケジューラは、 これらのスレッドをスケジューラが所有する実行可能キューに戻すべきです。 upcall に帰着する (同期または非同期) カーネル操作を完了した KSE グループ内の各々のスレッドは、確実に 1 つの KSE の .Va km_completed にリンクされることが保証されますが、 グループの中のどの KSE かは決まっていません。 その上、その完了はたった 1 つの upcall でしか報告されません。 .Pp .Va km_sigscaught にはその前のプロセス内の任意の KSE への upcall 以降に、 このプロセスによって捕まえられたシグナルのリストが含まれています。 ユーザプロセスの中に、 メールボックスに関連付けられた KSE が 1 つ以上存在する限りは、 シグナルは伝統的な方法ではなくこの方法で配信されます (これはまだ実装されておらず、変更されるかもしれません)。 .Pp .Va km_timeofday は、それぞれの upcall の前にカーネルによって現在のシステム時刻に設定されます。 .Pp .Va km_flags は以下の任意のビットを OR して同時に含むことができます: .Bl -tag -width indent .It Dv KMF_NOUPCALL upcall が起きないようにブロックします。 スレッドは何らかのクリティカルセクション (危険域) にあります。 .It Dv KMF_NOCOMPLETED , KMF_DONE , KMF_BOUND このスレッドは、永久に KSE に結びつけられると考えられるべきで、 スレッド化されていないプロセスとそっくりに扱われます。 .\" 原文: considerred は considered の誤り。Rev1.16 で修正済 .\" considered to be = 《be 〜》〜であると考えられている[目されている] .\" much like = そっくりの、酷似の それはある意味 .Dv KMF_NOUPCALL の .Dq 長期 バージョンといえます。 .\" in some ways = ある点[意味]で(は)、いろいろな意味で、いくつかの点で .It Dv KMF_WAITSIGEVENT シグナル配信スレッドに必要な特性を実装します。 .\" 原文: charactersitics は # characteristics の誤り。Rev1.16 で修正済 .El .\" .Ss スレッドメールボックス .\" 各ユーザスレッドは .In sys/kse.h で定義されている独自の .Vt "struct kse_thr_mailbox" に関連付けられている必要があります。 それは次のフィールドを含んでいます: .Pp .Va tm_udata はカーネルによって無視される不透明なポインタです。 .Pp .Va tm_context スレッドがはユーザ空間内でブロックされた時に、 そのスレッドのためのコンテキストを保存します。 このフィールドは完了したスレッドが .Va km_completed を介してユーザスレッドスケジューラに戻る前に、カーネルによっても更新されます。 .Pp .Va tm_next カーネルによって upcall を使って戻される時に、 .Va km_completed のスレッドをリンクします。 このリストの最後は .Dv NULL でマークされています。 .Pp .Va tm_uticks および .Va tm_sticks はそれぞれ、ユーザモードおよびカーネルモードにおける実行の時間カウンタです。 これらのカウンタは統計クロック .Xr ( clocks 7 参照) の刻みをカウントします。 カーネル内でいずれかのスレッドがアクティブに実行中の間は、対応する .Va tm_sticks カウンタがインクリメントされます。 ユーザ空間でいずれかの KSE が実行中で、その KSE の .Va km_curthread ポインタが .Dv NULL と等しくない間は、対応する .Va tm_uticks カウンタがインクリメントされます。 .Pp .Va tm_flags は以下の全てのビット毎の OR を含むことができます: .Bl -tag -width indent .It Dv TMF_NOUPCALL .Dv KMF_NOUPCALL と似ています。 このフラグはクリティカルセクション (危険域) への upcall を禁止します。 いくつかのアーキテクチャではこれが必要になるのは 1 ヶ所ですが、 他のアーキテクチャではまた別の場所で必要とします。 .El .Sh 戻り値 .Fn kse_create , .Fn kse_wakeup および .Fn kse_thr_interrupt システムコールは成功した場合 0 を返します。 .Fn kse_exit および .Fn kse_release システムコールは成功した場合戻りません。 .Pp これら全てのシステムコールはエラーの場合には、 0 ではないエラーコードを返します。 .Sh エラー .Fn kse_create システムコールは次の場合に失敗します: .Bl -tag -width Er .It Bq Er ENXIO 既に KSE グループの中にハードウェアプロセッサと同じ数の KSE が存在しています。 .It Bq Er EAGAIN 実行中の合計 KSE グループ数に関するシステム上の制限値を超過します。 この制限は .Xr sysctl 3 MIB 変数 .Dv KERN_MAXPROC によって与えられます。 (この制限はスーパユーザ以外の場合、実際にはこれより 10 小さい値です) .It Bq Er EAGAIN ユーザがスーパユーザではなく、1 ユーザへの実行中の合計 KSE グループ数 に関するシステム上の制限値を超過します。 この制限は .Xr sysctl 3 MIB 変数 .Dv KERN_MAXPROCPERUID によって与えられます。 .It Bq Er EAGAIN ユーザがスーパユーザではなく、 .Fa resource 引数 .Dv RLIMIT_NPROC に対応するソフトリソース制限を超過します .Xr ( getrlimit 2 参照)。 .It Bq Er EFAULT .Fa mbx 引数がプロセスのアドレス空間の有効ではない部分のアドレスを指しています。 .El .Pp .Fn kse_exit システムコールは次の場合に失敗します: .Bl -tag -width Er .It Bq Er EDEADLK 現在の KSE はその KSE グループ内の最後であり、 その KSE グループに関連付けられたカーネル内でブロックされているスレッドが 依然として 1 つ以上存在しています。 .It Bq Er ESRCH 現在の KSE は関連付けられたメールボックスを持っていません。 つまり、そのプロセスは伝統的なスレッド化されていないモードで、 動作しています (この場合はプロセスを終了するために .Xr _exit 2 を使用します)。 .El .Pp .Fn kse_release システムコールは次の場合に失敗します: .Bl -tag -width Er .It Bq Er ESRCH 現在の KSE は関連付けられたメールボックスを持っていません。 つまり、そのプロセスは伝統的なスレッド化されていないモードで 動作しています。 .El .Pp .Fn kse_wakeup システムコールは次の場合に失敗します: .Bl -tag -width Er .It Bq Er ESRCH .Fa mbx 引数が .Dv NULL ではなく、 .Fa mbx によって指されるメールボックスが、 そのプロセス内のいずれの KSE にも関連付けられていません。 .It Bq Er ESRCH .Fa mbx 引数が .Dv NULL 現在の KSE は関連付けられたメールボックスを持っていません。 つまり、そのプロセスは伝統的なスレッド化されていないモードで、 動作しています。 .El .Pp .Fn kse_thr_interrupt システムコールは次の場合に失敗します: .Bl -tag -width Er .It Bq Er ESRCH .Fa tmbx に対応するスレッドが、現在プロセス内のいずれの KSE にも割り当てられても、 カーネル内でブロックされてもいません。 .El .Sh 関連項目 .Xr rfork 2 , .Xr pthread 3 , .Xr ucontext 3 .Rs .%A "Thomas E. Anderson" .%A "Brian N. Bershad" .%A "Edward D. Lazowska" .%A "Henry M. Levy" .%J "ACM Transactions on Computer Systems" .%N Issue 1 .%V Volume 10 .%D February 1992 .%I ACM Press .%P pp. 53-79 .%T "Scheduler activations: effective kernel support for the user-level management of parallelism" .Re .Sh 歴史 KSE システムコール群は .Fx 5.0 ではじめて登場しました。 .Sh 作者 KSE は初めに .An -nosplit .An "Julian Elischer" Aq julian@FreeBSD.org が実装し、 .An "Jonathan Mini" Aq mini@FreeBSD.org , .An "Daniel Eischen" Aq deischen@FreeBSD.org および .An "David Xu" Aq davidxu@FreeBSD.org が追加の貢献をしました。 .Pp このマニュアルページは .An "Archie Cobbs" Aq archie@FreeBSD.org によって書かれました。 .Sh バグ KSE のコードは現在も開発中です。 .\" .Ud . .\" .Ud マクロは日本語では実装されていません。(池内)