Lions' 本読み (81)

朝練メモ。とりあえず unix/sys1.c の Page 3 あたりの_データセグメントを読み出す_部分の謎については調査保留ということで。

シグナル云々

psig 手続きあたり、理解が微妙な部分がある模様。呼び出し元をおさらいしてみます。

  • sleep 手続き (2066)
    • とは言え、直接呼び出している訳ではない
  • trap 手続き (2693)
  • clock 手続き (3725)

trap あるいは clock 割り込みから、ということなので u.u_ar0 からレジスタを云々できる模様ですが sleep がアレ。核心部分のコメントなどが以下なんですが

2100     * シグナルが存在する場合
2101     * qsav 位置へのローカルでない goto を
2102     * 実行する
2103     * (trap1/trap.c 参照)
2104     */
2105 psig:
2106    aretu(u.u_qsav);

これ、システムコール実行中に発生したシグナルの後始末らしい。システムコールの実態を呼び出している部分が以下なんですが

2841 trap1(f)
2842 int (*f)();
2843 {
2844
2845    u.u_intflg = 1;
2846    savu(u.u_qsav);
2847    (*f)();
2848    u.u_intflg = 0;
2849 }

手続き f を実行中にシグナルが発生して優先度が 0 以上で sleep する場合、上の aretu を介して 2772 の trap1 手続き呼び出しの次の命令に制御が移ることになります。
この時、u.u_intflg は 1 のまま (2848 行の命令が実行されていない) なので u.u_error に EINTR が格納されるのか。

2771            trap1(callp->call);
2772            if(u.u_intflg)
2773                    u.u_error = EINTR;

u_error のコードについては確認の必要がある模様。ここからどうなるのかが分からず。つか、u.u_error て errno なのか。man errno したらありますね。

       EINTR           Interrupted function call (POSIX.1); see signal(7).

うう、なんか微妙な所でヒッカカってるなぁ。とりあえずシステムコール実行中に signal 発行されて sleep するケイス、というのがイメージできてないのでそちらを整理する必要あり。