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は必ず存在しているので、ループ後は必ず親が見つかる(はず)

rexit

exitシステムコールを実現します。exit()を呼び出す前に、u.u_arg[0]を設定します(なんのため?)。

r0の下位バイトには親プロセスに通知する状態が入っています(?)。

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状態にする。つまりトレース状態の解除
  • 3313-3317 : 子プロセスが見つかったが、ゾンビ状態でもSTOP状態でもなかった場合寝る。起きた後再度チェックを行う。子プロセスがみつからなかったらエラー

終わりに

少し短いですが今回はここまで。次回のエントリでトレースを追い、13章を終える予定です。