2009年11月3日火曜日

Lions' Commentary (3) - setpriの真相はいかに -

setpri(2156)にはちょっとした問題がある。

関数のコメントには以下のように書かれている。

2150 /*
2151  * Set user priority.
2152  * The rescheduling flag (runrun)
2153  * is set if the priority is higher
2154  * than the currently running process.
2155  */
つまり、優先度を再計算して、現在実行中のプロセスより優先度が高くなっていたら再スケジューリングのためにrunrunを++する、と書かれている。ところが実際のコードは
2156 setpri(up)
2157 {
2158         register *pp, p;
2159 
2160         pp = up;
2161         p = (pp->p_cpu & 0377)/16;
2162         p =+ PUSER + pp->p_nice;
2163         if(p > 127)
2164                 p = 127;
2165         if(p > curpri)
2166                 runrun++;
2167         pp->p_pri = p;
2168 }
 であり、再計算した優先度が、実行中のプロセスの優先度より低ければ(if (p > curpri))再スケジューリング(runrun++)となっている。

で、Lions本によれば「自力でバグでない事を確認せよ(ヒント:呼び出し時の引数)」との事。さっそくgrepした感じではsetpriはプリエンプションの時に呼ばれているように見える。つまり、走行中のプロセスが持ち時間を使い切ってタイマーによって割り込まれた際に、CPU使用時間を計上してからsetpriを呼んでいる。優先度を下げる方向で再計算させているのであり、curpriは走行中のプロセスが選択された時の優先度。 下げてるんだからここでは常に「p > curpri」が成立するのは自明であり、再スケジューリングが走るのはしかるべきである。つまりコメント側が間違っている、という理解。バグではないという事で納得した・・・と思ったんですが。。。

例の2238 Clubにはバグという記述がありました。確かにベル研の資料には以下のように書かれている模様。
30)
    Bug fix in "setpri()": p>curpri should be p<curpri.
むぅ・・・公式にバグと言ってるわけだから、やっぱりバグなのだろうか。。。
真実を知っている人がいたら、ぜひ答えを教えて下さい。

simhと7th UNIX

我が家ではsimh上でAncient UNIXを動かしています。
具体的にはPDP11版の7th Editionに2BSDをインストール。自前パッチとして
  • date 2000年問題対応
  • vi hjklカーソル移動対応
  • vi 大画面対応
あたりを施した状態なんですが、動作中にCPUを食い潰しにいくのが気になってました。大昔のUNIXなんて電力制御も糞もないので、idle時にbusy loopでもしてるんだろう、と思ってたんですが、スケジューリング周りのコードを理解すると、きちんとスケジューリング対象がいない時にはidle()からwait命令を発行してCPUが割り込み待ちで寝るように作ってあります。
という事は・・・と思ってsimh側を見てみたら、どうやら「set cpu idle」を設定してあげないといけないようでした。

という事で、うちの設定は(ストレージ周りの設定を除くと)
set cpu u18
set cpu idle
set tti 7b
set dz 7b lines=16
att dz -am 4096
こんな感じです。
コンソールはマルチプレクサ(dz)通してtelnetで入れるようにしてあります。
7bってのはvi使うときに必要な設定で、これがないとtermcap使った画面制御がうまくいきません(制御ビットがマスクされちゃう)。viのbuildに成功して最初に起動したときは相当はまりました。termcapの設定ミスかと思って色々追いかけましたが、まさかsimh側の設定に問題があったとはorz 最近の環境に慣れ親しんだ身としてはcatとedだけの探検というのはジャングルでの生活に匹敵しますね。

2009年11月2日月曜日

Lions' Commentary (2)

