From: Ben Gras Date: Wed, 21 Mar 2007 09:45:01 +0000 (+0000) Subject: after enqueue()ing a process, only pick_proc() a new one if the current X-Git-Tag: v3.1.3~39 X-Git-Url: http://zhaoyanbai.com/repos/Bv9ARM.ch06.html?a=commitdiff_plain;h=bd2ddd5fd42cb31de4bb1beb0b8310600227a33c;p=minix.git 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.) --- 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); } /*===========================================================================*