• 沒有找到結果。

Linux Kernel Data Structure for Task and Scheduler

Chapter 2  Background

2.2 Linux Kernel Data Structure for Task and Scheduler

NCTUns 是一套橫跨 user-level 和 kernel-level 的網路模擬器,且事件層平行模擬 方法在 NCTUns 的應用上也與核心中的行程描述器及排程器有很大的關聯,因 此必需先介紹行程描述器與排程器在核心中扮演什麼樣的角色,這對之後的章節 會有莫大的幫助。

2.2.1 Task Data Structure in the Linux Kernel

行程代表一個正在執行程式的實體。當一個行程被創造出來,大部份都與創造它 的父行程具有相同的屬性。邏輯上,它從原有的父行程中複制一份相同的 addressing space,並與父行程執行相同部份的程式。雖然它們是共享相同的程式 頁面,不過在資料 (stack and heap)方面,它們彼此各自擁有一塊獨立空間。所以 子行程對於程式中資料的修改,從父行程的角度來看並不會有任何的改變。

核心為了管理各個行程,使用行程描述器 (task structure)紀錄一個行程的所 有資訊,包含行程優先權,行程使用哪一顆 CPU 上的資源或是被哪些事件給暫 停,分配給此行程的記憶體位置等 …,詳細欄位如 Figure 2.2 所示。

行程根據其本身的狀態,會被作業系統將其置入到不同的佇列中。所有處於 TASK_RUNNING 狀態的行程都群聚在「執行佇列」 (run_queue)串列中。不同

狀態會有不同的處理方式。處於 TASK_STOPPED、EXIT_ZOMBIE 或

EXIT_DEAD 狀態的行程,不必連結在特定串列中。處於 TASK_INTERRUPTIBLE 或 TASK_UNINTERRUPTIABLE 狀態的行程,則被串在「等待佇列」

(wait_queu)。

等待佇列有好幾種用途,特別是中斷事件的處理、行程同步以及計時。等待 佇列代表的是一組休眠中的行程,當某個條件為真時,就會被核心喚醒。由於事 件層平行模擬是在多顆核心中運行,為了達到各個核心的同步,修改 NCTUns 核心程式時,會在部份的程式碼中加入等待佇列的機制,這將在之後的章節會做 更詳細的介紹。

2.2.2 Scheduler Design in the Linux Kernel

只對狀態處在 TASK_RUNNING 的行程感興趣,因此,其它不為

TASK_RUNNING 狀態的行程都無法獲得 CPU 時間。隨著優先權的不同,行程 在核心中被劃分為兩類,優先權 0~100 屬於普通行程,而 101~139 是即時行程。

2.2.3 Spin Locks

多核心的系統裡最為廣泛使用的同步機制就是上鎖 (locking)。不同的 CPU 可能 同時在核心中存取一個共用資料結構或進入一個關鍵區 (critical section),為了保 護共同存取的資料,想要更改或是讀取共同資料的 CPU 就必須取得一個鎖。取 得鎖的 CPU 可以存取關鍵區的資料,其它未取得鎖的 CPU 將在門外不斷等待,

直到上一個取得鎖的 CPU 釋放鎖,等在門外的 CPU 才可以進入關鍵區內。

自旋鎖是 Linux 核心專門用在多處理器架構的同步機制。持有自旋鎖的行程 會先檢查它手中的鎖是否有其它 CPU 正在使用,如果是,行程會自旋,也就是 重覆執行一個指令迴圈,直到鎖被打開為止,相反的,如果並沒有任何 CPU 使 用,它就會取得進入關鍵區的資格,並將自旋鎖的狀態設成上鎖。

一般而言,被自旋鎖保護的資料結構或關鍵區中,核心先佔功能是關閉的。

就單處理器系統而言,自旋鎖並沒有什麼太大的用處,因為並不會有其它的 CPU 同時存取關鍵區的資料,但在使用事件層平行模擬方法的 NCTUns 網路模擬器 中,自旋鎖機制就是一個必要的存在。