• 沒有找到結果。

第四章 驅動程式層網路事件通知機制之實作

4.5 系統呼叫的重新執行

章節 4.4.2 中我們曾經提及,當發現當目前行程為 TASK_INTERRUPTIBLE 狀態時,

若發現有該行程感興趣的事件已發生,則將其狀態設定為 TASK_RUNNING,如此一來,

若是目前行程尚有多餘的時間切片的話,便可以繼續執行,以便對該發生的事件進行處 理。

初看之下,以上這段處理似乎十分自然,但是,我們知道,行程會由 TASK_RUNNING 狀態轉移到 TASK_INTERRUPITBLE 狀態,必然是因為該行程的要求無法即時的被完 成,而使用者空間的行程要向核心做出要求的話,必須通過系統呼叫的方式,因此,當 我們將行程的 TASK_INTERRUPTIBLE 狀態改變為 TASK_RUNNING 時,其實之前行 程向核心,也就是作業系統,經由系統呼叫所做的要求並未被完成 (例如,寫入檔案,

要求更多的記憶體...),而行程的狀態卻被換成 TASK_RUNNING 了。

現在,讓我們來看一下如果我們只將現在行程的狀態由 TASK_INTERRUPTIBLE 換成 TASK_RUNNING 的話會發生什麼樣的狀況?

當使用者空間的行程執行了一個系統呼叫後,IP 暫存器將會指向該系統呼叫的下 一個指令 (此在核心空間時將被儲存在核心堆疊內),接下來,系統便進入核心空間執行 以便完成系統的要求,當使用者的要求無法被馬上滿足時,核心程式會執行如以下的程 式碼,將該行程加入一個等待佇列當中,並且呼叫排程器排程:

Fig.4- 10 將行程加入某個等待佇列的程式碼片段

當我們將行程的狀態由 TASK_INTERRUPTIBLE 換成 TASK_RUNNING 時,該程

式碼會由 schedule()的下一行開始執行,此時,程式進入 while 迴圈的判斷,若是等待的 狀況(在圖 Fig.4-10 中以 condition 變數作為代表)沒有成立,換句話說,也就是行程的要 求無法被立即滿足時,程式將會重新進入 while 迴圈當中執行,又將行程的狀態設定為 TASK_INTERRUPTIBLE,然後又呼叫 schedule(),形成類似無窮迴圈。

瞭解了只改動行程的狀態會發生什麼事情後,我們來說明要如何避免前段所述的情 況發生;根據 Linux 系統在傳統訊號的處理上,當系統呼叫無法完成,且有訊號傳達時,

圖 Fig.4-10 中的 signal_pending()的回傳值為一個非零值,此時,系統呼叫必須回傳 EINTR、ERESTARTNOHAND、ERESTARTSYS 或 ERESTARTINTR。

在傳統的信號機制當中,根據行程各種信號的不同動作(忽略、捕捉或預設動作),

在信號處理的核心函數內系統會做出對應的不同處理,表 Table.4-2 表示了行程對信號的 動作和系統呼叫回傳值的對應,以及核心信號處理函數會採取的動作[10]。

行程對信

號動作 系統呼叫回傳值

EINTR ERESTARTSYS ERESTARTNOHAND ERESTARTNOINTR

預設 終止 重新執行 重新執行 重新執行

忽略 終止 重新執行 重新執行 重新執行

捕捉 終止 不一定 終止 重新執行

Table.4- 2 行程對信號動作和系統呼叫回傳值對系統呼叫執行影響之列表

其中,表 Table.4-2 中所指的「不一定」表示要根據 SA_RESTART 這個旗標的設定 與否來判斷(使用者空間行程可以利用 sigaction 系統呼叫設定此旗標),若該旗標被設 定,系統呼叫將會被重新執行。

在本系統當中,根據系統呼叫的回傳值的處理大致上仍然依照表 Table.4-2 所示的規 則來進行,此外,當系統發現目前行程有設備信號尚未被處理時,。

我們根據行程是否註冊處理函數來討論,如果使用者空間的行程沒有註冊處理函 數,則當系統呼叫回傳 EINTR 時會終止,而系統呼叫回傳 ERESTARTSYS、

ERESTARTNOHAND、ERESTARTNOINTR 時會重複執行系統呼叫;當使用者空間行程 註冊了處理函數時,當系統呼叫回傳 EINTR 以及 ERESTARTNOHAND 時,系統呼叫將 被終止,而當系統呼叫回傳 ERESTARTSYS 以及 ERESTARTNOINTR 則會重新執行中

