FreeBSD/sys/kern/sched_ule.c
/*
 * This tdq has idled.  Try to steal a thread from another cpu and switch
 * to it.
 */
This tdq has idled.  Try to steal a thread from another cpu and switch
to it.
This tdq has idled . Try to steal a thread from another cpu and switch to it .
static int
tdq_idled(struct tdq *tdq)
{
	struct cpu_group *cg;
	struct tdq *steal;
	cpuset_t mask;
	int thresh;
	int cpu;
	if (smp_started == 0 || steal_idle == 0)
		return (1);
	CPU_FILL(&mask);
	CPU_CLR(PCPU_GET(cpuid), &mask);
	spinlock_enter();
	for (cg = tdq->tdq_cg; cg != NULL; ) {
		if ((cg->cg_flags & CG_FLAG_THREAD) == 0)
			thresh = steal_thresh;
		else
			thresh = 1;
		cpu = sched_highest(cg, mask, thresh);
		if (cpu == -1) {
			cg = cg->cg_parent;
			continue;
		}
		steal = TDQ_CPU(cpu);
		CPU_CLR(cpu, &mask);
		tdq_lock_pair(tdq, steal);
		if (steal->tdq_load < thresh || steal->tdq_transferable == 0) {
			tdq_unlock_pair(tdq, steal);
			continue;
		}
		if (tdq->tdq_load == 0 && tdq_move(steal, tdq) == 0) {
			tdq_unlock_pair(tdq, steal);
			continue;
		}
		spinlock_exit();
		TDQ_UNLOCK(steal);
		mi_switch(SW_VOL | SWT_IDLE, NULL);
		thread_unlock(curthread);
		return (0);
	}
	spinlock_exit();
	return (1);
}
static int tdq_idled ( struct tdq * tdq ) { struct cpu_group * cg ; struct tdq * steal ; cpuset_t mask ; int thresh ; int cpu ; if ( smp_started == 0 || steal_idle == 0 ) return ( 1 ) ; CPU_FILL ( & mask ) ; CPU_CLR ( PCPU_GET ( cpuid ) , & mask ) ; spinlock_enter ( ) ; for ( cg = tdq -> tdq_cg ; cg != NULL ; ) { if ( ( cg -> cg_flags & CG_FLAG_THREAD ) == 0 ) thresh = steal_thresh ; else thresh = 1 ; cpu = sched_highest ( cg , mask , thresh ) ; if ( cpu == -1 ) { cg = cg -> cg_parent ; continue ; } steal = TDQ_CPU ( cpu ) ; CPU_CLR ( cpu , & mask ) ; tdq_lock_pair ( tdq , steal ) ; if ( steal -> tdq_load < thresh || steal -> tdq_transferable == 0 ) { tdq_unlock_pair ( tdq , steal ) ; continue ; } if ( tdq -> tdq_load == 0 && tdq_move ( steal , tdq ) == 0 ) { tdq_unlock_pair ( tdq , steal ) ; continue ; } spinlock_exit ( ) ; TDQ_UNLOCK ( steal ) ; mi_switch ( SW_VOL | SWT_IDLE , NULL ) ; thread_unlock ( curthread ) ; return ( 0 ) ; } spinlock_exit ( ) ; return ( 1 ) ; }
This tdq has idled.
This tdq has idled .
/* We don't want to be preempted while we're iterating. */ /*
		 * If a thread was added while interrupts were disabled don't
		 * steal one here.  If we fail to acquire one due to affinity
		 * restrictions loop again with this cpu removed from the
		 * set.
		 */