switch_to:這是乙個巨集,有三個引數prev,next,last
首先明確的是:last和prev是同乙個,用last只是為了理解方便,完全可以用兩個引數prev,next。因為last就是prev
switch_to巨集用於程序切換,給定了前乙個程序結構體指標prev,以及需要切換到的程序結構體指標next,從prev切換到next.
但是,實際上,switch_to巨集有三個引數,除了上面說的兩個引數之外,還有乙個last引數.而且使用switch_to巨集的時候傳入的prev和last都是同乙個值,比如會這麼呼叫這個巨集:
switch_to(prev,next,prev).
這是為什麼呢?
考慮一種場景,程序a切換到程序b,因為每個程序的空間是不同的,所以在切換之前,程序a的空間裡prev=a,next=b,last=a.
一段時間之後,需要切換回到程序a,假設當前程序是c,那麼對於c而言prev=c,next=a,last=c.
對比前後兩種場景:
程序a切換前:prev=a,next=b,last=a
程序c切換前:prev=c,next=a,last=c
這時開始從程序c切換到程序a,注意到在切換之前switch_to巨集將prev存放到了eax暫存器中,也就是在程序c切換到程序a之前,eax=c
切換之後,很顯然,來到了程序a的空間,因此prev,next,last指標要回到程序a被切換出去之前的指向,因此prev=a,next=b,last=a,而eax的資料保持不變(這是在eax的內容覆蓋a程序的堆疊的prev之前的情況)
在switch_to巨集返回之前,將eax暫存器的資料存放到last中,因此,last=eax=c,其實也就是prev=c
注意,在巨集裡面,出現last的地方實質上就是prev。
當從c轉回a的時候,a怎麼知道它的上乙個程序是哪乙個呢?
為了使你好理解,現在做如下假設:
加入沒有last這個引數,那麼switch變成:switch_to(prev, next);
這時候返回a程序後,prev指向它自己,next指向b,那麼如何知道a的上乙個程序是誰呢?就是不能夠獲取c的描述符。
這時候我們加上last,switch_to(prev, next, prev);,最後乙個引數是乙個輸出引數,那麼當switch_to執行完畢後,prev就會變成程序c的描述符。
這是通過movl %eax, last來實現的。
關鍵的一點來了,為什麼這個eax存的是c的描述符呢,這是由於在從c->a中的時候,movl prev, %eax,這個prev就是c。
我個人認為這樣做是為了便於理解,不然的話,switch_to(prev, next);也可以實現上述功能,直接把prev這個引數即當輸入引數,又當輸出引數就可以了。
linux核心測試 Linux核心測試的生命週期
linux核心測試 在針對linux核心的持續整合測試中 我寫了關於 持續核心整合 cki 專案及其更改核心開發人員和維護人員工作方式的使命。本文深入 了該項目的更多技術方面以及所有部分如何組合在一起。核心中每一項令人興奮的功能,改進和錯誤都始於開發人員提出的更改。這些更改將出現在不同核心儲存庫的大...
Linux核心 了解Linux核心搶占
目錄 無強制搶占 可搶占核心 自願核心搶占 完全實時搶占 在配置linux核心時,我們可以設定一些影響系統行為的引數。您可以使用不同的優先順序,排程類和搶占模型。了解並選擇正確的引數非常重要。在這篇文章中,我將介紹不同的搶占模型,以及每種模型如何影響使用者和核心行為 如果配置核心 使用make me...
Linux 核心 vs Windows 核心
windows 和 linux 可以說是我們比較常見的兩款作業系統的。windows 基本占領了電腦時代的市場,商業上取得了很大成功,但是它並不開源,所以要想接觸原始碼得加入 windows 的開發團隊中。這兩個作業系統各有千秋,不分伯仲。作業系統核心的東西就是核心,這次我們就來看看,linux 核...