斷的系統呼叫。

首先,我們將 signal_pending()這個函數的判斷加入判斷設備信號是否尚未處理的判 斷,如下所示:

Fig.4- 11 signal_pending()函數之修改

在設備信號的處理函數 handle_iw_event_sig()當中,我們必須判斷是否欲處理的信 號,如果有未處理的信號,而且又有註冊處理函數時,則以如下的程式碼來處理:

Fig.4- 12 重新執行系統呼叫。

如果行程並未對發生的設備事件註冊處理函數時,則會在設備信號的處理函數 handle_iw_event_sig()中執行以下的程式碼,除了回傳值為 EINTR 之外的情況都需要重 複執行系統呼叫:

Fig.4- 13 沒有註冊處理函數時的系統呼叫重新執行 4.6 使用者和核心的切換

根據章節 4.4.1 中所介紹的系統返回程式碼,當核心發現欲返回的使用者空間行程 有感興趣的事件發生時,會呼叫 handle_iw_event_sig()函式以處理,在這個函式中將會 做所有切換到使用者空間行程的設定及動作。

本系統主要實作的平台為英特爾 32 位元平台 (Intel Architecture 32-bits,IA32) ,在 使用者和核心空間的切換方面,我們採用 Linux 對於傳統信號處理中執行信號處理函式 之方法,該方法可分為兩大步驟:

1. 將目前儲存在核心模式堆疊的使用者空間硬體環境儲存到使用者模式堆疊。

2. 置換目前核心模式堆疊中的使用者空間硬體環境。

圖 Fig.4-14 為一般狀況下行程由核心空間返回使用者空間前核心模式堆疊和使用者 模式堆疊的狀態,當行程由使用者空間跳至核心空間時,核心會先將使用者空間的硬體 環境儲存在核心堆疊中,其中的 IP 暫存器值存著下一個要執行指令的記憶體位址,SP 暫存器儲存著堆疊端的位置。

Fig.4- 14 正常狀態下的核心模式堆疊和使用者模式堆疊

我們的作法是先將一段系統之後欲執行的組語碼寫在使用者模式堆疊的頂端,再將 原本儲存於核心模式堆疊的硬體環境 (hardware context) 儲存在使用者模式堆疊中,最 後將回存位址 (return address) 寫入使用者模式堆疊的頂端,並且使用核心堆疊內的行 程所註冊的信息處理函數的硬體環境 (包含 IP 暫存器) 取代原來核心模式的硬體環境。

Fig.4- 15 執行回叫函式前的核心模式堆疊和使用者模式堆疊

Fig.4-15 為執行回叫函數前的核心模式堆疊和使用者模式堆疊的狀態,此時原本的 硬體環境已經被儲存到使用模式堆疊上,且核心模式堆疊上的硬體環境已經被置換為欲 執行回叫函數的硬體環境,其中相對應 IP 暫存器的記憶體位置儲存著回叫函數的記憶 體位置,而相對應 SP 暫存器的位址則儲存著目前使用者模式堆疊的頂端位址,經過這 樣設定使用者模式堆疊以及核心堆疊之後,核心的處理便返回 entry.S,根據圖 Fig.4-8 所示,程式將會跳至 restore_all 函式處理,將核心模式堆疊中的使用者硬體環境回復,

並且開始執行使用者的回叫函式。

當回叫程式執行完之後,會由使用者模式堆疊的頂端找尋要跳回的位址,由圖 Fig.4-15 中我們可以看出,堆疊頂端所存放的位址為指向堆疊中一個固定的位址 (原本 的 SP 暫存器值減 8) ,該位址存放著我們欲執行的程式碼 (化為二進位碼存在堆疊 上) ,因此當回叫函式執行完之後,便會執行堆疊中我們放入的程式碼,該段程式碼相 當於圖 Fig.4-16,也就是呼叫我們所新增的一個系統呼叫,iw_sigreturn()。

Fig.4- 16 置放於堆疊中的程式返回碼

iw_sigreturn()系統呼叫主要的任務是將之前存放入使用者模式堆疊中的硬體環境,

回復至圖 Fig.4-14 的狀態,系統呼叫之後若沒有感興趣的事件發生,會進入 entry.S 中執 行,進入系統呼叫後的判斷。

第五章 操作實例

5.1 操作實例

圖 Fig.5-1 為一個簡單的程式碼,用以驗證本論文所實作出來系統的可行性,該程 式碼的主體部分為一個無窮空迴圈,程式碼的起始部分使用本論文實作的系統呼叫介面 iwsignal()註冊事件處理函數,而處理函數中會將發生的事件印出在終端機上,在本例中 我們註冊了 devup()以及 devdown()作為介面啟用以及停用的處理函數。

