議論/メッセージコード
新メッセージ機構についての議論 by ひげぽん †
- 現在のMonaカーネルのメッセージ機構とMonAPIのメッセージ機構を整理・改善する
メッセージ機構に必要なI/F †
- SEND
- メッセージを送信。送信先からのREPLYもしくはタイムアウトするまで送信元はブロックされる。
- POST
- RECEIVE
- REPLY
- 特定のSENDに対してOK/NG程度の返信を行う。
- PEEK
- メッセージキュー(が存在すれば)の任意のメッセージを参照?
send/reply方式についての考察 †
- 考えてみました。皆さんと認識あっていますか?>Gakuさん >shadowさん >Yui_Nekoさん > Tinoさん --ひげぽん
- スレッドAはスレッドBにsendする
- Bがメッセージ受信可能ならば
- Bのメッセージバッファにメッセージをセットする
- Aはブロックされる
- Bがメッセージ受信可能でないとき
- Aはブロックされる
- Bが受信可能になりしだいメッセージをセット後またブロックされてる。事前に設定された時間でタイムアウトになるとAのブロックは解除される
- スレッドBはreceiveする
- BはAにreplyする
- Aはsendの戻り値としてreply結果を得る
コメント †
コメントはありません。 コメント/議論/メッセージ?
- ありがとうございます。最小限の構成と認識しています。 -- ひげぽん 2004-05-24 (月) 22:42:21
- あってると思います。それでもインタフェースのきり方に色々な選択肢がありますが。 -- Gaku 2004-05-24 (月) 22:34:59
- おっと。わすれてました・・・。上記のような感じでイメージあっているのでしょうか? -- ひげぽん 2004-05-22 (土) 00:31:26
コメント †
コメントはありません。 コメント/議論/メッセージ?
- メッセージ構造体のサイズについて -- ひげぽん
- 現在のメッセージングに機構に思いついた懸念点 -- ひげぽん
- カーネルにキューを持った場合。あるスレッドがメッセージを受け取っているのにもかかわらず一向に受信しなかった場合。以下のようなことが起きる可能性がある。
- メッセージバッファを食い尽くして、メッセージ消失(←現行の仕様)
- カーネルメモリを食いつぶしてカーネルパニック死亡(←必要なだけ動的にメモリを割り当てるとこうなる)
- この場合の方法では、受け付けられるメッセージの上限を制限して、SEND 側をブロックするのではないかと。で、一定時間(指定した)が立てばエラーが返る。-- Gaku
- ユーザー側でキューを持つのであれば受信しないのはそのスレッドの責任で死亡するのは理想的にはそのスレッドだけである。 -- ひげぽん
- しかし、カーネルがキューを持たないのは、カーネル-ユーザ間でメッセージ取りこぼしを発生しないようにする労力が発生する -- Yui_Neko
- そうですね。その労力はユーザーライブラリ(or 標準神領域)が担う感じであっていますか? -- ひげぽん
- メッセージは重要なのでなるべく方向を決めたらそれでフィックス(ある程度の期間は)したいですなぁ。私などはメッセージが決まってないのにサーバなぞ書けるかー。と思ってしまうので。 -- Gaku 2004-05-16 (日) 01:29:31
- で、キューをカーネルで持たないようにする方針ならば、上の5つのうち、POST と PEEK がきっと余計です。プロセス間で CALL 的な動作を実現するためだけにメッセージを使う。というより、メッセージはシステム側で隠蔽してプロセス間コールできるんですよー。っていうインタフェースをユーザ側に見せる方が素直な気もする。 -- Gaku 2004-05-16 (日) 01:31:20
- きっと、サーバは別のプロセスから、SEND/RECEIVE/REPLY で CALL 的に呼び出されるのだけど、キューを持ちたければ、サーバプロセスの中でキューを持っていて、呼び出されたルーチンがキューに追加。追加するスレッドとは別にキューを読み出して処理を行うスレッドを用意。この2つのスレッド間は同期オブジェクトでキューへの操作を保護する。てな感じで、コールされるだけの場合も、キューに溜めて処理の調停を行う場合も、対応できるてな感じではないかと。 -- Gaku 2004-05-16 (日) 01:34:56
- なるほど。そろそろ決まったことをまとめて私用を固めますか? -- ひげぽん 2004-05-17 (月) 22:01:28
- いや、まだ固まってないなら放って置いても良いのでは。 -- Gaku
- 覚書 by ひげぽん
- プリミティブな段でメッセージングの機構をわけることも考慮に入れるのもあり(例えば、速度別・プロトコル別)
- サーバー⇔アプリ」を主眼にメッセージングを議論ってことであっていますか?
- チャネルって横方向だよ(後で整理)
- receive = peek ( peek はキュートップの取得? ) ていう話を見て、現在の Mona のメッセージキューはカーネル側にあるはずなので、キュートップを貰ってもユーザ側がメッセージを見ることは許されないのじゃないか。と思ったり。
- ユーザ側が受け取りたい特定のメッセージを待っているけど、待っている間に余計なメッセージが来る。だから、メッセージキューを持つ必要がある。現在はカーネルがキューを持っているが、カーネル側のキューはユーザ側から (直接) 見ることができないので、receive を使って、ユーザ側のキューへメッセージを移し変える機構を MonAPI が持っている状況。だと思います。
- ユーザ側が受け取りたい特定のメッセージを受け取ることを、キューを持つことで実現しようとする場合に (今の方向だと思うので) ユーザ側とカーネル側にキューを重複して持つのを避けたいという要求が、現在上がっているのだと思います。
- 解決策は、幾つか思い付いて・・・
- 1. カーネル側にキューを持つ。欲しいメッセージを特定して待つ機構をカーネル側に持つ (今のひげぽんの方針?)
- ちがいますねぇ。qnx方針がいちおしですカーネルはキューを持たない -- ひげぽん
- あれ?実は「5. キュー以外を考えてみよー」だったか。下のほうの返事からの意図を読み違えてた。 -- Gaku
- 2. ユーザ側にキューを持つ。スレッドにメッセージが届いたらカーネルはユーザ側のキューにメッセージを連結する。(ユーザがメッセージを見たければなんらかの方法でキューをロックしてある期間独占的に操作する)
- 3. カーネルにユーザ側の関数なりをコールバックとして登録する。カーネルはメッセージが届いたらユーザ側のコールバックを呼び出す。ユーザ側のコールバックでキューに連結しておく。後でメッセージが欲しいときになればキューの中を探してメッセージを取り出す。
- 4. 今のまま。2重なキュー。
- 5. キュー以外を考えてみよー。とか言い出す。
- それで peek と聞いたときに私が連想するイメージはキューに要素を連結したままで、その要素の中身を取得する。です。
- peek(&msg, index); とやると、index番目が msg に取得できるみたいな。でカーネル側にキューがあるとすると、peek はシステムコールになると思うので。。。それはかなり意味無いなと思ったり。(連想してるイメージが悪いかな。
- それで Mona の receive とか send で操作してるメッセージキューがユーザ側にあったら上の話は全く的外れだなぁ。(こんな長いのに)と思って確認のために、コードを読み始めてみました。
- 今のメッセージって test_higepon.cpp にある Messenger で実現してるんでしたっけ?(テスト状態だし・・・
- で Messenger::send で使ってる Messenger::allocateMessageInfo ですが allocated > size-1 の条件で allocated=0 してますけど。これキューに連結された状態のメッセージ要素をそのまま新しいメッセージ内容で上書きして重複してキューに繋ぐことがある。ってことですよね?もしかして。
- kernel.cpp を見ると g_messenger = new Messenger(512) とあるので Mona カーネルが扱えるメッセージの要素は全部で 512個までで、かつ、スレッドのメッセージキューに連結されたままほったらかしにされると、連結された状態の要素も強制的に再利用はじめるのかな?
- んー。g_messenger って test_higepon.cpp の Messenger 、、、ですよね。何か読み間違ったかな。
- ちなみに、カーネルはなるべくシンプルに。という方針だと理解したので、上で書いた方針1は、違うんじゃないかな。というのが感想。
- てな感じで -- Gaku 2004-05-11 (火) 23:32:22
- 実はみんなしてpeekの定義が違う?
私もGakuさん風味に peekはキュー全部を見る事が出来る(+それを捨てる事が出来る)、receiveはキュートップを取得(=peek(&msg, index = 0, flag = REMOVE | WAIT))ってのを考えています。 -- Yui_Neko
- peekが必要か不要か分かりません… 問題は「出来ない事がある」ということだけでしょう。
全て操作したいんなら post/peekのみでいける、いや、この2つのみで全部できなきゃいけない。
- send = post + peek
- receive = peek(ターゲットは全てのメッセージ = つまりキュートップ)
- reply = send + receive(個人的には要らない…というかマクロでいいじゃん?
- で、一番重要なのが、Monaの場合 普通のOSでやらない事をメッセージでやり取りしちゃうのが面倒な点。
ファイル操作なんかが尤もたる例で(いや確かにWin32でもソケットとかはメッセージでやるけどさ…)、ファイルとのやり取り中に別のメッセージが来る…普通では考えられない事が発生する。これをどう見るかがポイントかな。
- 昔ながらの伝統芸(?)なFIFOでユーザに全て押し付けるのか?
- それともキューを持たせてキューの中の特定メッセージを操作できる関数を用意するのか?
- MONAPIは基本的には後者の方向なんだけど、peekをreceiveの中に隠そうとするから(というか個人的には peekとreceiveが引っ付いたのが Message::Receiveという認識)、どっかで出来ない事が生まれるんだと思う。
低級で汎用性な物を望む。高級なのはユーザが勝手に作ればいいんです。(一応補足、ユーザが作れるから不要ではなく、どーせみんな書くんなら一緒のほーがいいじゃん?って意味だけであったほうが良い) -- Yui_Neko 2004-05-11 (火) 13:35:37
- キューが無い。という仮定なので、SEND は相手が RECEIVE していないとブロック。相手が RECEIVE 状態になると、SEND しようとしていたスレッドのうち1つが起きて SEND する。RECEIVE は SEND がされてなければブロック。SEND がされたら起きる。かな? SNED しあうとデッドロックしちゃうな。 -- Gaku 2004-05-10 (月) 00:17:40
- SEND した相手からの SEND の時は特別にエラーさせるなりすれば良いのかな。 -- Gaku 2004-05-10 (月) 00:26:29
- ていう事をした場合、基本的には CALL の動作しか使わない方が良さそう。ある場合は SEND できて、ある場合は SEND 失敗するのは気持ち悪いので。 -- Gaku 2004-05-10 (月) 00:27:47
- で、いままでの話題とはまた別の話になるんですが。QNX の SEND/RECEIVE/REPLY の話題へのコメント。 -- Gaku 2004-05-10 (月) 00:09:43
- REPLY と SEND って CALL のようなものを実現するんだと思うのですが、特定の SEND に REPLY って必要でしょうか。CALL した先のスレッドから来る次のメッセージは必ず REPLY (のためのメッセージ) であると仮定して良いのでは?<ならば、特定の SEND への REPLY でなく呼び出し元へのスレッドへの POST で REPLY の代わりに出来ると思います。<見落としがあるでしょうか? -- Gaku 2004-05-09 (日) 23:55:34
- 現在のMonaのメッセージングではREPLYが上記方法で実装されていますね。REPLYをわざわざひとつの機能にしたのは以下の意図があります。-- ひげぽん
- メッセージの機能として返事が送信先からのものだと仕組みとして保証される。
- そーいう方針である。ということですね。なら問題ありません。-- Gaku
- なので実装の内容に関しては上記のような感じでもよいと思います。
- SEND は POST したあと YEILD すれば実現できるんじゃないか?とか。どちらかと言えば YEILD した後起動するスレッドを指定したい気もしますが。 -- Gaku 2004-05-09 (日) 23:49:20
- 現在そのような実装になっています>SEND = POST + YIELD -- ひげぽん 2004-05-09 (日) 23:53:01
- SEND は現在のままで良いんではないか?と思っています。見落としがあれば、がらっと意見変える予定ですが。いまのところ上で書かれているような SEND と REPLY が必要?という立場で書いてます。 -- Gaku 2004-05-10 (月) 00:02:30
- 上の5つだと、機能的に SEND と REPLY が特定用途ぽくてなくても何とかなるんじゃないか。と思ってしまいます。 -- Gaku 2004-05-09 (日) 23:48:12
- 理解力がなくてすいません。どういうことでしょうか。SEND/REPLYが特定用途? -- ひげぽん
- ↑「REPLY と SEND って CALL のようなものを〜」でどーぞ。 - Gaku
- カーネル側にキューを持つならば PEEK はあったほうがユーザ側の操作を軽減できます。ユーザ側でキューが重複するよりはあった方が良いと思います。 -- Gaku 2004-05-09 (日) 23:51:30
- PEEK。必須かどうか議論の余地あり >shadowさん > Tinoさん >Gakuさん >Yui_Nekoさん-- ひげぽん
メッセージキューはどこに置くか by ひげぽん †
- QNXのドキュメントによればSEND/RECEIVE/REPLAYのブロックによる状態遷移を徹底すればカーネル側にはメッセージキューを持たなくてもよいということが判明。で必要であれば、ユーザー側にメッセージキューを持つと。
- 選択肢としては以下のものがあると思う。
- カーネルにキューを持つ
- ユーザーライブラリにキューを持つ
- カーネルに簡単なキューを、ユーザーライブラリに便利なキューを持つ
コメント †
コメントはありません。 コメント/議論/メッセージ?
- そーですねぇ。やって面白い範囲でないと本末転倒ですから。面倒だったら投げーとかも OK ですよね。よね? <私 FATFS.SVR 投げてるし -- Gaku 2004-05-10 (月) 23:37:57
- できることならそうしたいのですが、当面は0.2.0リリースのためのクイックハックに集中させてください。それ以後、時間があればということで。m(__)m -- Tino 2004-05-10 (月) 03:19:18
- いやー。混乱した方が面白いし、物事は進むので。もっと混乱の渦中に落としませう。 -- Gaku 2004-05-10 (月) 00:23:45
- ちょっとあれこれ深入りし過ぎて逆に混乱を招いたことを反省しているので、決定に従います。というわけでノーコメント。 -- Tino 2004-05-10 (月) 00:15:02
- >shadowさん > Tinoさん >Gakuさん >Yui_Nekoさん。皆様はどこにキューを置いたほうがよいと思いますか?理由も添えていただけるとうれしいです。 -- ひげぽん 2004-05-09 (日) 23:59:22
メッセージコード †