- processor_t processor;
- spl_t s;
-
- s = splsched();
- thread_lock(thread);
-
- /*
- * Check if the thread is in the right pset,
- * is not bound to a different processor,
- * and that realtime is not involved.
- *
- * Next, pull it off its run queue. If it
- * doesn't come, it's not eligible.
- */
- processor = current_processor();
- if (processor->current_pri < BASEPRI_RTQUEUES &&
- thread->sched_pri < BASEPRI_RTQUEUES &&
- thread->processor_set == processor->processor_set &&
- (thread->bound_processor == PROCESSOR_NULL ||
- thread->bound_processor == processor) &&
- run_queue_remove(thread) != RUN_QUEUE_NULL ) {
- /*
- * Hah, got it!!
- */
- thread_unlock(thread);
-
- thread_deallocate_internal(thread);
-
- if (option == SWITCH_OPTION_WAIT)
+ spl_t s = splsched();
+
+ /* This may return a different thread if the target is pushing on something */
+ thread_t pulled_thread = thread_run_queue_remove_for_handoff(thread);
+
+ KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_SCHED,MACH_SCHED_THREAD_SWITCH)|DBG_FUNC_NONE,
+ thread_tid(thread), thread->state,
+ pulled_thread ? TRUE : FALSE, 0, 0);
+
+ if (pulled_thread != THREAD_NULL) {
+ /* We can't be dropping the last ref here */
+ thread_deallocate_safe(thread);
+
+ if (wait_option)