boolean_t swtch_pri(int pri) { thread_t thread = current_thread(); processor_t myprocessor; #if NCPUS > 1 myprocessor = current_processor(); if (myprocessor->runq.count == 0 && myprocessor->processor_set->runq.count == 0) return(FALSE); #endif /* NCPUS > 1 */ /* * XXX need to think about depression duration. * XXX currently using min quantum. */ thread_depress_priority(thread, min_quantum); counter(c_swtch_pri_block++); thread_block(swtch_pri_continue); if (thread->depress_priority >= 0) (void) thread_depress_abort(thread); myprocessor = current_processor(); return(myprocessor->runq.count > 0 || myprocessor->processor_set->runq.count > 0); }
void swtch_pri_continue(void) { register thread_t thread = current_thread(); register processor_t myprocessor; if (thread->depress_priority >= 0) (void) thread_depress_abort(thread); myprocessor = current_processor(); thread_syscall_return(myprocessor->runq.count > 0 || myprocessor->processor_set->runq.count > 0); /*NOTREACHED*/ }
void thread_switch_continue(void) { thread_t cur_thread = current_thread(); /* * Restore depressed priority */ if (cur_thread->depress_priority >= 0) (void) thread_depress_abort(cur_thread); thread_syscall_return(KERN_SUCCESS); /*NOTREACHED*/ }
/* * thread_switch: * * Context switch. User may supply thread hint. * * Fixed priority threads that call this get what they asked for * even if that violates priority order. */ kern_return_t thread_switch( mach_port_t thread_name, int option, mach_msg_timeout_t option_time) { thread_t cur_thread = current_thread(); processor_t myprocessor; ipc_port_t port; /* * Process option. */ switch (option) { case SWITCH_OPTION_NONE: /* * Nothing to do. */ break; case SWITCH_OPTION_DEPRESS: /* * Depress priority for given time. */ thread_depress_priority(cur_thread, option_time); break; case SWITCH_OPTION_WAIT: thread_will_wait_with_timeout(cur_thread, option_time); break; default: return(KERN_INVALID_ARGUMENT); } #ifndef MIGRATING_THREADS /* XXX thread_run defunct */ /* * Check and act on thread hint if appropriate. */ if ((thread_name != 0) && (ipc_port_translate_send(cur_thread->task->itk_space, thread_name, &port) == KERN_SUCCESS)) { /* port is locked, but it might not be active */ /* * Get corresponding thread. */ if (ip_active(port) && (ip_kotype(port) == IKOT_THREAD)) { thread_t thread; spl_t s; thread = (thread_t) port->ip_kobject; /* * Check if the thread is in the right pset. Then * pull it off its run queue. If it * doesn't come, then it's not eligible. */ s = splsched(); thread_lock(thread); if ((thread->processor_set == cur_thread->processor_set) && (rem_runq(thread) != RUN_QUEUE_NULL)) { /* * Hah, got it!! */ thread_unlock(thread); (void) splx(s); ip_unlock(port); /* XXX thread might disappear on us now? */ #if MACH_FIXPRI if (thread->policy == POLICY_FIXEDPRI) { myprocessor = current_processor(); myprocessor->quantum = thread->sched_data; myprocessor->first_quantum = TRUE; } #endif /* MACH_FIXPRI */ counter(c_thread_switch_handoff++); thread_run(thread_switch_continue, thread); /* * Restore depressed priority */ if (cur_thread->depress_priority >= 0) (void) thread_depress_abort(cur_thread); return(KERN_SUCCESS); } thread_unlock(thread); (void) splx(s); } ip_unlock(port); } #endif /* not MIGRATING_THREADS */ /* * No handoff hint supplied, or hint was wrong. Call thread_block() in * hopes of running something else. If nothing else is runnable, * thread_block will detect this. WARNING: thread_switch with no * option will not do anything useful if the thread calling it is the * highest priority thread (can easily happen with a collection * of timesharing threads). */ #if NCPUS > 1 myprocessor = current_processor(); if (myprocessor->processor_set->runq.count > 0 || myprocessor->runq.count > 0) #endif /* NCPUS > 1 */ { counter(c_thread_switch_block++); thread_block(thread_switch_continue); } /* * Restore depressed priority */ if (cur_thread->depress_priority >= 0) (void) thread_depress_abort(cur_thread); return(KERN_SUCCESS); }