這一節可以很長,也可以很短.要寫長是因為這里有不少細節可以寫,要寫短是因為如果不關注細節,而只關注基本的原理,那么幾句話就可以說完了.
坦白的說,細節部分我還沒有完全吃透,即使是<<深入理解Linux內核>>一書,講到這部分也費了不少篇幅.因為我在第一遍閱讀時閱讀速度要盡可能的加快,一些不太明白的細節暫且放過去,等精讀第一遍完畢了再繼續深入,所以我選擇了長話短說.
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的數據保持不變.
在switch_to宏返回之前,將eax寄存器的數據存放到last中,因此,last=eax=C.
此時,也就是進程A被切換回來之后,prev=A,next=B,last=C
從上面的分析可以看出,實際上,prev指向的是進程切換之前被切換走的進程指針,而last指向的是切換之后從哪個進程切換過來的.
兩者的意義并不一樣,只不過是在切換之后原先的prev無用了,可以用于保存切換之后是從哪個進程切換過來的,所以才會出現調用switch_to宏時prev和last相同的情況.