xv6进程切换-swtch函数

    xiaoxiao2021-03-25  74

    进程切换中由于需要保存当前进程的寄存器状态信息,又要将新进程记录的寄存器状态信息加载到寄存器,因此涉及到许多栈的操作,堆栈间的来回切换,容易让人眼花缭乱,难以理解。本文试图分析以下xv6中的进程切换过程。

    当前进程通过调用yield函数,进行进程切换。yield函数调用sched函数,sched函数启动swtch函数完成进程切换。整个流程是这样的:

    yield->sched->swtch

    在sched函数中,可以看到,当前进程总是先切换到当前cpu的scheduler切换器:

    //void sched(void) swtch(&proc->context, cpu->scheduler);

    切换器是一个死循环,该循环不断在进程表中扫描,选择一个RUNNABLE的进程调度,即从scheduler切换器转换到新选择的进程:

    //scheduler切换器 void scheduler(void) { struct proc *p; for(;;){ // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->state != RUNNABLE) continue; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; } release(&ptable.lock); } }

    显然,swtch函数是重点。swtch函数的原型是:

    void swtch(struct context **old, struct context *new);

    它的工作主要包括:1. 保存当前(old)进程的上下文。 2. 加载新进程(new)的上下文到机器寄存器中。

    contex中其实就是几个寄存器变量,用来保存这些寄存器的值。

    swtch的函数代码如下:

    # Context switch # # void swtch(struct context **old, struct context *new); # # Save current register context in old # and then load register context from new. .globl swtch swtch: movl 4(%esp),
    转载请注明原文地址: https://ju.6miu.com/read-32787.html

    最新回复(0)