mgh
mgh

Reputation: 407

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

Right now it seems that on every click tick, the running process is preempted and forced to yield the processor, I have thoroughly investigated the code-base and the only relevant part of the code to process preemption is below (in 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();

I guess that timing is specified in T_IRQ0 + IRQ_TIMER, but I can't figure out how these two can be modified, these two are specified in trap.h:

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

#define IRQ_TIMER        0

I wonder how I can change the default RR scheduling time-slice (which is right now 1 clock tick, fir example make it 10 clock-tick)?

Upvotes: 1

Views: 2900

Answers (2)

Mathieu
Mathieu

Reputation: 9629

If you want a process to be executed more time than the others, you can allow it more timeslices, without changing the timeslice duration.

To do so, you can add some extra_slice and current_slice in struct proc and modify the TIMER trap handler this way:

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();
  }

Then you just have to create a syscall to set extra_slice and modify the scheduler function to reset current_slice to extra_slice at process wakeup:

// 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

Upvotes: 3

Mathieu
Mathieu

Reputation: 9629

You can read lapic.c file:

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);

So, if you want the timer interrupt to be more spaced, change the TICR value:

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

can become

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

Warning, TICR references a 32bits unsigned counter, do not go over 4 294 967 295 (0xFFFFFFFF)

Upvotes: 1

Related Questions