1

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

Mehdi Dehghani
  • 10,970
  • 6
  • 59
  • 64
mgh
  • 377
  • 2
  • 4
  • 14

2 Answers2

2

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
Mathieu
  • 8,840
  • 7
  • 32
  • 45
1

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)

Mathieu
  • 8,840
  • 7
  • 32
  • 45
  • And can I change this time-slices at run-time (with a system call for instance)? @Mathieu – mgh Dec 13 '19 at 01:29
  • 1
    @mahdi: the `10 000 000` is a dimension less number, the time will depend on bus frequency. For instance, if your bus is at 1Mhz, its period will be at 1us (1micro second), so your time slice will be at `1us*10 000 000 = 10 000 000 us = 10 seconds` – Mathieu Dec 13 '19 at 08:04
  • @mahdi Well lapic's register `TICR` controls the time slice duration, you can image to create a system call to modify it dynamically, but I'm not sure that it's supported... – Mathieu Dec 13 '19 at 08:12