Currently, a new runnable thread cannot preempt the thread on any
processor other than the thread that called mi_switch().  For
instance, we do something like the following in _mtx_unlock_sleep():

--- v --- _mtx_unlock_sleep() --- v ---
setrunqueue(th_waken_up);
if (curthread->preemptable && th_waken_up->priority < curthread->priority) {
        setrunqueue(curthread);
        mi_switch();
}
--- ^ --- _mtx_unlock_sleep() --- ^ ---

If the priority of curthread is higher than th_waken_up, we cannot run
it immediately even if there is another processor running a thread
with a priority lower than th_waken_up.  th_waken_up should preempt
that processor, or we would end up with a priority inversion.

Maybe we have to dispatch a runnable thread to the processor running
a thread with the lowest priority.  Solaris seems to take the
following steps to do that:

1. If a new thread has slept for longer than 3/100 seconds (this
   should be tunable), linearly search the processor running a thread
   with the lowest priority.  Otherwise, choose the processor that ran
   the new thread most recently.

2. Make an inter-processor interrupt to the processor chosen in 1.

3. The chosen processor puts its current thread back to the dispatch
   queue and performs a context switch to run the new thread.

Above is only a rough sketch.  We have to watch out for a race of
inter-processor interrupts and a processor entering a critical section.

If no one is working on preemption across processors, I would like to
see if I can do that.

Thanks.

-- 
Seigo Tanimura <[EMAIL PROTECTED]> <[EMAIL PROTECTED]>

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to