如何在 XV6 中修改进程抢占策略(如 RR 时间片)?

How to modify process preemption policies (like RR time-slices) in XV6?

现在看来,在每次点击时,运行 进程都会被抢占并被迫让出处理器,我已经彻底调查了代码库和代码中唯一相关的部分来处理抢占低于(trap.c):

// Force process to give up CPU on clock tick.
// If interrupts were on while locks held, would need to check nlock.

if(myproc() && myproc() -> state == RUNNING && tf -> trapno == T_IRQ0 + IRQ_TIMER)
    yield();

我猜是在T_IRQ0 + IRQ_TIMER中指定了时间,但是我想不通这两个怎么修改,这两个在trap.h[=21中指定了=]:

#define T_IRQ0          32      // IRQ 0 corresponds to int T_IRQ

#define IRQ_TIMER        0

我想知道如何更改默认的 RR 调度时间片(现在是 1 个时钟滴答,例如将其设为 10 个时钟滴答)?

您可以阅读 lapic.c 文件:

lapicinit(void) 
{
    ....
    // The timer repeatedly counts down at bus frequency
    // from lapic[TICR] and then issues an interrupt.
    // If xv6 cared more about precise timekeeping,
    // TICR would be calibrated using an external time source.
    lapicw(TDCR, X1);
    lapicw(TIMER, PERIODIC | (T_IRQ0 + IRQ_TIMER));
    lapicw(TICR, 10000000);

因此,如果您希望定时器中断间隔更大,请更改TICR值:

    lapicw(TICR, 10000000); //10 000 000

可以变成

    lapicw(TICR, 100000000); //100 000 000

警告,TICR 引用一个 32 位无符号计数器,不要超过 4 294 967 295 (0xFFFFFFFF)

如果您希望某个进程的执行时间比其他进程多,您可以允许它有更多的时间片,*无需更改时间片持续时间。

为此,您可以在 struct proc 中添加一些 extra_slicecurrent_slice 并以这种方式修改 TIMER 陷阱处理程序:

if(myproc() && myproc()->state == RUNNING &&
  tf->trapno == T_IRQ0+IRQ_TIMER)
  {
    int current = myproc()->current_slice;
    if ( current ) 
      myproc()->current_slice = current - 1;
    else 
      yield();
  }

然后你只需要创建一个系统调用来设置 extra_slice 并修改 scheduler 函数以在进程唤醒时将 current_slice 重置为 extra_slice:

// Switch to chosen process.  It is the process's job
// to release ptable.lock and then reacquire it
// before jumping back to us.
c->proc = p;
switchuvm(p);
p->state = RUNNING;
p->current_slice = p->extra_slice