Beispiel #1
0
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;
}
Beispiel #2
0
/*
 * 	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);
}