'How to change the preemption rate in xv6?

I need to achieve the following:

Process preemption should be done in every time quantum (measured in clock ticks) instead of every clock tick

In order to achieve this, I have modified the yield() function in proc.c

void
yield(void)
{ 
  struct proc *p = myproc();

  acquire(&ptable.lock);  //DOC: yieldlock
  p->state = RUNNABLE;
  p->timeslice--;
  if(!p->timeslice)
    sched();
  release(&ptable.lock);
}

I have added the field int timeslice in struct proc. I timeslice is initialized in scheduler(), every time a process is scheduled

void
scheduler(void)
{
  struct proc *p;
  struct cpu *c = mycpu();
  c->proc = 0;
  
  for(;;){
    // Enable interrupts on this processor.
    sti();

    // Loop over process table looking for process to run.
    acquire(&ptable.lock);
    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
      if(p->state != RUNNABLE)
        continue;

      // 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->timeslice = QUANTA;

      swtch(&(c->scheduler), p->context);
      switchkvm();

      // Process is done running for now.
      // It should have changed its p->state before coming back.
      c->proc = 0;
    }
    release(&ptable.lock);

  }
}

But I am getting the following error in xv6 shell

xv6...
cpu1: starting 1
cpu0: starting 0
sb: size 1000 nblocks 941 ninodes 200 nlog 30 logstart 2 inodestart 32 bmap start 58
unexpected trap 14 from cpu 1 eip 801059d2 (cr2=0x3920)
lapicid 1: panic: trap
 80105cdf 801059c9 0 0 0 0 0 0 0 0

Please help me fix the error. Thanks in advance ...



Solution 1:[1]

You should not change the process state if you don't call sched().

void
yield(void)
{ 
    acquire(&ptable.lock); 
    struct proc *p = myproc();

    p->timeslice--;

    if(!p->timeslice ) {
        acquire(&ptable.lock); 
        p->state = RUNNABLE;
        sched();
    }
    release(&ptable.lock);
}

Note:

In code above, you might acquire and release the process table in the if body, but I'm not sure that it's save to change p->timeslice if process table is not locked.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mathieu