φ(.. )メモシテオコウ このシリーズ3回目はsched_setrunnable()とsched_nice()を見てみます。
まずはsched_setrunnable()から。
331 void 332 sched_setrunnable(struct lwp *l) 333 { 334 335 if (l->l_slptime > 1) 336 updatepri(l); 337 }
内容としては「(´-`).。oO(lwpが1秒(単位は秒ですよね?)以上寝てたらプライオリティを変えるんだな」と予測できますね。
125 u_int l_slptime; /* l: time since last blocked */
sys/sys/lwp.hで変数のコメント見てみると↑ように書かれています。
それではsched_setrunnable()の処理の本体と言えるupdatepri()を見ましょう。
310 static void 311 updatepri(struct lwp *l) 312 { 313 fixpt_t loadfac; 314 315 KASSERT(lwp_locked(l, NULL)); 316 KASSERT(l->l_slptime > 1); 317
ここまでは特に問題無いですね。
318 loadfac = loadfactor(averunnable.ldavg[0]);
loadfactor()は関数では無くてsched_4bsd.cで定義しているマクロとなっています。
236 /* calculations for digital decay to forget 90% of usage in 5*loadav sec */ 237 #define loadfactor(loadav) (2 * (loadav) / ncpu)
このマクロについている説明はFreeBSDカーネルの設計と実装のP140にある「減衰処理が5回行われると~」というところに該当してそうです。
averunnable.ldavgは昨日調べたので飛ばします。
319 320 l->l_slptime--; /* the first time was done in sched_pstats */
l_slptimeの値を1減らして(負にならない or なってもOKということ?)
321 l->l_estcpu = decay_cpu_batch(loadfac, l->l_estcpu, l->l_slptime);
cpuの利用度をdecay_cpu_batch()で再計算します。
258 /* 259 * For all load averages >= 1 and max l_estcpu of (255 << ESTCPU_SHIFT), 260 * sleeping for at least seven times the loadfactor will decay l_estcpu to 261 * less than (1 << ESTCPU_SHIFT). 262 * 263 * note that our ESTCPU_MAX is actually much smaller than (255 << ESTCPU_SHIFT). 264 */ 265 static fixpt_t 266 decay_cpu_batch(fixpt_t loadfac, fixpt_t estcpu, unsigned int n) 267 { 268 269 if ((n << FSHIFT) >= 7 * loadfac) { 270 return 0; 271 } 272
if文が真になる場合はcpuが使われていないということで利用度0を返す。
273 while (estcpu != 0 && n > 1) { 274 estcpu = decay_cpu(loadfac, estcpu); 275 n--; 276 } 277 278 return estcpu; 279 } 280
decay_cpu()も昨日調べましたね。
decay_cpu()で計算したcpu利用度と引数で渡ってきたnの値を使ってwhile文の条件が偽になるまでcpu利用度を計算しつづけると。
そして、cpu利用度の計算が終わったらresetpriority()を呼び出してプライオリティの更新を実行です。
322 resetpriority(l); 323 }
resetpriority()も昨日調べたやつです。
と、ここまでがsched_setrunnable()で次はsched_nice()を見てみましょう。
339 void 340 sched_nice(struct proc *p, int n) 341 { 342 struct lwp *l; 343 344 KASSERT(mutex_owned(p->p_lock)); 345 346 p->p_nice = n;
まずはプロセスのnice値の変更。
347 LIST_FOREACH(l, &p->p_lwps, l_sibling) { 348 lwp_lock(l); 349 resetpriority(l); 350 lwp_unlock(l); 351 } 352 } 353
次にプロセスに所属しているlwp全てに対してプライオリティを変更します。プロセスのnice値を変更するわけだからそのプロセスが持つ全lwpが対象になりますね。
こう見ていると昨日調べたdecay_cpu()、resetpriority()がsched_4bsd.cの重要な関数なんだなーって思いますね。
(´-`).。oO(この辺の挙動を理解することが大事ですねぇ