The first branch in the loop's body has a continue
statement, but I'm not exactly sure why. I'm under the impression that a continue
statement here is unnecessary, and that having an if-statement like if(p->state == RUNNABLE)
with the rest of the loop's body inside the if-statement's body would be better (i.e. it would make control-flow more explicit).
I'm thinking it could be to avoid nesting for readability's sake. Or am I missing out on something here?
// 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;
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++) {
// What's the purpose of this?
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);
}
}