예제 #1
0
/*
 * pthread_attr_setschedpolicy: sets the scheduling policy.
 */
int
pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
{
	thrattr_t *ap;

	if (attr != NULL && (ap = attr->__pthread_attrp) != NULL &&
	    policy != SCHED_SYS && get_info_by_policy(policy) != NULL) {
		ap->policy = policy;
		return (0);
	}
	return (EINVAL);
}
예제 #2
0
int
posix_spawnattr_setschedpolicy(
	posix_spawnattr_t *attr,
	int schedpolicy)
{
	spawn_attr_t *sap = attr->__spawn_attrp;

	if (sap == NULL || schedpolicy == SCHED_SYS)
		return (EINVAL);

	/*
	 * Cache the policy information for later use
	 * by the vfork() child of posix_spawn().
	 */
	if (get_info_by_policy(schedpolicy) == NULL)
		return (errno);

	sap->sa_schedpolicy = schedpolicy;
	return (0);
}
예제 #3
0
int
pthread_create(pthread_t *thread, const pthread_attr_t *attr,
    void * (*start_routine)(void *), void *arg)
{
	ulwp_t		*self = curthread;
	const thrattr_t	*ap = attr? attr->__pthread_attrp : def_thrattr();
	const pcclass_t	*pccp;
	long		flag;
	pthread_t	tid;
	int		error;

	update_sched(self);

	if (ap == NULL)
		return (EINVAL);

	/* validate explicit scheduling attributes */
	if (ap->inherit == PTHREAD_EXPLICIT_SCHED &&
	    (ap->policy == SCHED_SYS ||
	    (pccp = get_info_by_policy(ap->policy)) == NULL ||
	    ap->prio < pccp->pcc_primin || ap->prio > pccp->pcc_primax))
		return (EINVAL);

	flag = ap->scope | ap->detachstate | ap->daemonstate | THR_SUSPENDED;
	error = _thrp_create(ap->stkaddr, ap->stksize, start_routine, arg,
	    flag, &tid, ap->guardsize, ap->name);
	if (error == 0) {
		/*
		 * Record the original inheritence value for
		 * pthread_getattr_np(). We should always be able to find the
		 * thread.
		 */
		(void) _thr_setinherit(tid, ap->inherit);

		if (ap->inherit == PTHREAD_EXPLICIT_SCHED &&
		    (ap->policy != self->ul_policy ||
		    ap->prio != (self->ul_epri ? self->ul_epri :
		    self->ul_pri))) {
			/*
			 * The SUSv3 specification requires pthread_create()
			 * to fail with EPERM if it cannot set the scheduling
			 * policy and parameters on the new thread.
			 */
			error = _thr_setparam(tid, ap->policy, ap->prio);
		}

		if (error) {
			/*
			 * We couldn't determine this error before
			 * actually creating the thread.  To recover,
			 * mark the thread detached and cancel it.
			 * It is as though it was never created.
			 */
			ulwp_t *ulwp = find_lwp(tid);
			if (ulwp->ul_detached == 0) {
				ulwp->ul_detached = 1;
				ulwp->ul_usropts |= THR_DETACHED;
				(void) __lwp_detach(tid);
			}
			ulwp->ul_cancel_pending = 2; /* cancelled on creation */
			ulwp->ul_cancel_disabled = 0;
			ulwp_unlock(ulwp, self->ul_uberdata);
		} else if (thread) {
			*thread = tid;
		}
		(void) thr_continue(tid);
	}

	/* posix version expects EAGAIN for lack of memory */
	if (error == ENOMEM)
		error = EAGAIN;
	return (error);
}