次のページ 前のページ 目次へ

3. メッセージ層

最下層では、Venus と FS ドライバ間のコミュニケーションはメッセージによっ て進みます。Coda ファイルサービスを要求するプロセスと Venus 間の同期は block (休止状態への移行) と wake (スケジュール待ち状態への移行) に依りま す。Coda FS ドライバはプロセス P のために VFS および pioctl の要求を処理 し、Venus 向けのメッセージを作成し、応答を待ち、最後に呼び出し元に返りま す。メッセージの交換の実装はプラットフォーム固有ですが、仕組みは一般的に 適用可能であると (今のところ) 考えています。プロセス P 用のためのデータ バッファはカーネルメモリの中に FS ドライバによって作成され、Venus 内のユー ザメモリにコピーされます。

P をサービスする間 FS ドライバは Venus への upcall を行います。 このような upcall はメッセージ構造体を作成することで、Venus へ送られます。 構造体は、P の識別子、メッセージシーケンス番号、要求のサイズおよび要求用 のカーネルメモリ内のデータへのポインタを含みます。データバッファは Venus から応答を保持するために再利用されるので、返答のサイズ用のフィールドがあ ります。フラグフィールドはメッセージの状態を正確に記録するためにメッセー ジの中で使用されます。さらにプラットフォーム依存の構造体のメンバ (キュー 上のメッセージの位置を決めるポインタおよび同期化オブジェクトへのポインタ など) があります。upcall ルーチンの中でメッセージ構造体の諸情報が記 入され、フラグは 0 に設定され、待機キューに置かれます。データバッ ファの割当ては upcall を呼ぶルーチンの責任です - データバッファの構 造は次のセクションで説明します。

メッセージが作成されたことを通知する機構が存在し、かつ OS 内で利用可能な 同期化オブジェクトを用いて実装されていなければなりません。この通知はプロ セス P の upcall コンテキストの中で行われます。メッセージが待機キュー 上にある時、プロセス P は upcall を行えません。ファイルシステム要求 ルーチン内の P の (カーネルモードの) 処理は、Venus が応答するまで、サス ペンドされなければなりません。したがって、P からスレッドを呼ぼうとすると upcall 中でブロックされます。メッセージ構造体のポインタは P をスリー プさせている同期化オブジェクトを示すでしょう。

Venus はメッセージが到着した通知を検出し、Venus は FS ドライバから getmsg_from_kernel コールでメッセージを受け取ります。このコール の処理はカーネル内で、処理するメッセージのキュー上にメッセージを置き、 READ のフラグを設定することで終わります。Venus にはデータバッファの内容 が渡されます。getmsg_from_kernel コールは呼び出し元に返り、Venus は 要求を処理します。

すこししてから、FS ドライバは Venus からメッセージを受け取ります。具体的 には Venus が sendmsg_to_kernel をコールした際です。この時、 Coda FS ドライバはメッセージの内容を見て、以下の分類を行い何をするか決定 します -

この後 P は起きて upcall の処理を続けます。説明の必要な微妙なことが あります。始めに P は、他のソースからシグナルにより upcall の中で起 こされた (例えば P を終了しようとした) か、もしくは sendmsg_to_kernel コールから戻ったことで普通に Venus により起こされ たか、を決定することになります。通常の場合では、upcall を行ったルーチン はメッセージ構造体を解放して返りますが、その際に FS ルーチンが upcall 処理を続けることがあります。

Sleeping and IPC arrangements

P が Venus ではなくシグナルによって起こされる場合、始めにフラグフィール ドを見ます。メッセージがまだ READ でない場合、プロセス P は、Venus に通 知することなくそれを扱うことができます。Venus がそのメッセージをすでに読 んでおり (フラグが READ である)、要求を処理すべきではない場合、P は前の メッセージを無視すべきことを示すシグナルメッセージを、Venus に送ることが できます。このようなシグナルはキューの先頭に置かれ、Venus は始めに読みま す。メッセージがすでに WRITTEN とマークされている場合、処理を止めるには 遅すぎます。VFS ルーチンはこの時点で続行します。

VFS 要求が二つ 以上の upcall を含む場合、これは複雑な状態になる可能性があります。この場 合の対処のため、すでに通過した返らない場所を示す特別なフィールド "handle_signals" をメッセージ構造体に追加することができます。

3.1 実装の詳細

この仕組みの Unix 実装では、Coda に関連づけられたキャラクタデバイスが実 装されました。Venus はデバイスに読み取りを行うことで、メッセージを 受け取り、応答は書き込みで送られ、通知はデバイス用のファイル記述子 に対する select システムコールを用います。プロセス P は割込み可能な 待機キューのオブジェクト上で待たされます。

Windows NT および DPMI Windows 95 実装では DeviceIoControl コールが用い られました。DeviceIoControl コールはユーザメモリからカーネルメモリへ OPCODES でバッファをコピーするためのものです。sendmsg_to_kernel は 同期コールとして発行されますが、getmsg_from_kernel コールは非同期コー ルです。Windows EventObjects がメッセージ到着の通知のために使われました。 プロセス P は、NT では KernelEvent オブジェクト、Windows 95 ではセマフォ で待たされます。


次のページ 前のページ 目次へ