如何解决我无法理解 xv6 中的这行代码
尽管查阅了文档,我仍然无法理解这一行:swtch(&c->scheduler,&p->context);
。
我的问题:我知道这一行是切换p->context,包括save registers和restore registers,但是我无法理解这个过程中的pc
变化,那就是这段代码的执行顺序? swtch(&c->scheduler,&p->context);
执行完后,是不是立即执行c->proc = 0;
,那么执行c->proc=p;
的效果就消失了?我现在很困惑。
代码链接:https://github.com/mit-pdos/xv6-riscv/blob/riscv/kernel/proc.c 第 456 行
*// Per-cpu process scheduler.*
*// Each cpu calls scheduler() after setting itself up.*
*// Scheduler never returns. It loops,doing:*
*// - choose a process to run.*
*// - swtch to start running that process.*
*// - eventually that process transfers control*
*// via swtch back to the scheduler.*
void
scheduler(void)
{
struct proc *p;
struct cpu *c = mycpu();
c->proc = 0;
for(;;){
*// Avoid deadlock by ensuring that devices can interrupt.*
intr_on();
int found = 0;
for(p = proc; p < &proc[NPROC]; p++) {
acquire(&p->lock);
if(p->state == RUNNABLE) {
*// Switch to chosen process. It is the process's job*
*// to release its lock and then reacquire it*
*// before jumping back to us.*
p->state = RUNNING;
c->proc = p;
swtch(&c->scheduler,&p->context);
*// Process is done running for Now.*
*// It should have changed its p->state before coming back.*
c->proc = 0;
found = 1;
}
release(&p->lock);
}
if(found == 0){
intr_on();
asm volatile("wfi");
}
}
}
解决方法
这确实是一段非常令人困惑的代码,以至于它的原作者在评论中写道“你不会理解这个”,所以不要因为不理解而感到难过。
您可能错过的关键是 p->context
包含一个地址,其中 swtch
用于恢复进程 p
的执行。例如,它被设置为 here:
// Set up new context to start executing at forkret,// which returns to user space.
memset(&p->context,sizeof(p->context));
p->context.ra = (uint64)forkret;
p->context.sp = p->kstack + PGSIZE;
因此,当调度程序调用 swtch 时,它实际上是对 p->context.ra
指向的任何内容进行间接函数调用。该代码将无限期地执行,然后最终(某种程度上)返回到 swtch,后者返回到调度程序,并以 c->proc = 0
继续。
(在上面的句子中,“sort of”和“effectively”这两个词做了很多工作。要了解这些词背后隐藏着什么,接下来您应该阅读coroutines。)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。