日期:2014-05-16 浏览次数:20773 次
Linux内核进程切换
本文主要参考了Understanding The LinuxKernel 和水木精华区的分析进程切换宏 switch_to 。感谢相关的作者!本文中有部分内容直接从上面提到的文章中重复,仅仅是为了方便大家阅读。本文中提到的所有内核代码可以到LinuxCross
Reference上查阅。欢迎转载本文,转载请保留这份声明。
本文仅讨论内核进程的切换,而不涉及进程的调度算法。详细讲了switch_to这个宏。
文中涉及到的Linux内核源码,如没有特别指出,均指2.6.26版本的源码。
首先简单提一下这个宏和函数的被调用关系:
schedule() --> context_switch() --> switch_to --> __switch_to()
这里面,schedule是主调度函数,涉及到一些调度算法,这里不讨论。当schedule()需要暂停A进程的执行而继续B进程的执行时,就发生了进程之间的切换。进程切换主要有两部分:1、切换全局页表项;2、切换内核堆栈和硬件上下文。这个切换工作由context_switch()完成。其中switch_to和__switch_to()主要完成第二部分。更详细的,__switch_to()主要完成硬件上下文切换,switch_to主要完成内核堆栈切换。
阅读switch_to时请注意:这是一个宏,不是函数,它的参数prev, next, last不是值拷贝,而是它的调用者context_switch()的局部变量。局部变量是通过%ebp寄存器来索引的,也就是通过n(%ebp),n是编译时决定的,在不同的进程的同一段代码中,同一局部变量的n是相同的。有关局部变量如何索引的问题,可以参考这里和这里。在switch_to中,发生了堆栈的切换,即ebp发生了改变,所以要