UNIX 6th code reading - signalシステムコール続き
はじめに
今回は第13章の続きを見ていきます。
grow
grow( )は引数で渡されたspを含むようにスタックを拡張します。既にスタックがspを含んでいたら拡張はしません。
絵で描くとこんな感じです。
- 4141-4142 : 既にスタックが十分大きければreturn. 拡張しない。この式の意味は後で考える
- 4143-4145 : スタックの必要な拡張サイズを求め、それが正であることをチェック。正でなければreturn. 拡張しない。このチェックが4141のチェックと重複しているような?
- 4146-4147 : estaburを使ってユーザセグメンテーションプロトタイプを、スタック拡張したものに対応するよう変更する。失敗したらreturn.
- 4148 : expandを使ってスタック領域を拡張
- 4149 - 4155 : 拡張したスタック領域の初期化?
- 4156 - 4157 : スタックサイズを更新し、拡張成功したことを表すためreturn 1.
exit
プロセスが自分自身を終了するときに呼ばれる。
自分自身をコアから解放
自分自身をコアから解放します。プロセス固有領域の前半(重要なところだけ?)はswap領域に待避しておき、親から(?)見られるようにしておきます。終了したプロセスはゾンビ状態(SZOMB)になります。
- 3224 : トレースフラグをリセット
- 3225-3226 : 全てのソフトウェア割り込みを無視するため、全てのu.u_signal[n]を1に設定
- 3227-3231 : このプロセスが開いていたファイルを全て閉じる
- 3232 : カレントディレクトリの参照カウントをデクリメント
- 3233 : 共有テキストセグメント(?)を解放
- 3234-3236 : swap領域から1 block(256 word)取得。ここにu(プロセス固有領域)を待避しておいて、親プロセスから見られるようにしておく。3241で、mfreeによるメモリ解放をしているが、その後でも見られるようにするためだと思う。ゾンビ状態の始末や復帰(できるのか?)のため?swapに空き領域がなければpanic.
- 3237 : バッファを取得
- 3238 : 取得したバッファに、プロセス固有領域の前半だけ(?)を格納
- 3239 : そのバッファをスワップ領域に書き込む
- 3240-3243 : 使用していたコアを解放し、カレントプロセスのアドレスはswapの領域を指すようにする。また、状態をゾンビモード(どういう状態?復活できる屍?)にしておく
親プロセスを起こし、子プロセスがSTOP状態ならば解除する
親プロセスを探しだし起こします。子プロセスも探し、STOP状態ならば解除します。また子プロセスの親プロセスを#1(ブートストラッププロセス)にし、「状態の被後見人?」にします。
- 3246-3247 : 親プロセスを探す
- 3248 : ブートストラッププロセスを起こす(なんのため?)
- 3249 : 親プロセスを起こす
- 3250-3251 : 子プロセスを探す
- 3252 : 子プロセスの親プロセスをproc#1にする(何のため?)
- 3253-3254 : STOP状態ならば解除する
- 3256 : swtchを呼び出し実行プロセスを切り替える。終了したプロセスはSZOMBになっているので、選択されることはない
- 3259 : 親プロセスが見つからなかったら、カレントプロセスの親プロセスをproc#1にし、3245へループ。proc#1は必ず存在しているので、ループ後は必ず親が見つかる(はず)
wait
waitシステムコールを実現します。
(exit( )によって)ゾンビ状態になっている子プロセスを探しだし、それを始末します。
また、STOP状態(トレース参照)にある子プロセスを見つけ、その状態を解放します。
ゾンビ状態にある子プロセスを始末する
- 3277-3278 : 子プロセスを探す
- 3279 : f(子プロセスが見つかったフラグ?)をインクリメント
- 3280 : 子プロセスがゾンビ状態ならば
- 親に伝えるため?子プロセスのpidをr0に格納
- スワップに待避していたプロセス固有領域を解放
- プロセスの設定(idなど)を初期化(→空エントリをproc[ ]配列に戻しているとも言える)
- 時間関係の設定を加算?
- 親に報告するためr1にu_arg[0]を格納(何が入っている?)
STOP状態にある子プロセスを解除
- 3301 : 子プロセスがSTOP状態ならば
- 3302 : SWTEDフラグが立っていなかったら(親プロセス=カレントプロセスがこの子プロセスがSTOP状態であることを知らなかったら?)
- 3303 : SWTEDフラグを立てる
- 3304-3306 : waitの返り値として?r0, r1にpid, {psig, '1111111'}を格納
- 3307 : return. このあと親プロセス(=カレントプロセス)のptrace( )処理を期待する?そこで子プロセスのSWTEDフラグが解除される
- 3309-3310 : SWTEDフラグが立っていた場合。つまり、一度3303でフラグを立てた後、親プロセスがptrace( )による処理を行われないまま再度wait( )が実行された場合。親プロセスは子プロセスのトレースに興味がなくなったと判断し、STRC, SWTEDフラグを解除し、setrunでSRUN状態にする。つまりトレース状態の解除
- 3302 : SWTEDフラグが立っていなかったら(親プロセス=カレントプロセスがこの子プロセスがSTOP状態であることを知らなかったら?)
- 3313-3317 : 子プロセスが見つかったが、ゾンビ状態でもSTOP状態でもなかった場合寝る。起きた後再度チェックを行う。子プロセスがみつからなかったらエラー
終わりに
少し短いですが今回はここまで。次回のエントリでトレースを追い、13章を終える予定です。