我试图了解 XV6 中的 MLFQ 和 RR 是如何工作的。我见过的一个实现如下:
void rr_scheduler(void){
struct proc *p;
struct cpu *c = mycpu();
c->proc = 0;
intr_on();
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->context, &p->context);
// Process is done running for now.
// It should have changed its p->state before coming back.
c->proc = 0;
}
release(&p->lock);
}
void mlfq_scheduler(void){
struct proc *p;
struct cpu *c = mycpu();
c->proc = 0;
intr_on();
char high_avail = 0;
do
{
high_avail = 0;
for (p = proc; p < &proc[NPROC]; p++)
{
acquire(&p->lock);
if (p->priority > 0)
{
release(&p->lock);
continue;
}
if (p->state == RUNNABLE)
{
high_avail = 1;
// 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->context, &p->context);
// check if we are still the right scheduler
if (sched_pointer != &mlfq_scheduler)
{
release(&p->lock);
return;
}
// Process is done running for now.
// It should have changed its p->state before coming back.
c->proc = 0;
}
release(&p->lock);
}
} while (high_avail);
// RR on low prio - break when high prio found
for (p = proc; p < &proc[NPROC]; p++)
{
acquire(&p->lock);
if (p->priority == 0 && p->state == RUNNABLE)
{
// found high prio - switch to high prio task
release(&p->lock);
break;
}
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->context, &p->context);
// check if we are still the right scheduler
if (sched_pointer != &mlfq_scheduler)
{
release(&p->lock);
return;
}
// Process is done running for now.
// It should have changed its p->state before coming back.
c->proc = 0;
}
release(&p->lock);
}
}
我对 C 不太熟悉,但确实理解提供的代码。但是我不明白如何使用 MLFQ 更改优先级以及进程如何运行指定的时间直到 RR 中的切换。如果我认为这是在 trap.c 文件中实现的中断,那么我是否完全关闭了?在这种情况下,任何人都可以回答这是如何在 trap.c 文件中实现的吗?
感谢您的提前答复。
如果 MLFQ 正确实现,一些逻辑应该处理陷阱并更新进程的优先级。这可能位于
usertrap
中的 trap.c
内部,或者位于 yield
中的 proc.c
函数内部。前一个函数应该调用后者,并将进程产生的原因作为参数,这可以用于编辑优先级,例如,如果时间片已用完。