[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]

[OSASK 1509] Re: memory management.



  こんにちは、川合です。


nabe さんは 2001/02/16 06:03:06 の「[OSASK 1507] Re: memory mana
gement.」で書きました:

>>  僕が嫌いな命令は、STRとSLDT命令です。この命令はアプリからも実
>>行できます。僕が嫌いなのは、TRやLDTRの値はシステムが管理して把握
>>している値なのに、それをアプリが参照できることです。
>えっ特権レベル0 以外でも実行できてしまうんですか??
>てっきりOS命令の欄にあるものは全部 特権0 が必要なのかと思った(汗)

  ええと、追加です。CPL == 3でも実行できてしまうシステムレジスタ
周りの命令は他にもありました。

    STR, STR, SGDT, SIDT, SMSW

さらに、CPL == 3でも実行できるシステム制御命令もありました。

    INVD, WBINVD, INVLPG

これらは僕の大嫌いな命令です。高く評価していたインテルの設計セン
スを疑ってしまいそうです。どんなに良いアプリケーションでもこの命
令を使ったら「川合秀実推奨」は付けませんよ(笑)。

>仮想化、抽象化ですね。
>OSASK 自体はすべてシグナルで繋がるんですね、やっぱり。

  ええと、誤解しないでいただきたい事があります。だから、その話を
先に書きます。

  シグナルと共有バッファによって接続されるのは、OSASKのアプリケ
ーションでの話であって、他には適用されません。もっと厳密には、OS
ASKのアプリケーション規格には数多くのバリエーションを予定してい
て、今話題にしているのは「ぐいぐい00」というOSASKアプリケーショ
ン規格に限定した話です。他のアプリケーション規格ではこのルールは
崩れているかもしれません。以下でもOSASKアプリケーションという単
語を使っていますが、ぐいぐい00限定の話です。

  OSASKアプリケーションの入出力の全てをまとめると、こんな風にな
ります。

・アプリから外部への出力手段
  far-call
  外部へのシグナル出力
  共有バッファへの書き込み

・アプリの入力手段(外部からの情報を得る手段)
  far-call
  シグナル入力
  共有バッファからの読み込み

  「far-call」っていうのは、要するに外部ルーチンを呼ぶわけです。
これは何でもできます。引数で外部に出力することもできますし、返値
で外部からの情報を受け取ることもあるでしょう。OSASKアプリではDLL
もfar-callで呼ぶだけなので、DLL-callもfar-callに含まれています。
far-callっていうのは実感がないかもしれませんが、ASKAで

    DB(0x9a); DD(0); DW(0x00c7);

と書くのがfar-callの例です。これはASKAでOSASKアプリを作る時によ
く見かけますね。

  「外部へのシグナル出力」は、主にアプリ間の通信に使われます。マ
ルチスレッドでプログラミングしている時にお世話になるでしょう。wi
nman0がウィンドウ制御するときも、これを多用しています。もちろん
、CPUにはシグナル出力命令なんてありません。従って、これも適切な
パラメーターをセットしてfar-callでシステムコールすることで実現し
ています。ですからこれをfar-callに分類することもできるでしょう。

  「共有バッファへの書き込み」は、実に簡単で、メモリへ書き込めば
いいだけです。システムからみると、アプリの全てのメモリ領域は丸見
えで、見方によってはアプリの全メモリが共有バッファとして使えるこ
とになります。実際、ほとんどのシステムコールはFS:EBXにポインタを
入れて呼び出すルールになっていますが、これはFS:EBXで指された領域
をシステムとアプリとの共有バッファとして使っていることになります
。

  マルチスレッドなどでアプリ間で大きなデーターをやり取りする時は
、共有バッファを持って入出力するのが望ましいです。もちろん、原理
的にはシグナルでも問題はないのですが、シグナルは大きなデーターを
やり取りすることよりもリアルタイム性を追求しているので、効率が悪
いです。ですから、共有バッファにデーターを書き込んで、共有バッフ
ァへのポインタをシグナルで渡し合うような使い方が推奨されています
。

  「シグナル入力」は、方法が2つあります。一つはポーリングです。
これは初心者向けの手法で、シグナルをバッファに溜めさせておいて、
必要に応じてチェックする方法です。もう一つは、割り込み制御による
方法で、シグナルが着た瞬間にユーザーが定義したシグナルハンドラへ
分岐します。シグナルハンドラへの分岐は、CPUの割込み制御のように
一時的にマスクすることもできます。シグナル処理中に次のシグナルが
来ても、ちゃんとキューイングされます。

  なべちゃんさん向けに話を書けば、FM-TOWNSとかでプログラミングす
るときは、タイマー割り込みを利用する時は関数timer()が呼ばれて、V
SYNC割り込みを利用する時は関数vsync()が呼ばれて、そんでもってキ
ー入力があるとkeyint()が呼ばれる・・・みたいにプログラムするじゃ
ないですか。それを、タイマー割り込みが来たらシグナル0x1234、VSYN
Cが来たらシグナル0x5678、キー入力があったら、0x9abcとキーコード
からなる8バイトのシグナル、といった風にするわけです。これは果た
して便利なのかというと、ええ、もちろん便利です。アプリは割り込み
ルーチンを一元化できますし、元のように各ルーチンを呼ぶ仕様がお好
きなら、シグナルハンドラをswitch〜caseだけにしておいて、各caseで
それぞれの関数を呼び出せばいいです。一方、前のメールにも書きまし
たがシステムはアプリを制御するのは単純になり、好都合です。

  「共有バッファからの読み込み」は単にメモリリードです。簡単です
ね。

>デバイスドライバとかも、基本的にはシグナルでのみ結合するのですか?

  デバイスドライバーにはいろんな設計方針があると思いますが、僕は
仮想化とか抽象化を追求するよりも速度や安定性を追求すべきだと考え
ています。

  したがって、アプリからデバイスドライバーへの情報伝達は、far-ca
llがメインです。デバイスドライバーはタスクでさえありません。デバ
イスドライバーはGDT上に配置され、タスクスイッチせずに呼び出され
ます。アプリがデバイスドライバーを直接制御することはあまりないか
もしれませんが、あるとすれば、LDT内のゲートをくぐって呼び出すこ
とになります。

  デバイスドライバーからアプリへの情報伝達は、事前に設定しておい
た共有バッファに書き出すか、もしくはシグナルを送ることです。

  デバイスドライバー間、その他のシステムルーチンとのやりとりなど
は、シグナル以外の方法も使われます。この辺の抽象化はもはやどうで
もいいことで、効率と安定が全てだと考えています。

>>知りたければ、シェルに聞いてください。シェルが教えてくれます。た
>>だし、本当のことを教えるかどうかは別ですが(笑)。
>シェルがカーネルに近い役割をするのですか?

  はい。OSASKのシェルは、普通のOSとは立場が違います。

  詳しいことは、[OSASK 842](2000/06/11)を参照してください。


  それでは。

--
    川合 秀実(KAWAI Hidemi)
川合堂社長 / OSASK計画総指揮 / カーネル開発班
E-mail:kawai !Atmark! imasy.org
Homepage http://www.imasy.org/~kawai/