Bug #622 » xu-schedparams-checkother.patch
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);
|