1, each process through the clock interrupt departure trap.c in the
if (proc && proc->state = = RUNNING && tf->trapno = t_irq0+irq_timer)
Yield (); To force the process to be runnable state, the yield is implemented as follows:
Acquire (&ptable.lock); Doc:yieldlock
Proc->state = RUNNABLE;
Sched ();
Release (&ptable.lock);
In the Sched
Swtch (&proc->context, Cpu->scheduler); The kernel stack from the current process is implemented to switch to the scheduler stack, which is specifically responsible for program scheduling in the CPU.
(GDB) p/x *cpus[0]->scheduler
$7 = {edi = 0x0, esi = 0x80104ea4, ebx = 0x8, EBP = 0x8010c608,
EIP = 0x80104ab2}
At this point, we set breakpoints in Sched
(GDB) B proc.c:314
(GDB) s enters assembly code
In the assembly code of Swtch, we use the current process's ESP to point to the memory address +8 as the new context of ESP, and then save the old register value, POPL load the value of the new register
Swtch:
Movl
Xv6 design Trick (constantly updated)