Project

General

Profile

Bug #622 » xu-schedparams-checkother.patch

aoiko, 04/30/2007 12:49 PM

View differences:

thread/thr_attr.c 27 Apr 2007 21:37:04 -0000
struct pthread_attr _pthread_attr_default = {
.sched_policy = SCHED_OTHER,
.sched_inherit = 0,
.sched_interval = TIMESLICE_USEC,
.prio = THR_DEFAULT_PRIORITY,
.suspend = THR_CREATE_RUNNING,
.flags = 0,
thread/thr_getschedparam.c 28 Apr 2007 09:46:01 -0000
struct sched_param *param)
{
struct pthread *curthread = tls_get_curthread();
int ret, tmp;
int ret;
if ((param == NULL) || (policy == NULL))
/* Return an invalid argument error: */
ret = EINVAL;
else if (pthread == curthread) {
if (policy == NULL || param == NULL)
return (EINVAL);
if (pthread == curthread) {
/*
* Avoid searching the thread list when it is the current
* thread.
*/
THR_THREAD_LOCK(curthread, curthread);
param->sched_priority =
THR_BASE_PRIORITY(pthread->base_priority);
tmp = pthread->attr.sched_policy;
THR_THREAD_UNLOCK(curthread, curthread);
*policy = tmp;
THR_LOCK(curthread);
*policy = curthread->attr.sched_policy;
param->sched_priority = curthread->attr.prio;
THR_UNLOCK(curthread);
ret = 0;
}
/* Find the thread in the list of active threads. */
else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0))
== 0) {
THR_THREAD_LOCK(curthread, pthread);
param->sched_priority =
THR_BASE_PRIORITY(pthread->base_priority);
tmp = pthread->attr.sched_policy;
*policy = pthread->attr.sched_policy;
param->sched_priority = pthread->attr.prio;
THR_THREAD_UNLOCK(curthread, pthread);
_thr_ref_delete(curthread, pthread);
*policy = tmp;
}
return (ret);
}
thread/thr_kern.c 30 Apr 2007 11:17:45 -0000
#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/signalvar.h>
#include <sys/rtprio.h>
#include <pthread.h>
#include "thr_private.h"
......
{
return (lwp_gettid());
}
/*
* We don't use the priority for SCHED_OTHER, but
* some programs may depend on getting an error when
* setting a priority that is out of the range returned
* by sched_get_priority_{min,max}. Not sure if this
* falls into implementation defined behavior or not.
*/
int
_thr_set_sched_other_prio(struct pthread *pth, int prio)
{
static int max, min, init_status;
/*
* switch (init_status) {
* case 0: need initialization
* case 1: initialization successful
* case 2: initialization failed. can't happen, but if
* it does, accept all and hope for the best.
* It's not like we use it anyway.
*/
if (!init_status) {
int tmp = errno;
errno = 0;
init_status = 1;
if (((min = sched_get_priority_min(SCHED_OTHER)) == -1) &&
(errno != 0))
init_status = 2;
if (((max = sched_get_priority_max(SCHED_OTHER)) == -1) &&
(errno != 0))
init_status = 2;
errno = tmp;
}
if ((init_status == 2) || ((prio >= min) && (prio <= max))) {
return 0;
}
errno = EINVAL;
return -1;
}
int
_rtp_to_schedparam(const struct rtprio *rtp, int *policy,
struct sched_param *param)
{
switch(rtp->type) {
case RTP_PRIO_REALTIME:
*policy = SCHED_RR;
param->sched_priority = RTP_PRIO_MAX - rtp->prio;
break;
case RTP_PRIO_FIFO:
*policy = SCHED_FIFO;
param->sched_priority = RTP_PRIO_MAX - rtp->prio;
break;
default:
*policy = SCHED_OTHER;
param->sched_priority = 0;
break;
}
return (0);
}
int
_schedparam_to_rtp(int policy, const struct sched_param *param,
struct rtprio *rtp)
{
switch(policy) {
case SCHED_RR:
rtp->type = RTP_PRIO_REALTIME;
rtp->prio = RTP_PRIO_MAX - param->sched_priority;
break;
case SCHED_FIFO:
rtp->type = RTP_PRIO_FIFO;
rtp->prio = RTP_PRIO_MAX - param->sched_priority;
break;
case SCHED_OTHER:
default:
rtp->type = RTP_PRIO_NORMAL;
rtp->prio = 0;
break;
}
return (0);
}
int
_thr_getscheduler(lwpid_t lwpid, int *policy, struct sched_param *param)
{
struct pthread *curthread = tls_get_curthread();
struct rtprio rtp;
int ret;
if (lwpid == curthread->tid)
lwpid = -1;
ret = lwp_rtprio(RTP_LOOKUP, 0, lwpid, &rtp);
if (ret == -1)
return (ret);
_rtp_to_schedparam(&rtp, policy, param);
return (0);
}
int
_thr_setscheduler(lwpid_t lwpid, int policy, const struct sched_param *param)
{
struct pthread *curthread = tls_get_curthread();
struct rtprio rtp;
if (lwpid == curthread->tid)
lwpid = -1;
_schedparam_to_rtp(policy, param, &rtp);
return (lwp_rtprio(RTP_SET, 0, lwpid, &rtp));
}
thread/thr_private.h 30 Apr 2007 10:38:54 -0000
struct pthread_attr {
int sched_policy;
int sched_inherit;
int sched_interval;
int prio;
int suspend;
#define THR_STACK_USER 0x100 /* 0xFF reserved for <pthread.h> */
......
void _thr_report_death(struct pthread *curthread);
void _thread_bp_create(void);
void _thread_bp_death(void);
int _thr_getscheduler(lwpid_t, int *, struct sched_param *);
int _thr_setscheduler(lwpid_t, int, const struct sched_param *);
int _thr_set_sched_other_prio(struct pthread *, int);
/* #include <sys/aio.h> */
#ifdef _SYS_AIO_H_
thread/thr_setschedparam.c 30 Apr 2007 10:40:46 -0000
struct pthread *curthread = tls_get_curthread();
int ret = 0;
if ((param == NULL) || (policy < SCHED_FIFO) || (policy > SCHED_RR)) {
/* Return an invalid argument error: */
ret = EINVAL;
} else if ((param->sched_priority < THR_MIN_PRIORITY) ||
(param->sched_priority > THR_MAX_PRIORITY)) {
/* Return an unsupported value error. */
ret = ENOTSUP;
/* Find the thread in the list of active threads: */
if (pthread == curthread) {
THR_LOCK(curthread);
if (curthread->attr.sched_policy == policy &&
curthread->attr.prio == param->sched_priority) {
THR_UNLOCK(curthread);
return (0);
}
if (policy == SCHED_OTHER) {
ret = _thr_set_sched_other_prio(curthread,
param->sched_priority);
} else {
ret = _thr_setscheduler(curthread->tid, policy, param);
}
if (ret == -1)
ret = errno;
else {
curthread->attr.sched_policy = policy;
curthread->attr.prio = param->sched_priority;
}
THR_UNLOCK(curthread);
} else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0))
== 0) {
/*
* Lock the threads scheduling queue while we change
* its priority:
*/
== 0) {
THR_THREAD_LOCK(curthread, pthread);
if (pthread->state == PS_DEAD) {
if (pthread->attr.sched_policy == policy &&
pthread->attr.prio == param->sched_priority) {
THR_THREAD_UNLOCK(curthread, pthread);
_thr_ref_delete(curthread, pthread);
return (ESRCH);
return (0);
}
/* Set the scheduling policy: */
pthread->attr.sched_policy = policy;
if (param->sched_priority ==
THR_BASE_PRIORITY(pthread->base_priority))
/*
* There is nothing to do; unlock the threads
* scheduling queue.
*/
THR_THREAD_UNLOCK(curthread, pthread);
if (policy == SCHED_OTHER) {
ret = _thr_set_sched_other_prio(curthread,
param->sched_priority);
} else {
ret = _thr_setscheduler(curthread->tid, policy, param);
}
if (ret == -1)
ret = errno;
else {
/* Set the thread base priority: */
pthread->base_priority = param->sched_priority;
/* Recalculate the active priority: */
pthread->active_priority = MAX(pthread->base_priority,
pthread->inherited_priority);
/* Unlock the threads scheduling queue: */
THR_THREAD_UNLOCK(curthread, pthread);
pthread->attr.sched_policy = policy;
pthread->attr.prio = param->sched_priority;
}
THR_THREAD_UNLOCK(curthread, pthread);
_thr_ref_delete(curthread, pthread);
}
return (ret);
(2-2/4)