Linux--CFS調度1(復習)
簡單說:就是允許每個進程運行一段時間,循環(huán)輪詢,選擇運行最少的作為下一個進程。
? ? ? ? ? ? ? 通過總的運行數計算出單個進程運行時間
? ? ? ? ? ? ? nice優(yōu)先級用于計算權重
一 時間記賬
每個進程只能在公平分配給他的處理器里時間運行。
時間在調度實體struct sched_entity中維護。
vruntime記錄程序運行時長和還有多少運行時間。(ns)
delta_exec:當前進程的執(zhí)行時間,參數傳遞給calc_delta_fair。
calc_delta_fair 再根據當前可運行進程總數對運行時間進行加權計算,將最終權重值與當前進程的vruntimes相加。curr->vruntime += calc_delta_fair(delta_exec, curr);。
update_curr由系統(tǒng)定時器周期性調用,不管進程在可運行還是阻塞狀態(tài),vruntime可以準確地計算出給定進程的運行時間,而且制定誰應該是下一個被運行進程。
二 調度器入口
schedule() 選擇哪個進程可以運行,何時將其投入運行。
調用pick_next_task,會以優(yōu)先級排序,從高到低,依次檢查每個調度類,并從最高優(yōu)先級調度類中,選擇最高優(yōu)先級的進程。
上下文切換本身通過調用兩個特定于處理器的函數完成
1> switch_mm 更換通過task_struct->mm描述的內存管理上下文
2> switch_to切換處理器寄存器內容和內核棧,通常使用匯編編寫
switch_to(prev, next, prev);//之后的代碼只有在當前進程的下一次被選擇運行時才會執(zhí)行
barrier();//前后語句執(zhí)行順序不會因為任何可能的優(yōu)化而改變
return finish_task_switch(prev);//完成清理工作,才能夠正確釋放鎖.
三 進程選擇

進程不在就緒態(tài)就用_dequeue_entity將其從樹種刪除。
選擇vruntime最小也就是紅黑樹中最左側葉子節(jié)點,
實現函數pick_next_entity->__pick_next_entity。
睡眠:進程會標記為休眠狀態(tài),從可執(zhí)行紅黑樹中移除,放入等待隊列,然后調用schedule選擇執(zhí)行下一個進程。
喚醒:進程被設置為可執(zhí)行狀態(tài),從等待隊列中移到可執(zhí)行紅黑樹中。
check_preempt_wakeup->wakeup_preempt_entity