[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
あらゆるHurdプログラムは以下の付加的な引数を受け取る。
簡潔な使い方のメッセージを表示し、終了する。このメッセージはプログラムの 解説書を読むことの代わりではなく、プログラムが理解する特定のコマンドライ ンのオプションについて思い出すのに役に立つのである。
プログラムのバージョン情報を出力し、終了する。
この章の残りで、Hurdをプログラマに対して紹介する。もしあなたがプログラマ でないなら、この章はあなたには大して意味がない… 特定のHurdプログラ ムの記述まで飛ばすことを考えるべきだ (see section 読者)。
Hurdのユーティリティやサーバを書くための有用なツールの組を提供するために、 Hurdの配布にはたくさんのライブラリが含まれている。これらのライブラリのい くつかはHurdにだけではなく、一般的にマイクロカーネルに基くプログラムを書 くのに役立つ。これらの基本的なライブラリは理解するのに難しくはなく、それ らは良い開始点である。なぜなら、Hurdの残りの部分は非常に激しくそれらに頼っ ているからだ。
4.1 スレッド・ライブラリ | あらゆるHurdサーバとライブラリは マルチスレッド化されている。 | |
4.2 マイクロカーネル・オブジェクト・ライブラリ | マイクロカーネル・オブジェクト・モデル(MOM)。 | |
4.3 portのライブラリ | ||
4.4 整数ハッシュ・ライブラリ | ||
4.5 雑多なライブラリ | GNU Cライブラリにすぐに入るもの。 | |
4.6 バグの宛先ライブラリ | Hurdのバグを報告する場所。 |
マイクロカーネルや土台となるハードウェアのよって提供される多重処理の能力
を十分に利用するために、Hurdサーバやライブラリは全て積極的にマルチスレッ
ド化されている。Hurdのスレッド・ライブラリ、libthreads
はデフォル
トのHurdスレッドの実装を含み、それは<cthreads.h>
で宣言されている。
現在(1998年4月)、Hurdはcthreadsを使っているが、それはすでにCMUによって完 全に解説されている。最後には、それはPOSIX pthreadsを使うように移行される だろう。それはたくさんのところで解説されている。
(GNU Cライブラリを含む)Hurd配布物の中の個々のライブラリは完全にスレッド・ セーフで、Hurdサーバ自身は積極的にマルチスレッド化されている。
一般に尋ねられる質問はHurdはMachマイクロカーネルのOpen Groupのバージョン に移植されているかどうかだ。その答えは"いいえ"だ。
現在(1998年4月)、Hurdは非常にGNU Machマイクロカーネルに依存しており、そ れはユタ大学のMach 4から派生している。しかしながら、Hurdの開発者はMachの 限界をあまりにも気にし過ぎている。
libmom
はHurdを他のメッセージ通信式マイクロカーネルに移植できるよ
うにするために必要とされるいくつかの段階のうち最初のものである。
MOMはMicrokernel Object Modelを表し、一般的なメッセージ通信
式マイクロカーネルによって提供される基本的なサービスの抽象概念である。そ
れはHurdサーバとCライブラリがマイクロカーネルに依存したカーネル呼び出し
を行わないでいいように、必要な隔離を行うだろう。
でも、現在では、libmom
はまだ発展中であり、完全にHurdに組み込まれ
るにはいくらか時間がかかるだろう。
portはカーネルによって所有される通信路である。
portは別々の送信権と受信権を持ち、それらはカーネルを通してタスクからタ スクへ譲られても良い。port権はUnixのファイル記述子と似ている。それらは カーネル呼び出しを行うときにportを識別するのに使われるタスク毎の整数で ある。送信権はRPCリクエストをportに遅るために必要で、受信権はRPCリクエ ストに応対するために必要である。受信権は単一のportsetに集めら れても良く、それは有用な構成単位として役に立つ。
単一スレッドのRPCクライアントでは、portを管理し類別することは難しい処 理ではない。しかしながら、複雑なマルチスレッドのサーバでは、portset を管理するのにより抽象的なインターフェースを持つことは、サーバの抽象的な データを管理することと同様、役に立つのである。
Hurdのportのライブラリ、libports
はその必要性を満たす。
libports
関数は<hurd/ports.h>
で宣言されている。
4.3.1 BucketとClass | port編成の基本単位。 | |
4.3.2 port権 | port権のlibports との間での移動。
| |
4.3.3 portの抽象データ | ||
4.3.4 portの参照 | 漏曳や欠失に対する保護。 | |
4.3.5 RPCの操作 |
libports
のbucketはただのportの組と、いくらかの抽象データ
とロックだけである。libports
関数の全てはbucketに対して操作する。
新しい、空のbucketを作って返す。
portのclassは個々のportの集まりで、それは簡便に扱うことができ、 解放ルーチンを強制している。bucketとclassはまったくorthogonalである。 classのportが全て同じbucketに入っている必要性はなく、bucketのportが 全て同じclassに入っている必要性もない。
新しいport classを作って返す。もし非ゼロなら、clean_routineはこの classの割り当てられたportオブジェクトが破壊されるときにそれぞれに対して 呼び出されるだろう。もし非ゼロなら、dropweak_routineは弱い参照が減 少するようにリクエストするときに呼び出されるだろう。(もし dropweak_routineがnullなら、弱い参照と強い参照はこのclassのportに 対して等価だろう。)
少なくとも一つのbucketとclassを作ってしまったら、新しいportを作り、これ らのbucketに収めて良い。あなたのアプリケーションの必要性に依存して、port の生成に対して少数の異なる関数がある。
classとbucketの新しいportを作り、resultに入れて返す。 sizeバイトがport構造体とユーザが定義するプライベートなデータを保持 するために割り当てられるだろう。
実際にはportをbucketの根底にあるportsetに入れられないことを除いて、
ports_create_port
とちょうど同じである。これはportが完全に初期化さ
れる前にport権が配られなければならない場合に使われることを意図されている。
この呼び出しを使うと、portを初期化し終わりportsetにあなた自身がそれを入
れるまで、そのportにRPCサービスが起こらないことが保証される。
存在する受信権に対し、新しいport構造体を作ってresultに返す。
bucket、size、そしてclass引数は
ports_create_port
と同様である。
以下の関数はport受信権をport構造体との間で移動する。
現在portと結び付いている受信権を破棄し、新しい受信権を割り当てる。
現在portと結び付いている受信権を破棄し、receiveを新しい受信 権として指定する。
現在portと結び付いている受信権を破棄する。この呼び出しの後に、
ports_reallocate_port
とports_reallocate_from_external
は使
えない。
現在portと結び付いている受信権を返す。portに対する効果は
受信権自体には影響しないことを除いてports_destroy_right
と同じであ
る。マルチスレッド化されているサーバでは、このportがportsetから除かれる
前にメッセージがすでにキューから除かれているかもしれないことに注意せよ。
そのようなメッセージからはEOPNOTSUPP
エラーを得るであろう。
fromptからtoptへ受信権を移す。(あたかも
ports_destory_right
が呼ばれたように)fromptは破棄された権利
を持つようになり、(あたかもports_reallocate_from_external
が呼ばれ
たよう)toptの古い権利は破棄される。
portと結び付いている受信権の名前を返す。ユーザは責任を持って、この 名前から普通の送信権を作らねばならない。
libports
関数のそれぞれへのport引数がvoid *
であって
struct port_info *
ではないことを指摘するのは重要だ。これは任意の
抽象的な情報をあなたのlibports
に管理されるportへ追加できるために
行われている。単に最初の要素がstruct port_info
であるような、あな
た自身の構造体を定義すれば、どんなlibports
関数へもport引数
としてこれらの構造体へのポインタを使うことができる。
以下の関数はあなた自身があつらえたport構造体に収められる抽象データを管理 するのに役立つ。
portを探し、参照を割り当てて、結び付いているport構造体を返す。この 呼び出しが失敗すると、ゼロを返す。もしbucketが非ゼロなら、それは検 索するためのbucketを指定する。そうでなければ全てのbucketが検索されるだろ う。もしclassが非ゼロなら、portがclassにないなら検索が 失敗するだろう。
bucketの各portに対し一度だけfunを呼び出す。
これらの関数はport情報構造体がもはや必要とされていないときに限り解放され
るように、portへの参照を管理する。libports
にいつportへの参照が変
化するかを教えるのは、あなたの責任である。
portへの強い参照を割り当てる。
portへの強い参照を減少させる。
ユーザは送信元不在通知を受け取ろうとすることに責任がある。やって来たとき には、そのメッセージが送られたportに対して、その通知からの mscountを与えてこのルーチンを呼び出しなさい。
classに新しいportを生成するのを妨げる。現在classにあるportの 数を返す。
bucketに新しいportを生成するのを妨げる。現在bucketにあるport の数を返す。
(ports_count_class
によって妨げられた)中断されたport生成を続けるこ
とを許可する。
(ports_count_bucket
によって妨げられた)中断されたport生成を続けるこ
とを許可する。
弱い参照はdropweak_routineがnullであるport classでは強い参照を同じ なので、それほど使用されない。See section BucketとClass。
portへの弱い参照を割り当てる。
portへの弱い参照を減少させる。
libports
関数の残りはRPC操作を制御することにささげられる。これらの
関数は頑健なサーバを構築するために必要とされるlockingやthread
cancellationを全て行うのに役立つ。
MiGのdemuxerルーチンの型。
RPCがport上で開始しているときにこれを呼び出す。infoは呼び出
し元で割り当てられるべきで、動的な状態を保持するのに使われるだろう。この
RPCが放棄されれば、EDIED
を返す。そうでなければゼロを返す。
RPCが終えられているときにこれを呼び出す。引数は対になる
ports_begin_rpc
の呼び出しに渡されたものと一致しなければならない。
bucketのportへの操作を処理し始め、それぞれのやって来るメッセージに 対しdemuxerを呼び出す。timeoutが非ゼロでtimeoutミリ秒 の間メッセージが受け取られないと返る。たった一つのスレッドだけ(呼び出し スレッド)を使う。
bucketのportへの操作を処理し始め、それぞれのやって来るメッセージに 対しdemuxerを呼び出す。global_timeoutが非ゼロで global_timeoutミリ秒の間メッセージを受け取られないと返る。他のport での緩慢さが原因でどのportも飢餓状態にならないように、やって来るメッセー ジを処理するのに必要なだけスレッドを生成する。もしthread_timeoutが 非ゼロなら、個々のスレッドはthread_timeout(5)ミリ秒の間 やって来るメッセージを処理しなかったら死んでいくだろう。もしnullでないな ら、hookは、新しいスレッドが作られる後にすぐ、それぞれに対して呼び 出されるだろう。
portへのどの未処理のRPCにも割り込む。全ての未処理のRPCが終わるのを 待ち、そしてこのportで始まるどの新しいRPCでも妨げる。
ports_inhibit_port_rpcs
に似ているが、classの全てのportに影
響する。
ports_inhibit_port_rpcs
に似ているが、bucketの全てのportに影
響する。
ports_inhibit_port_rpcs
に似しているが、ありとあらゆるportに影響する。
このportに対する以前のports_inhibit_port_rpcs
の効果を元に戻
し、妨げられたRPCを続けることを許可する。
このclassに対する以前のports_inhibit_class_rpcs
の効果を元に
戻す。
このbucketに対する以前のports_inhibit_bucket_rpcs
の効果を元
に戻す。
以前のports_inhibit_all_rpcs
の効果を元に戻す。
portで進行中のどのRPCも(thread_cancel
を使って)中止する。
もし現在のスレッドのRPCがports_interrupt_rpcs
で割り込まれたなら、
非ゼロを返し、割り込みフラグを取り除く。
whatにあるもののいづれかがportに対して起きたなら、
hurd_cancel
がrpcのスレッド上で呼ばれるように手配する。
rpcはobject上のRPCであるべきだ。
もしportがwhatという条件で通知を受けたら、hurd_cancel
が、それはobject上のRPCであるべきだが、現在のスレッド上で呼ばれる
ように手配する。
whatがMACH_NOTIFY_DEAD_NAME
に設定されて
ports_interrupt_self_on_notification
を呼ぶのと同じである。
そのようにリクエストしているobject上のどのRPCにも割り込む。
whatがMACH_NOTIFY_DEAD_NAME
に設定されて
ports_interrupt_notified_rpcs
を呼ぶのと同じである。
libihash
は任意の要素データ型に対して、整数を鍵としたハッシュ表を
提供する。この種のハッシュ表は疎らな配列やバッファ・キャッシュを実装する
ときに頻繁に使われる。
以下の関数は<hurd/ihash.h>
で宣言されている。
整数ハッシュ表を生成し、それをhtに返す。もしメモリ割り当てエラーが
起きれば、ENOMEM
が返され、そうでなければゼロである。
htとそれが消費している全ての資源を解放する。
htの要素を後始末する関数をcleanupに設定し、その二つ目の引数 をargに設定する。その後上書きされたり削除される、あらゆる要素 valueに対して、argを二番目の引数としてcleanupが呼び出 されるだろう。
整数鍵idの下にitemをハッシュ表htに加える。locpは
itemに位置するポインタのアドレスである。もしnullでなければ、
locpはvoid **
型の変数を指しているべきで、
ihash_locp_remove
の引数として使われて良いポインタで埋められるだろ
う。locpによって指された変数はこの呼び出しとその要素が削除されると
きの間のいつかに上書きされるかもしれない。だからその値を他の場所に隠して
おき、その隠しておいた値をihash_locp_remove
で使おうと考えることは
できない。もしメモリ割り当てエラーが起きると、ENOMEM
が返され、そ
うでなければゼロが返る。
ハッシュ表htで鍵idで項目を探して返す。指定された項目が存在し なければnullを返す。
htのあらゆる要素に関数funを呼び出す。funの唯一の引数、
valueはそのハッシュ表に収められている値へのポインタである。もし
funが非ゼロをいつか返せば、繰り返すのを止め、ihash_iterate
はその値を返し、そうでなければそれは(最後には)0を返す。
htからidの鍵に伴う項目を削除する。もしそのような要素がなかっ たら、ゼロを返し、そうでなければ非ゼロを返す。
ハッシュ表htからlocpにある項目を削除する。locpは
ihash_add
への以前の呼び出しから返されたのと同じものである。この呼
び出しはihash_remove
より速いはずだ。その呼び出しが成功するのに、
後始末が行われていない場合には、htがnullで良い。
GNU CライブラリはHurdの必要性を満たすように絶えず発展している。しかしな がら、Cライブラリは非常に安定している必要があるので、新しい関数のインター フェースを注意深く指定し、完全にそれらを試験することなく、それらを加える のは無責任である。
Hurdの配布にはlibshouldbeinlibc
と呼ばれるライブラリが含まれ、それ
はGNU Cライブラリへ追加するための試験をする基盤として役に立つ。関数の一
部はHurd開発者によってそれに加えられ、それ以外は公式のCライブラリに移動するというように、このライブラリは流動的である。
これらの関数は(それらのヘッダ・ファイル以外は)現在解説されていないが、こ れらの関数がGNU Cライブラリの一部となるときに、完全な解説が に加えられるだろう。
libhurdbugaddr
は単一の変数を定義するためだけに存在する。
argp_program_bug_address
はデフォルトのHurdバグ報告用e-mailアドレ
スで、bug-hurd@gnu.orgである。この宛先は標準的なHurdサーバやユー
ティリティのいづれかが`--help'オプションを使って起動されたときにユー
ザに示される。
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Akihiro Sagawa on June, 15 2005 using texi2html 1.70.