NetBSD系列介紹--調(diào)度器
調(diào)度器的介紹不是很好寫,如果簡(jiǎn)單介紹,那就只有兩個(gè)文件:src/sys/kern/sched_4bsd.c 和 src/sys/kern/sched_m2.c,默認(rèn)調(diào)度算法還是從4.4BSD就一直沿用的調(diào)度算法,即前一個(gè)文件中實(shí)現(xiàn)的,代碼中有關(guān)于調(diào)度算法的詳細(xì)注釋,直接看代碼就可以了。你實(shí)現(xiàn)了這兩個(gè)文件中共有的函數(shù),就算實(shí)現(xiàn)了一個(gè)調(diào)度器了,內(nèi)核的其他部分會(huì)在適當(dāng)?shù)奈恢谜{(diào)用這些函數(shù)。問題是NetBSD 5.0 對(duì)調(diào)度器的接口進(jìn)行了重新設(shè)計(jì),現(xiàn)在有了實(shí)時(shí)調(diào)度擴(kuò)展,并且線程是可搶占的了,i386和amd64平臺(tái)已經(jīng)支持搶占。要把這些說清楚就有點(diǎn)麻煩了,因?yàn)槲易约阂策沒整明白,呵呵。
先說個(gè)大概吧。
關(guān)于調(diào)度器的接口,可以看src/sys/sys/sched.h中聲明的函數(shù),這些函數(shù)中有幾個(gè)是src/sys/kern/kern_synch.c和src/sys/kern/sys_sched.c中實(shí)現(xiàn)的,這幾個(gè)函數(shù)不是調(diào)度器接口,調(diào)度器接口是在前面這個(gè)頭文件中聲明,并在sched_4bsd.c和sched_m2.c中實(shí)現(xiàn)了的函數(shù)。調(diào)度器的主要任務(wù)是計(jì)算出下一個(gè)希望運(yùn)行的是哪個(gè)線程,并告訴系統(tǒng)需不需要進(jìn)行線程切換,如果需要,下一個(gè)是哪一個(gè)。調(diào)度器的功能還是很簡(jiǎn)單的,關(guān)鍵是調(diào)度的過程很復(fù)雜,我沒怎么弄明白,主要是對(duì)x86的smp的工作原理不是很熟悉。
我的理解是這樣,時(shí)鐘中斷進(jìn)來,調(diào)用hardclock(),在hardclock()中有兩個(gè)變量我還沒弄明白是干什么的,分別是stathz和schedhz。這是hardclock()中相關(guān)的代碼:
/*
* If no separate statistics clock is available, run it from here.
*/
if (stathz == 0)
statclock(frame);
/*
* If no separate schedclock is provided, call it here
* at about 16 Hz.
*/
if (schedhz == 0) {
if ((int)(--ci->ci_schedstate.spc_schedticks) ci_schedstate.spc_schedticks = hardscheddiv;
}
}
if ((--ci->ci_schedstate.spc_ticks) <= 0)
sched_tick(ci);
schedclock()和sched_tick()最終會(huì)走到調(diào)度器中去,然后計(jì)算下一個(gè)線程是誰(shuí),如果是同一cpu,則觸發(fā)一個(gè)軟中斷,如果不是,就觸發(fā)一個(gè)cpu間中斷,在處理這個(gè)中斷的時(shí)候切換線程上下文,中斷返回的時(shí)候判斷是否要切換進(jìn)程上下文。
to be continued