Lions' 本読み (32)
どうも sched な手続きの理解が微妙。63p にある proc 構造体の p_stat 属性と p_flag 属性の意図するナニを理解できてないのが敗因なのかどうなのか。
状態として定義されているのは以下なんですが
0379 /* 状態コード */ 0380 0381 /* null 0 割り当てられていない */ 0382 #define SSLEEP 1 /* 高い優先度でスリープ中 */ 0383 #define SWAIT 2 /* 低い優先度でスリープ中 */ 0384 #define SRUN 3 /* 実行中 */ 0385 #define SIDL 4 /* プロセスは生成処理中である */ 0386 #define SZOMB 5 /* プロセスは終了処理中である */ 0387 #define SSTOP 6 /* プロセスはトレース処理中である */ 0388 0389 /* フラグコード */ 0390 0391 #define SLOAD 01 /* コア中 */ 0392 #define SSYS 02 /* スケジューリングプロセス */ 0393 #define SLOCK 04 /* プロセスはスワップされない */ 0394 #define SSWAP 010 /* プロセスはスワップアウト中である */ 0395 #define STRC 020 /* プロセスはトレースされている */ 0396 #define SWTED 040 /* 別のトレースフラグ */
力技で xref でもごもごしてみます。
ちなみに、#0 なスケジューラは最初に以下な初期設定らしい。
1592 proc[0].p_stat = SRUN; 1593 proc[0].p_flag =| SLOAD|SSYS;
次に出てくるのが newproc な手続きでの初期設定で以下。
1861 rpp->p_stat = SRUN; 1862 rpp->p_flag = SLOAD;
あ、これって定数で xref 引くより属性で確認した方が良いのかな。ちなみに空いた proc 配列の要素を探す時には p_stat が NULL な要素を云々してます。
また、newproc 手続きで malloc で領域確保できなくてカレントプロセスをスワップアウトする処理では SIDL になって SRUN になるナニが見れます。
1902 if(a2 == NULL) { 1903 rip->p_stat = SIDL; 1904 rpp->p_addr = a1; 1905 savu(u.u_ssav); 1906 xswap(rpp, 0, 0); 1907 rpp->p_flag =| SSWAP; 1908 rip->p_stat = SRUN;
sched な手続きでは_実行可能状態で最も長い時間スワップアウトされていたプロセス_の探索な条件分岐が以下なのか。
1961 if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 && 1962 rp->p_time > n) {
p_time が何を表現しているのか、はちょっとタイム。同じ sched 手続きで_安易にコアを見つけようとする_ナニが以下。
1992 if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD && 1993 (rp->p_stat == SWAIT || rp->p_stat == SSTOP))
1992 な記述は p_flag 属性 (の末端 3bits) が SLOAD しか上がってない、という事で良いのかな。なんとなく安易に、てのが理解できる条件式ですね。
あるいは_コア中に最も長く存在したプロセス_的な記述が以下なのか。
2007 if((rp->p_flag&(SSYS|SLOCK|SLOAD))==SLOAD && 2008 (rp->p_stat==SRUN || rp->p_stat==SSLEEP) && 2009 rp->p_time > n)
ちょっと意味合いが異るのが分かります。
次は sleep 手続きで、p_stat は SWAIT になる模様。
2077 rp->p_stat = SWAIT;
2090 でも同様な記述。
そして setrun では SRUN が設定。
2140 rp->p_stat = SRUN;
次は swtch における_最も優先度の高い実行可能プロセスをサーチする_条件式
2208 if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)!=0) {
SRUN で SLOAD じゃない、というナニ。
もう少し頑張ります。p_flag は次回以降なカンジ。exit では状態が以下に変更されている模様。
3243 q->p_stat = SZOMB;
で、親プロセスを見つけて SSTOP な状態なら setrun してますね。ちょい謎。
3250 for(p = &proc[0]; p < &proc[NPROC]; p++) 3251 if(q->p_pid == p->ppid) { 3252 p->p_ppid = 1; 3253 if (p->p_stat == SSTOP) 3254 setrun(p);
このあたり、別途きちんと見たいのですが、SZOMB なナニを始末するのが wait らしい。
3280 if(p->p_stat == SZOMB) { 3281 u.u_ar0[R0] = p->p_pid; 3282 bp = bread(swapdev, f=p->p_addr); 3283 mfree(swapmap, 1, f); 3284 p->p_stat = NULL;
初期化されてますね。ちなみに wait では p_stat が SSTOP な要素についても云々してますがスルーします。
fork では proc 配列を線形探索して p_stat が NULL のものを云々、な処理をしてます。ここでも無かった場合のナニが気になります。
3328 if(p2->p_stat == NULL) 3329 goto found; 3330 u.u_error = EAGAIN; 3331 goto out;
次に出てくるのは clock の sched なナニな模様。
3810 for(pp = &proc[0]; pp < &proc[NPROC]; pp++) 3811 if (pp->p_stat) {
これ、348p で記述されている_現存するすべてのプロセスに対して次の処理をする_というあたりのナニなのかなと。
て、次に出てくる以下は何だ。psignal 手続きです。
3973 if(rp->p_stat > PUSER) 3974 rp->p_stat = PUSER; 3975 if(rp->p_stat == SWAIT) 3976 setrun(rp);
PUSER て定義は以下だな。
0160 #define PUSER 100
普通に考えてそうなるはずはないんですがスルー。後は
- stop 手続きで SSTOP な状態になっている
- ptrace 手続きで SSTOP な状態のものが処理対象の候補になっている
というカンジ。
sched 手続き
で runout と runin な状態というのが読めるのかどうなのか。そろそろ色々な意味で限界なのでクタバります。