如何在 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_slice
和 current_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
现在看来,在每次点击时,运行 进程都会被抢占并被迫让出处理器,我已经彻底调查了代码库和代码中唯一相关的部分来处理抢占低于(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_slice
和 current_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