我无法理解 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。)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...