Lions' 本読み (30)

13 章に勝手に突入。psig 手続きの中で u.u_ar0 がレジスタを指す形になっちゃってるんですが、その根拠やいかに、という事で xref を引きつつ確認。
ちなみに psig を呼び出すのは

  • sleep
  • trap
  • clock

との事でそれぞれを確認した所、まず sleep が以下なカンジ。

2072    if(pri >= 0) {
2073            if(issig())
2074                    goto psig;

trap が以下で

2820 out:
2821    if(issig())
2822            psig();

clock が以下。

3824            if((ps&UMODE) == UMODE) {
3825                    u.u_ar0 = &r0;
3826                    if(issig())
3827                            psig();

あら? r0 て何? て思ってたら trap でも代入されてる箇所発見。

2701    u.u_ar0 = &r0;

ちなみに r0 ですが trap とか clock に渡される引数で 344p のカーネルスタックな図 10.1 のソレですね。ちなみに u.u_ar0 なカーネルスタックを指すナニの添字が unix/reg.h で定義されてて以下らしい。

2605 #define    R0      (0)
2606 #define    R1      (-2)
2607 #define    R2      (-9)
2608 #define    R3      (-8)
2609 #define    R4      (-7)
2610 #define    R5      (-6)
2611 #define    R6      (-3)
2612 #define    R7      (1)
2613 #define    RPS     (2)
2614
2615 #define    TBIT    020

む、てことは trap とか clock とかは良いとして sleep はどうなるんでしょ。ええと、330p の記述によれば sleep 手続きは

カーネルプロセスが自分を一時停止しようとしたときに、(コードのおよそ 30 の異なるところから) 呼び出される。


とのこと。んーと、でも該当箇所の記述が

2072    if(pri >= 0) {
2073            if(issig())
2074                    goto psig;
2075            spl6();
2076            rp->p_wchan = chan;
2077            rp->p_stat = SWAIT;
2078            rp->p_pri = pri;
2079            spl0();
2080            if(runin != 0) {
2081                    runin = 0;
2082                    wakeup(&runin);
2083            }
2084            swtch();
2085            if(issig())
2886                    goto psig;

みたくなってるな。sleep 呼び出し元を浚えてみるか。てか、今ようやく気づいたんですが sleep から psig 呼び出したら戻ってこないのか。
そもそも psig の以下なナニから

4059            u.u_ar0[R6] = n;
4060            u.u_ar0[RPS] =& ~TBIT;
4061            u.u_ar0[R7] = p;
4062            return;

return する時のスタックは一体どうなっててスタックの中身はどうされて何処に戻るのか、というナニが意味不明だな。特に sleep 手続き呼び出し時のカーネルスタックの状態がアレ。
これが割り込み、というかトラップ経由だったらカーネルスタックに積んであったレジスタを元に戻して云々、というのは想定可能なんですが sleep て一体。

ええと

goto て一体どーゆー事なんだろ。もう少し読んでみるとしてここで一旦エントリ投入。