Fig.5- 1 「驅動程式層網路事件通知機制」範例程式

而圖 Fig.5-2 為使用本機制所需要的定義檔,主要是定義了系統中網路事件的代碼 代碼以及我們所新增的系統呼叫介面 iwsignal()的相關宣告。

Fig.5- 2 「驅動程式層網路事件通知機制」的標頭檔 接下來則是程式執行的結果:

[步驟一]

‹ [執行動作]:開始執行程式。

‹ [程式動作]:執行實作函數 iwsiscall,註冊處理函數,如圖 Fig.5-3。

‹ [系統反應]:處理函數已註冊,如圖 Fig.5-4。

Fig.5- 3 範例程式開始執行

Fig.5- 4 範例程式註冊兩個處理函數

[步驟二]

‹ [執行動作]:啟用 wlan0 網路介面,如圖 Fig.5-5。

‹ [程式動作]:印出對應訊息,表示事件已經傳達,如圖 Fig.5-6。

Fig.5- 5 啟用網路介面 wlan0

Fig.5- 6 介面改變傳達至範例程式,印出啟用的介面 [步驟三]

‹ [執行動作]: 停用 wlan0 網路介面,如圖 Fig.5-7。

‹ [程式動作]:印出對應訊息,表示事件已傳達,如圖 Fig.5-8。

Fig.5- 7 停用網路介面 wlan0

Fig.5- 8 介面改變傳達至範例程式,印出停用的介面

[步驟四]

‹ [執行動作]:程式停止。

‹ [程式動作]:程式停止,如圖 Fig.5-9。

‹ [系統反應]:顯示註冊函數已經移除,如圖 Fig.5-10。

Fig.5- 9 按下 Control-C,程式停止執行

Fig.5- 10 範例程式註冊的處理函數被移除

第六章 結論與未來工作

面,使用該機制加入網路介面相關的處理,使得應用程式本身即具有網路介面的處理能 力也是一個選擇。

最後,本論文對於排程器的修改方面為優先執行有事件發生的行程,也就是說,有 事件發生的行程執行優先權為最大,當系統中有許多使用本機制的行程在執行,且網路 介面狀態頻繁的改變時,可能會阻礙到系統其他的行程的執行,比較好的方法應該是將

「行程有未處理的網路事件」這個條件加入系統執行優先權的計算因素之一,使得該種 行程的執行優先權較高,然後以一般的排程來處理,如此一來對於系統其他的行程影響 較少,但是隨之而來的負面影響就是網路事件的傳達會變得較慢。

參考文獻

[1] Linux Programmers Manual (Linux man pages), ioctl(2), 2000-09-21 [2] Linux Programmers Manual (Linux man pages), sigaction(2), 2001-12-29 [3] Linux Programmers Manual (Linux man pages), sigprocmask(2), 2001-12-29 [4] Linux Programmers Manual (Linux man pages ), select(2), 2001-02-09 [5] Linux Programmers Manual (Linux man pages), poll(2), 1997-12-07 [6] Portable Operating System Interface, http://www.knosof.co.uk/posix.html [7] phhttpd home page, http://www.zabbo.net/phhttpd

[8] Raimo Nikkilä, “Vertical Handover Study Cluster: VHO DAEMON”, Product Modelling and Realisation Group, Helsinki University of Technology, 2005-03-08 [9] Andrew Josey, editor, “Go solo2: The Authorized Guide to Version 2 of the Single

UNIX Specification”, Chapter 9 and Chapter 10, May 1997.

[10] Danial P.Bovert, Marco Cesati, “Understanding The Linux Kernel, 2nd edition”. Chapter 10, December 2002.

[11] Alessandro Rubini, Johathan Corbet, “Linux Device Driver, 2nd edition”, Chapter 1, June 2001.

[12] Klaus Whhrle, Frank Pählke, Hartmut Ritter, Daniel Muller, Marc Bechler, “The LINUX Networking Architecture – Design and Implementation of Network Protocols in the Linux Kernel”, Chapter 5, 2002.

[13] G. Carneiro, J. Ruela, M. Ricardo, "Cross-layer design in 4G Wireless Terminals". IEEE Wireless Communications, pp. 7-13, , April 2004.

[13] G. Carneiro, J. Ruela, M. Ricardo, "Cross-layer design in 4G Wireless Terminals". IEEE Wireless Communications, pp. 7-13, , April 2004.

相關文件