#include <mach/boolean.h>
#include <mach/thread_switch.h>
#include <ipc/ipc_port.h>
#include <ipc/ipc_space.h>
#include <kern/counters.h>
#include <kern/etap_macros.h>
#include <kern/ipc_kobject.h>
#include <kern/processor.h>
#include <kern/sched.h>
#include <kern/sched_prim.h>
#include <kern/spl.h>
#include <kern/task.h>
#include <kern/thread.h>
#include <kern/ast.h>
#include <mach/policy.h>
#include <kern/syscall_subr.h>
#include <mach/mach_host_server.h>
#include <mach/mach_syscalls.h>
#include <kern/mk_sp.h>
void
swtch_continue(void)
{
register processor_t myprocessor;
boolean_t result;
mp_disable_preemption();
myprocessor = current_processor();
result = myprocessor->runq.count > 0 ||
myprocessor->processor_set->runq.count > 0;
mp_enable_preemption();
thread_syscall_return(result);
}
boolean_t
swtch(void)
{
register processor_t myprocessor;
boolean_t result;
mp_disable_preemption();
myprocessor = current_processor();
if ( myprocessor->runq.count == 0 &&
myprocessor->processor_set->runq.count == 0 ) {
mp_enable_preemption();
return (FALSE);
}
mp_enable_preemption();
counter(c_swtch_block++);
thread_block_reason(swtch_continue, AST_YIELD);
mp_disable_preemption();
myprocessor = current_processor();
result = myprocessor->runq.count > 0 ||
myprocessor->processor_set->runq.count > 0;
mp_enable_preemption();
return (result);
}
void
swtch_pri_continue(void)
{
register processor_t myprocessor;
boolean_t result;
_mk_sp_thread_depress_abort(current_thread(), FALSE);
mp_disable_preemption();
myprocessor = current_processor();
result = myprocessor->runq.count > 0 ||
myprocessor->processor_set->runq.count > 0;
mp_enable_preemption();
thread_syscall_return(result);
}
boolean_t
swtch_pri(
int pri)
{
register processor_t myprocessor;
boolean_t result;
mp_disable_preemption();
myprocessor = current_processor();
if ( myprocessor->runq.count == 0 &&
myprocessor->processor_set->runq.count == 0 ) {
mp_enable_preemption();
return (FALSE);
}
mp_enable_preemption();
counter(c_swtch_pri_block++);
_mk_sp_thread_depress_abstime(std_quantum);
thread_block_reason(swtch_pri_continue, AST_YIELD);
_mk_sp_thread_depress_abort(current_thread(), FALSE);
mp_disable_preemption();
myprocessor = current_processor();
result = myprocessor->runq.count > 0 ||
myprocessor->processor_set->runq.count > 0;
mp_enable_preemption();
return (result);
}
kern_return_t
thread_switch(
mach_port_name_t thread_name,
int option,
mach_msg_timeout_t option_time)
{
register thread_t self = current_thread();
register thread_act_t hint_act = THR_ACT_NULL;
switch (option) {
case SWITCH_OPTION_NONE:
case SWITCH_OPTION_DEPRESS:
case SWITCH_OPTION_WAIT:
break;
default:
return (KERN_INVALID_ARGUMENT);
}
if (thread_name != MACH_PORT_NULL) {
ipc_port_t port;
if (ipc_port_translate_send(self->top_act->task->itk_space,
thread_name, &port) == KERN_SUCCESS) {
ip_reference(port);
ip_unlock(port);
hint_act = convert_port_to_act(port);
ipc_port_release(port);
}
}
return _mk_sp_thread_switch(hint_act, option, option_time);
}