Linux調度主要是在一個runqueue結構體上操作。runqueue結構體有一個prio_array結構體數組,該數組中有個兩個prio_array結構體。prio_array結構體的定義如下:
struct prio_array
{
int nr_active /* number of tasks in the queue */;
unsigned long bitmap[BITMAP_SIZE]; /* priority bitmap */
struct list_head queue[MAX_PRIO]; /* priority queue */
}
這兩個prio_array,一個掛著expired task(時間片已經用完的task),另一個掛著active task(時間片尚未用完的task)。當active task為空時,就交換這兩個prio_array的指針值就OK了。
接下來講解prio_array中的成員
nr_active:就不用多說了,就表示該prio_array結構體上掛著多少個任務。
struct list_head queue[MAX_PRIO]:這是一個指針數組,每個數組標記一個鏈表頭,每個鏈表頭上掛著一串相同優先級的task。
unsigned long bitmap[BITMAP_SIZE]:這個成員的每一個表示對應的優先級的task鏈表上是否為空。
有了上面的基礎,接下來就講解如何實現O(1)調度,當要調度程序時,
1)首先找到bitmap成員上第一個為 1 的bit位置,比如說bitmap的第8位為1,則表示前面0~7高優先級的task鏈表上沒有task。
2)然後訪問struct list_head queue[MAX_PRIO]數組的第八個成員,該成員是優先級為8的task鏈表的表頭,
3)最後通過表頭取下第一個task,再將其調度上CPU,這樣就實現了O(1)調度。