前回から読み進めた結果のまとめ。
まず、プリエンプションについては前回読み解いた通りの模様。
ただし端末から操作してるプロセスに関してはttyからの入出力で絶えず割り込みによるタスクスイッチが発生するので1秒という持ち時間は気にならない。
実際、この1秒のタスクスイッチを実験で観測しようとするとかなり難しい。システムコールも割り込みもなしにプロセスの状況を計測する手段がない。例えば、前回みたいな空ループのプロセスと、ひたすら“hello”と出力し続けるプロセスを同時に実行しても、どちらも違和感無く同時に実行されているように見えてしまう。これはhello側の実行を律速しているのがtty出力待ちであって、一文字書いてはタスクスイッチを行い、tty出力が終わると再びタスクスイッチでhelloに実行が戻る、といった処理が行われるため。一応、これについてはUNIX 7版上で実際に試してみました。
また(Lionsの順番通り)スワップアウトの処理を理解した上でスケジューラを読み直してみると、スワップアウト後は3秒経たないとスワップインさせない仕様や、スワップイン後にアクティブなプロセスが残っている状況では2秒経たないとスワップアウトさせない、といった仕様が目につく。これは4秒ごとの神の雷や、1秒ごとのプリエンプションとの相性を考えると妥当な数字のようだ。一度スワップすると3秒は戻ってこない、というのは凄いけど。。。アプリケーションのサイズの物理メモリの搭載サイズの差が小さかった状況を考えると、当然の実装かもしれない。
あと、順序的にはclockの話とスワップの話の間になりますが、システムコール入口やsignalの処理についても読み終わりました。
システムコールについてはプロセスの起動、終了やsignal関係、つまりはプロセス処理関連を読み終えました。ちょっと前の日記で疑問として書いた件ですが、execによるとやはり命令空間分離やデータ領域分離は実行ファイルの持つマジックナンバーが違うようです。またexitとwaitの関係とか。exitすると終了コードをswap空間に残して親がwaitで回収するのを待ちます。親が死ぬとinitの子供になるとか、ゾンビプロセスについての説明で出てくるような話も当時から存在した模様(swap空間に残す、というのが独特かもしれませんが)。
signalはSIGKILのみ上書きはできないけど、最後に呼ばれた1つしか覚えていない、という実装になってますが、これはそういうものなのかな。。。signalは取りこぼさないと思ってたんだけど、保証はしてないのかな。
まだ確証が得られるまで読み込んでないけど、signalが設定されたら即座に対象プロセスを起こしてハンドラを起動させているように見える。。。けど、たぶんスワップアウトしていたらスワップインを起動して再びスケジューラを起こすので、別プロセスから多重でsignalを設定される事はありそう。。。 まぁ、またそのうち見直すとします。
あとは特殊なsignalとしてptraceの処理。ptrace自体使った事がなかったので、こんな機能があったのかと勉強になりました。子プロセスのメモリ空間なら触る事ができるんですね、UNIXは。子供側からも許可を出す必要があるみたいだけど、これはforkしてから許可を出してexecすれば済む話のはず。
この辺はC言語からの引数とsystem call時の引数の順番が違っていて、読んでいて少しはまりました。7版でmanを見たらアセンブラからの呼び出し例が書いてあってようやく誤解に気づく罠。
Lions本とは関係ないけどBach本も入手。こっちはファイルシステムから解説に入るんですね。単独で読めるのでしばらくはトイレに常駐させときます。ぱっと見た感じではSystem Vになっても6版の構造はかなりひきずってるみたいですね。u区域とか重要な関数の名前なんかはそのままなので疑似コードからソースが想像しやすそう。
6版のソースは逆に残すところファイルシステムとドライバ関連のみ。どっちを読んでも、しばらくはファイルシステムべったりです。こっちは昼休みとか使ってコメント埋め込みつつMercurialでログをとってます。
今回は長文でした。
0 件のコメント:
コメントを投稿