From bd2ddd5fd42cb31de4bb1beb0b8310600227a33c Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Wed, 21 Mar 2007 09:45:01 +0000 Subject: [PATCH] after enqueue()ing a process, only pick_proc() a new one if the current process is not PREEMPTIBLE (or it's not ready, or there isn't a current process yet). This fixes a case where a process that isn't PREEMPTIBLE actually gets preempted. (This solves a race condition between CLOCK and SYSTEM.) --- kernel/proc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/kernel/proc.c b/kernel/proc.c index dede6f9e4..31de06de7 100755 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -523,8 +523,14 @@ register struct proc *rp; /* this process is now runnable */ rp->p_nextready = NIL_PROC; /* mark new end */ } - /* Now select the next process to run. */ - pick_proc(); + /* Now select the next process to run, if there isn't a current + * process yet or current process isn't ready any more, or + * it's PREEMPTIBLE. + */ + if(!proc_ptr || proc_ptr->p_rts_flags || + (priv(proc_ptr)->s_flags & PREEMPTIBLE)) { + pick_proc(); + } #if DEBUG_SCHED_CHECK rp->p_ready = 1; @@ -554,8 +560,7 @@ register struct proc *rp; /* this process is no longer runnable */ #if DEBUG_SCHED_CHECK check_runqueues("dequeue1"); - if (! rp->p_ready) kprintf("%s:%d: dequeue() already unready process\n", - f_str, f_line); + if (! rp->p_ready) kprintf("dequeue() already unready process\n"); #endif /* Now make sure that the process is not in its ready queue. Remove the @@ -639,6 +644,7 @@ PRIVATE void pick_proc() return; } } + panic("no ready process", NO_NUM); } /*===========================================================================*