kern_return_t server_thread_priorities( int priority, int max_priority) { kern_return_t kr; struct thread_basic_info ti; mach_msg_type_number_t ti_size; /* * First we have to get the current scheduling policy, because there * is no way to set the priority without also setting the policy. */ ti_size = THREAD_BASIC_INFO_COUNT; kr = thread_info(mach_thread_self(), THREAD_BASIC_INFO, (thread_info_t)&ti, &ti_size); if (kr != KERN_SUCCESS) { MACH3_DEBUG(2, kr, ("server_thread_priorities: thread_info")); return kr; } /* * Set the priorities using the correct scheduling policy. */ switch (ti.policy) { case POLICY_RR: { struct policy_rr_base rr_base; struct policy_rr_limit rr_limit; rr_base.quantum = 10; /* XXX should be larger ? */ rr_base.base_priority = priority; rr_limit.max_priority = max_priority; kr = thread_set_policy(mach_thread_self(), default_processor_set, POLICY_RR, (policy_base_t) &rr_base, POLICY_RR_BASE_COUNT, (policy_limit_t) &rr_limit, POLICY_RR_LIMIT_COUNT); break; } case POLICY_TIMESHARE: { struct policy_timeshare_base ts_base; struct policy_timeshare_limit ts_limit; ts_base.base_priority = priority; ts_limit.max_priority = max_priority; kr = thread_set_policy(mach_thread_self(), default_processor_set, POLICY_TIMESHARE, (policy_base_t) &ts_base, POLICY_TIMESHARE_BASE_COUNT, (policy_limit_t) &ts_limit, POLICY_TIMESHARE_LIMIT_COUNT); break; } case POLICY_FIFO: { struct policy_fifo_base ff_base; struct policy_fifo_limit ff_limit; ff_base.base_priority = priority; ff_limit.max_priority = max_priority; kr = thread_set_policy(mach_thread_self(), default_processor_set, POLICY_FIFO, (policy_base_t) &ff_base, POLICY_FIFO_BASE_COUNT, (policy_limit_t) &ff_limit, POLICY_FIFO_LIMIT_COUNT); break; } default: kr = KERN_FAILURE; break; } return kr; }
/* * thread_policy * * Set scheduling policy and parameters, both base and limit, for * the given thread. Policy must be a policy which is enabled for the * processor set. Change contained threads if requested. */ kern_return_t thread_policy( thread_t thread, policy_t policy, policy_base_t base, mach_msg_type_number_t count, boolean_t set_limit) { kern_return_t result = KERN_SUCCESS; processor_set_t pset = &pset0; policy_limit_t limit = NULL; int limcount = 0; policy_rr_limit_data_t rr_limit; policy_fifo_limit_data_t fifo_limit; policy_timeshare_limit_data_t ts_limit; if (thread == THREAD_NULL) return (KERN_INVALID_ARGUMENT); thread_mtx_lock(thread); if ( invalid_policy(policy) || ((POLICY_TIMESHARE | POLICY_RR | POLICY_FIFO) & policy) == 0 ) { thread_mtx_unlock(thread); return (KERN_INVALID_POLICY); } if (set_limit) { /* * Set scheduling limits to base priority. */ switch (policy) { case POLICY_RR: { policy_rr_base_t rr_base; if (count != POLICY_RR_BASE_COUNT) { result = KERN_INVALID_ARGUMENT; break; } limcount = POLICY_RR_LIMIT_COUNT; rr_base = (policy_rr_base_t) base; rr_limit.max_priority = rr_base->base_priority; limit = (policy_limit_t) &rr_limit; break; } case POLICY_FIFO: { policy_fifo_base_t fifo_base; if (count != POLICY_FIFO_BASE_COUNT) { result = KERN_INVALID_ARGUMENT; break; } limcount = POLICY_FIFO_LIMIT_COUNT; fifo_base = (policy_fifo_base_t) base; fifo_limit.max_priority = fifo_base->base_priority; limit = (policy_limit_t) &fifo_limit; break; } case POLICY_TIMESHARE: { policy_timeshare_base_t ts_base; if (count != POLICY_TIMESHARE_BASE_COUNT) { result = KERN_INVALID_ARGUMENT; break; } limcount = POLICY_TIMESHARE_LIMIT_COUNT; ts_base = (policy_timeshare_base_t) base; ts_limit.max_priority = ts_base->base_priority; limit = (policy_limit_t) &ts_limit; break; } default: result = KERN_INVALID_POLICY; break; } } else { /* * Use current scheduling limits. Ensure that the * new base priority will not exceed current limits. */ switch (policy) { case POLICY_RR: { policy_rr_base_t rr_base; if (count != POLICY_RR_BASE_COUNT) { result = KERN_INVALID_ARGUMENT; break; } limcount = POLICY_RR_LIMIT_COUNT; rr_base = (policy_rr_base_t) base; if (rr_base->base_priority > thread->max_priority) { result = KERN_POLICY_LIMIT; break; } rr_limit.max_priority = thread->max_priority; limit = (policy_limit_t) &rr_limit; break; } case POLICY_FIFO: { policy_fifo_base_t fifo_base; if (count != POLICY_FIFO_BASE_COUNT) { result = KERN_INVALID_ARGUMENT; break; } limcount = POLICY_FIFO_LIMIT_COUNT; fifo_base = (policy_fifo_base_t) base; if (fifo_base->base_priority > thread->max_priority) { result = KERN_POLICY_LIMIT; break; } fifo_limit.max_priority = thread->max_priority; limit = (policy_limit_t) &fifo_limit; break; } case POLICY_TIMESHARE: { policy_timeshare_base_t ts_base; if (count != POLICY_TIMESHARE_BASE_COUNT) { result = KERN_INVALID_ARGUMENT; break; } limcount = POLICY_TIMESHARE_LIMIT_COUNT; ts_base = (policy_timeshare_base_t) base; if (ts_base->base_priority > thread->max_priority) { result = KERN_POLICY_LIMIT; break; } ts_limit.max_priority = thread->max_priority; limit = (policy_limit_t) &ts_limit; break; } default: result = KERN_INVALID_POLICY; break; } } thread_mtx_unlock(thread); if (result == KERN_SUCCESS) result = thread_set_policy(thread, pset, policy, base, count, limit, limcount); return(result); }