XV6中swtch.s调用后的返回位置及进程锁释放位置咨询
XV6 sched()与swtch相关问题解答
1. swtch汇编函数返回至何处?
swtch是XV6上下文切换的核心汇编函数,其返回位置由目标上下文的寄存器值决定:
- 调用swtch时,
a0指向当前进程的context结构体,a1指向目标进程(或调度器)的context结构体。 - 函数先将当前CPU的寄存器(包括
ra——即当前调用swtch的返回地址)保存到a0指向的结构中;随后从a1指向的结构加载目标上下文的寄存器值,其中ra会被替换为目标上下文里预先保存的返回地址。 - 最后执行
ret指令,会直接跳转到目标上下文结构体中保存的ra寄存器对应的地址:- 如果是切换回之前被挂起的进程,返回地址是该进程上次调用swtch时,swtch指令的下一行代码(比如调用
sched()的yield()函数中,sched()之后的位置); - 如果是首次切换到新创建的进程,返回地址通常是
forkret函数的入口(进程初始化时会将context的ra设置为forkret)。
- 如果是切换回之前被挂起的进程,返回地址是该进程上次调用swtch时,swtch指令的下一行代码(比如调用
针对sched()中调用swtch的场景:当当前进程被切换出去后再次被调度回来时,swtch的ret会回到sched()函数中调用swtch的下一行代码(即mycpu()->intena = intena;这一行)。
2. 进入sched()后,进程的锁在何处释放?
在XV6标准实现中,sched()内部不会直接释放进程锁,锁的释放逻辑位于调用sched()的上层函数中(以yield()为例):
yield()会先调用acquire(&p->lock)获取进程锁,将进程状态设为RUNNABLE后调用sched();- 当
sched()通过swtch完成上下文切换,当前进程再次被调度回来时,sched()执行完毕并返回yield(),随后yield()调用release(&p->lock)完成进程锁的释放。
简言之:进程锁是在sched()返回之后,由调用sched()的上层函数完成释放操作。
内容的提问来源于stack exchange,提问作者user23315277
相关产品推荐
相关产品推荐