ちょっと忙しくなって進捗が停滞してました。
仕事のコードレビューとかいつも数万行単位で実施してて、その時間を6版のレビューにあてられたら、すぐなのになぁ・・・とか思ったりします。って前回も同じ事書いてたか(汗

という事で、風邪をひいて熱を出してしまい、せっかくだから病院で読み進めました。
Lions'本でいうところの7章プロセスのあたりを読みました。外なので訳本で読んでたんですが、P.322の表に誤字がありますね。t+16,t+144って書いてあるところ、d+16,d+144が正しい。オリジナルの資料を確認したらそっちは正しく書いてありました。

Kernel空間と違ってUser空間はブロック(64B)単位(MMUが扱える最小単位)に細かくMMUを張ってますね。ページ単位に慣れた現代人としてはちょっと気持ち悪いですが。suregの最後(1762)のアドレス補正はちょっと難しい。アドレス空間分離モードだと必ずx_caddrが設定される、という前提のコードという理解で良いのだろうか。。。

まだローダとか見てないんだけど、命令/データ分離の場合とそうでない場合で実行ファイルの互換性ってないのかな?

完全には消化しきれていない感じです。

2009年10月25日日曜日

Lions' Commentary

積まれてたタネンバウム先生のModern Operating Systems(しかも初版)を最近になって読みました。
後半の分散OSのところはどこまで生き残ってる話かわからなかったので、RPCやNFS以外は流し読みでしたけど。

で、いっそのことOS関連をざっと勉強し直そうかな・・・と思って資料をあさっていたところで見つけたのがLions' CommentaryのPDF版。おぉ、まずはこれを読もう!ということで、ちびちびと読み始めてます。Kernel部分は1万行程度だったりするので、仕事でレビューさせられてる大量のコードに比べるとかわいいもんです。がぜんやる気が出てきました。

現在のところ、initを起動するところまでの流れを見渡して、プロセス管理を深く見直すあたりまでいってますが、とりあえず感想とか少しずつ書いてみようかと。

まず最初に面食らうのはCの文法。K&R前の代物で、型チェックがまったくないとか、構造体が無名でグローバルに参照可能とか。構造体の要素にp_とかプレフィックス付けてるのは、名前空間が存在しないがゆえか。。。型に関係なくいきなりfoo->intvalみたいな形でポインタの読み替えをしてくるので油断できません。

最初に見るのがメモリ管理。といってもページ管理みたいな大層なものではなく、ほんとにナイーブなmalloc/freeの実装。というか、アドレス順に並んでるのにリストですらない!!途中の要素を取り出すと、後ろの要素を全部1つずつ前に詰めるという・・・。ちょっと驚きました。

初期化部分はPDP-11のアセンブラで、ここも変な文法に悩まされるわけですが、2238 Clubに助けられました(笑。

ようやくCの世界に入るmain呼び出しの直前にMMUの設定がありますが、ここでまだジェネレーションギャップというか。MMUとは言っても最大8KBページが8エントリまでしかないんですね。つまり論理アドレス空間は64KB。おぉぉぉ・・・そっか純粋な16bit CPUじゃそうだよな。。。Z80以降の感覚だと8bit CPUでもメモリ空間だけは16bitだったり、16bit CPU(例えばMC68000)でもメモリ空間だけは24bitだったりしてたので、これはちょっと焦りました。そっか・・・初期のUNIXは64KBで動けたんだ・・・。

で、この8エントリのうち6エントリまでがKernelが使ってまして7エントリ目にユーザプロセス空間、8ページ目にI/O空間がマップされます。確かにこういうところからスタートしてると、スワップとかページ単位じゃなくてプロセス単位にもなりますね。。。という事で、歴史を堪能しております。

2009年9月26日土曜日

Spacewar!

しばらく前に作ったDEC PDP-1のエミュレータをベースにActionScript(Flash)版のエミュレータを作ってみました。せっかくのFlash版なので表示はそれっぽく・・・と思ったのですがセンスが足りないためイマイチな表示になってしまいました。

太古のマシンなわけですが、表示が1024x1024の解像度があり、残像やらボカシやら縮小やらで、表示系がずっしり重たい処理になってしまいました。エミュレーション自体はたいした事ないんですけどね。。。後でソースを1つにまとめてWonderflにも投稿したいと思います。

ちなみに動いているのはSpacewar! 知っている人は知っていると思いますが、世界で最初のテレビゲームと言われている物です。パンチカードの情報をデジタル化したファイルがありまして、そいつを読み込んで実行しています。

個人的な目的としては、プリプロセッサを使ってC++向けのコードとActionScript向けのコードを共通化する実験とか、版管理ツールとしてMercurialを使ってみる実験とか。

追記:さっそくWonderfl向けにカスタマイズして投稿してみました。

2009年8月12日水曜日

wonderfl続き

Frocessing版があまりにも重たかったのでBitmapData使って直接描画するバージョンも作ってみました。私の使い方が悪いだけなんですが。。。画面の再描画が常に走ってたのがいけないのですが、その辺の制御の仕方がわかりませんでした。どうせflashで描くならドット単位の描画ではなく、ベクターで描くタイプのプログラムを組んでみたいですね。


追記:再描画はnoLoop();で抑制できるようでした。また、pointを使っていたのがまずかったようです。F5MovieClip2Dではなく、F5MovieClip2DBmpを継承すればpixelが使えて高速化できるそうです。前者では画素ごとにシェイプが作られる・・・だそうで。。。すみません。

2009年8月10日月曜日

ProcessingとかActionScriptとか

今更だけどProcessing(*1)を試してみました。
事始めに参考書としてJohn Maeda氏のDesign By Numbers(*2)とかBen Fry氏のVisualizing Data(*3)も読んでみました。前者はプログラムを全く知らないデザイナ向けのCG入門書でしょうか。後者はエクセルを使ったグラフ作成より一歩進んだ事をプログラムを使って表現したい人向け。ただ、スクリーンスクレイピングの説明をはじめとして、本筋ではない雑多な話題についてのページが多く、読んでみると中途半端な感じがしました。やはりプログラマ向けの書籍ではないために感じる違和感かもしれません。
実際ちょろっと使ってみると確かに便利は便利。ただ最初の敷居が低いだけで、アルゴリズム組み始めるとその先は他のライブラリ使って組み上げるのとあまり手間は変わらないかなぁ・・・。

で、こちらも今更なんだけど、ActionScriptを使える開発がオンラインで行えるサイトWonderfl(*4)も試してみました。せっかくなので、Processing互換のライブラリFrocessing(*5)を使って遊んでみましたが・・・この手のサービスとの相性は良いですね。
最近ウェブを漁っていてマンデルブロと類似の図形でバーニングシップというのがあるのを知って、面白そうだったので練習題材にしてみました。やっぱりちょっと重いかなぁ・・・。マルチコアのマシンでないとブラウザが操作効かなくなるかも。。。






*1:Processing 1.0
*2:Design By Numbers
*3:ビジュアライジング・データ —Processingによる情報視覚化手法
*4:wonderfl
*5:Frocessing