#include <cpus.h>
#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/sf.h>
#if 0
swtch_continue()
{
boolean_t retval;
register processor_t myprocessor;
mp_disable_preemption();
myprocessor = current_processor();
retval = (
#if NCPUS > 1
myprocessor->runq.count > 0 ||
#endif
myprocessor->processor_set->runq.count > 0);
mp_enable_preemption();
return retval;
}
#endif
boolean_t
swtch(void)
{
register processor_t myprocessor;
boolean_t result;
mp_disable_preemption();
myprocessor = current_processor();
if (
#if NCPUS > 1
myprocessor->runq.count == 0 &&
#endif
myprocessor->processor_set->runq.count == 0 ) {
mp_enable_preemption();
return (FALSE);
}
mp_enable_preemption();
counter(c_swtch_block++);
thread_block((void (*)(void)) 0);
mp_disable_preemption();
myprocessor = current_processor();
result =
#if NCPUS > 1
myprocessor->runq.count > 0 ||
#endif
myprocessor->processor_set->runq.count > 0;
mp_enable_preemption();
return (result);
}
boolean_t
swtch_pri(
int pri)
{
thread_t self = current_thread();
register processor_t myprocessor;
boolean_t result;
sched_policy_t *policy;
spl_t s;
s = splsched();
thread_lock(self);
myprocessor = current_processor();
if (
#if NCPUS > 1
myprocessor->runq.count == 0 &&
#endif
myprocessor->processor_set->runq.count == 0 ) {
thread_unlock(self);
splx(s);
return (FALSE);
}
policy = &sched_policy[self->policy];
thread_unlock(self);
splx(s);
policy->sp_ops.sp_swtch_pri(policy, pri);
mp_disable_preemption();
myprocessor = current_processor();
result =
#if NCPUS > 1
myprocessor->runq.count > 0 ||
#endif
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;
sched_policy_t *policy;
spl_t s;
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);
}
}
s = splsched();
thread_lock(self);
policy = &sched_policy[self->policy];
thread_unlock(self);
splx(s);
return (policy->sp_ops.
sp_thread_switch(policy, hint_act, option, option_time));
}