最下層では、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 ドライバはメッセージの内容を見て、以下の分類を行い何をするか決定
します -
sendmsg_to_kernel
コールは Venus に返ります。
プロセス P はその後スケジュールされ、Venus からの応答に置き換えられたデー
タバッファを用いて upcall
の処理を続けます。
sendmsg_to_kernel
は返ります。この後 P は起きて upcall
の処理を続けます。説明の必要な微妙なことが
あります。始めに P は、他のソースからシグナルにより upcall
の中で起
こされた (例えば P を終了しようとした) か、もしくは
sendmsg_to_kernel
コールから戻ったことで普通に Venus により起こされ
たか、を決定することになります。通常の場合では、upcall を行ったルーチン
はメッセージ構造体を解放して返りますが、その際に FS ルーチンが
upcall
処理を続けることがあります。
P が Venus ではなくシグナルによって起こされる場合、始めにフラグフィール ドを見ます。メッセージがまだ READ でない場合、プロセス P は、Venus に通 知することなくそれを扱うことができます。Venus がそのメッセージをすでに読 んでおり (フラグが READ である)、要求を処理すべきではない場合、P は前の メッセージを無視すべきことを示すシグナルメッセージを、Venus に送ることが できます。このようなシグナルはキューの先頭に置かれ、Venus は始めに読みま す。メッセージがすでに WRITTEN とマークされている場合、処理を止めるには 遅すぎます。VFS ルーチンはこの時点で続行します。
VFS 要求が二つ 以上の upcall を含む場合、これは複雑な状態になる可能性があります。この場 合の対処のため、すでに通過した返らない場所を示す特別なフィールド "handle_signals" をメッセージ構造体に追加することができます。
この仕組みの 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 ではセマフォ
で待たされます。