arrays 二元數組是兩類就緒隊列的容器,active 和 expired 分別指向其中一個。active 中的進程一旦用完了自己的時間片,就被轉移到 expired 中,並設定好新的初始時間片;而當 active 為空白時,則表示當前所有進程的時間片都消耗完了,此時,active 和 expired 進行一次對調,重新開始下一輪的時間片遞減過程(參見"調度器")。
回憶一下 2.4 調度系統,進程時間片的計算是比較耗時的,在早期核心版本中,一旦時間片耗盡,就在時鐘中斷中重新計算時間片,後來為了提高效率,減小時鐘中斷的處理時間,2.4 調度系統在所有就緒進程的時間片都耗完以後在調度器中一次性重算。這又是一個 O(n) 量級的過程。為了保證 O(1) 的調度器執行時間,2.6 的時間片計算在各個進程耗盡時間片時單獨進行,而通過以上所述簡單的對調來完成時間片的輪轉(參見"調度器")。這又是 2.6 調度系統的一個亮點。
2) spinlock_t lock
runqueue 的自旋鎖,當需要對 runqueue 進行操作時,仍然應該鎖定,但這個鎖定操作隻影響一個 CPU 上的就緒隊列,因此,競爭發生的機率要小多了。
3) task_t *curr
本 CPU 正在啟動並執行進程。
4) tast_t *idle
指向本 CPU 的 idle 進程,相當於 2.4 中 init_tasks[this_cpu()] 的作用。
5) int best_expired_prio
記錄 expired 就緒進程組中的最高優先順序(數值最小)。該變數在進程進入 expired 隊列的時候儲存(schedule_tick()),用途見 "expired_timestamp"的解釋)。
6) unsigned long expired_timestamp
當新一輪的時間片遞減開始後,這一變數記錄著最早發生的進程耗完時間片事件的時間(jiffies 的絕對值,在 schedule_tick() 中賦),它用來表徵 expired 中就緒進程的最長等待時間。它的使用體現在 EXPIRED_STARVING(rq) 宏上。
上面已經提到,每個 CPU 上維護了兩個就緒隊列,active 和 expired。一般情況下,時間片結束的進程應該從 active 隊列轉移到 expired 隊列中(schedule_tick()),但如果該進程是互動式進程,調度器就會讓其保持在 active 隊列上以提高它的響應速度。這種措施不應該讓其他就緒進程等待過長時間,也就是說,如果 expired 隊列中的進程已經等待了足夠長時間了,即使是互動式進程也應該轉移到 expired 隊列上來,排空 active。這個閥值就體現在EXPIRED_STARVING(rq) 上:在 expired_timestamp 和 STARVATION_LIMIT 都不等於 0 的前提下,如果以下兩個條件都滿足,則 EXPIRED_STARVING() 返回真:
(當前絕對時間 - expired_timestamp) >= (STARVATION_LIMIT * 隊列中所有就緒進程總數 + 1),也就是說 expired 隊列中至少有一個進程已經等待了足夠長的時間;
正在啟動並執行進程的靜態優先順序比 expired 隊列中最高優先順序要低(best_expired_prio,數值要大),此時當然應該儘快排空 active 切換到expired 上來。