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 て一体どーゆー事なんだろ。もう少し読んでみるとしてここで一旦エントリ投入。