FreeBSD/sys/kern/sched_4bsd.c
/*
 * This function is called when a thread is about to be put on run queue
 * because it has been made runnable or its priority has been adjusted.  It
 * determines if the new thread should be immediately preempted to.  If so,
 * it switches to it and eventually returns true.  If not, it returns false
 * so that the caller may place the thread on an appropriate run queue.
 */
This function is called when a thread is about to be put on run queue
because it has been made runnable or its priority has been adjusted.  It
determines if the new thread should be immediately preempted to.  If so,
it switches to it and eventually returns true.  If not, it returns false
so that the caller may place the thread on an appropriate run queue.
This function is called when a thread is about to be put on run queue because it has been made runnable or its priority has been adjusted . It determines if the new thread should be immediately preempted to . If so it switches to it and eventually returns true . If not it returns false so that the caller may place the thread on an appropriate run queue .
int
maybe_preempt(struct thread *td)
{
#ifdef PREEMPTION
	struct thread *ctd;
	int cpri, pri;
	ctd = curthread;
	THREAD_LOCK_ASSERT(td, MA_OWNED);
	KASSERT((td->td_inhibitors == 0),
			("maybe_preempt: trying to run inhibited thread"));
	pri = td->td_priority;
	cpri = ctd->td_priority;
	if (panicstr != NULL || pri >= cpri || cold  ||
	    TD_IS_INHIBITED(ctd))
		return (0);
#ifndef FULL_PREEMPTION
	if (pri > PRI_MAX_ITHD && cpri < PRI_MIN_IDLE)
		return (0);
#endif
	if (ctd->td_critnest > 1) {
		CTR1(KTR_PROC, "maybe_preempt: in critical section %d",
		    ctd->td_critnest);
		ctd->td_owepreempt = 1;
		return (0);
	}
	MPASS(ctd->td_lock == td->td_lock);
	MPASS(TD_ON_RUNQ(td));
	TD_SET_RUNNING(td);
	CTR3(KTR_PROC, "preempting to thread %p (pid %d, %s)\n", td,
	    td->td_proc->p_pid, td->td_name);
	mi_switch(SW_INVOL | SW_PREEMPT | SWT_PREEMPT, td);
	spinlock_enter();
	thread_unlock(ctd);
	thread_lock(td);
	spinlock_exit();
	return (1);
#else
	return (0);
#endif
}
int maybe_preempt ( struct thread * td ) { #ifdef PREEMPTION struct thread * ctd ; int cpri , pri ; ctd = curthread ; THREAD_LOCK_ASSERT ( td , MA_OWNED ) ; KASSERT ( ( td -> td_inhibitors == 0 ) , ( " " ) ) ; pri = td -> td_priority ; cpri = ctd -> td_priority ; if ( panicstr != NULL || pri >= cpri || cold || TD_IS_INHIBITED ( ctd ) ) return ( 0 ) ; #ifndef FULL_PREEMPTION if ( pri > PRI_MAX_ITHD && cpri < PRI_MIN_IDLE ) return ( 0 ) ; #endif if ( ctd -> td_critnest > 1 ) { CTR1 ( KTR_PROC , " " , ctd -> td_critnest ) ; ctd -> td_owepreempt = 1 ; return ( 0 ) ; } MPASS ( ctd -> td_lock == td -> td_lock ) ; MPASS ( TD_ON_RUNQ ( td ) ) ; TD_SET_RUNNING ( td ) ; CTR3 ( KTR_PROC , " \n " , td , td -> td_proc -> p_pid , td -> td_name ) ; mi_switch ( SW_INVOL | SW_PREEMPT | SWT_PREEMPT , td ) ; spinlock_enter ( ) ; thread_unlock ( ctd ) ; thread_lock ( td ) ; spinlock_exit ( ) ; return ( 1 ) ; #else return ( 0 ) ; #endif }
This function is called when a thread is about to be put on run queue
 because it has been made runnable or its priority has been adjusted.
This function is called when a thread is about to be put on run queue because it has been made runnable or its priority has been adjusted .
/*
	 * The new thread should not preempt the current thread if any of the
	 * following conditions are true:
	 *
	 *  - The kernel is in the throes of crashing (panicstr).
	 *  - The current thread has a higher (numerically lower) or
	 *    equivalent priority.  Note that this prevents curthread from
	 *    trying to preempt to itself.
	 *  - It is too early in the boot for context switches (cold is set).
	 *  - The current thread has an inhibitor set or is in the process of
	 *    exiting.  In this case, the current thread is about to switch
	 *    out anyways, so there's no point in preempting.  If we did,
	 *    the current thread would not be properly resumed as well, so
	 *    just avoid that whole landmine.
	 *  - If the new thread's priority is not a realtime priority and
	 *    the current thread's priority is not an idle priority and
	 *    FULL_PREEMPTION is disabled.
	 *
	 * If all of these conditions are false, but the current thread is in
	 * a nested critical section, then we have to defer the preemption
	 * until we exit the critical section.  Otherwise, switch immediately
	 * to the new thread.
	 */ /* || dumping */ /*
	 * Thread is runnable but not yet put on system run queue.
	 */ /*
	 * td's lock pointer may have changed.  We have to return with it
	 * locked.
	 */