1999-11-30 09:07:29 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by John Birrell.
|
|
|
|
* 4. Neither the name of the author nor the names of any co-contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
* Extensively modified and added to by Richard Seaman, Jr. <dick@tar.com>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include <sys/syscall.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/resource.h>
|
|
|
|
#include <unistd.h>
|
1999-12-24 01:12:08 +00:00
|
|
|
#include <errno.h>
|
1999-11-30 09:07:29 +00:00
|
|
|
#include "pthread.h"
|
|
|
|
#include "internals.h"
|
|
|
|
|
|
|
|
int _sched_yield(void);
|
|
|
|
int _sched_setparam(pid_t pid, const struct sched_param *param);
|
|
|
|
int _sched_getparam(pid_t pid, struct sched_param *param);
|
|
|
|
int _sched_setscheduler(pid_t pid, int policy,
|
|
|
|
const struct sched_param *param);
|
|
|
|
int _sched_getscheduler(pid_t pid);
|
|
|
|
int _sched_get_priority_max(int policy);
|
|
|
|
int _sched_get_priority_min(int policy);
|
|
|
|
int _sched_rr_get_interval(pid_t pid, struct timespec *interval);
|
|
|
|
|
1999-12-24 01:12:08 +00:00
|
|
|
int __sched_setparam(pid_t pid, const struct sched_param *param);
|
|
|
|
int __sched_setscheduler(pid_t pid, int policy,
|
|
|
|
const struct sched_param *param);
|
|
|
|
int __sched_getscheduler(pid_t pid);
|
|
|
|
int __sched_get_priority_max(int policy);
|
|
|
|
int __sched_get_priority_min(int policy);
|
|
|
|
int __sched_getparam(pid_t pid, struct sched_param *param);
|
|
|
|
int __sched_rr_get_interval(pid_t pid, struct timespec *interval);
|
|
|
|
|
1999-11-30 09:07:29 +00:00
|
|
|
extern int _posix_priority_scheduling;
|
|
|
|
|
|
|
|
int
|
|
|
|
sched_yield(void)
|
|
|
|
{
|
|
|
|
if (_posix_priority_scheduling)
|
|
|
|
return (_sched_yield());
|
|
|
|
else
|
|
|
|
syscall(SYS_yield);
|
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef HAVE_FIXED_SCHED_FUNCTIONS
|
|
|
|
int __sched_setparam(pid_t pid, const struct sched_param *param)
|
|
|
|
{
|
|
|
|
if (_posix_priority_scheduling)
|
|
|
|
return (_sched_setparam(pid, param));
|
|
|
|
else {
|
|
|
|
errno = ENOSYS;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int __sched_setscheduler(pid_t pid, int policy,
|
|
|
|
const struct sched_param *param)
|
|
|
|
{
|
|
|
|
if (_posix_priority_scheduling) {
|
|
|
|
return (_sched_setscheduler(pid, policy, param));
|
|
|
|
} else {
|
|
|
|
errno = ENOSYS;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int __sched_getscheduler(pid_t pid)
|
|
|
|
{
|
|
|
|
if (_posix_priority_scheduling) {
|
|
|
|
return (_sched_getscheduler(pid));
|
|
|
|
} else {
|
|
|
|
errno = ENOSYS;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
int __sched_get_priority_max(int policy)
|
|
|
|
{
|
|
|
|
if (_posix_priority_scheduling)
|
|
|
|
return (_sched_get_priority_max (policy));
|
|
|
|
else
|
|
|
|
errno = ENOSYS;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
int __sched_get_priority_min(int policy)
|
|
|
|
{
|
|
|
|
if (_posix_priority_scheduling)
|
|
|
|
return (_sched_get_priority_min (policy));
|
|
|
|
else
|
|
|
|
errno = ENOSYS;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int __sched_getparam(pid_t pid, struct sched_param *param)
|
|
|
|
{
|
|
|
|
if (_posix_priority_scheduling)
|
|
|
|
return (_sched_getparam(pid, param));
|
|
|
|
else {
|
|
|
|
errno = ENOSYS;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int __sched_rr_get_interval(pid_t pid, struct timespec *interval)
|
|
|
|
{
|
|
|
|
if (_posix_priority_scheduling)
|
|
|
|
return (_sched_rr_get_interval(pid, interval));
|
|
|
|
else {
|
|
|
|
errno = ENOSYS;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
|
|
|
|
#include <sys/rtprio.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
|
|
/* Defines take from sys/posix4/ksched.c */
|
|
|
|
#define p4prio_to_rtpprio(P) (RTP_PRIO_MAX - (P))
|
|
|
|
#define rtpprio_to_p4prio(P) (RTP_PRIO_MAX - (P))
|
|
|
|
#define P1B_PRIO_MIN rtpprio_to_p4prio(RTP_PRIO_MAX)
|
|
|
|
#define P1B_PRIO_MAX rtpprio_to_p4prio(RTP_PRIO_MIN)
|
|
|
|
#define p4prio_to_p_nice(P) (-(P + PRIO_MIN))
|
|
|
|
#define p_nice_to_p4prio(P) (-(P - PRIO_MAX))
|
|
|
|
#define P_NICE_PRIO_MIN p_nice_to_p4prio(PRIO_MAX)
|
|
|
|
#define P_NICE_PRIO_MAX p_nice_to_p4prio(PRIO_MIN)
|
|
|
|
|
|
|
|
int _getpriority __P((int, int));
|
|
|
|
int _setpriority __P((int, int, int));
|
|
|
|
|
|
|
|
int sched_setparam(pid_t pid, const struct sched_param *param)
|
|
|
|
{
|
|
|
|
int policy = __sched_getscheduler (pid);
|
|
|
|
|
|
|
|
if (policy == -1)
|
|
|
|
return (-1);
|
|
|
|
return (__sched_setscheduler (pid, policy, param));
|
|
|
|
}
|
|
|
|
#pragma weak __sched_setparam=sched_setparam
|
|
|
|
|
|
|
|
int sched_setscheduler(pid_t pid, int policy,
|
|
|
|
const struct sched_param *param)
|
|
|
|
{
|
|
|
|
struct rtprio rtp;
|
|
|
|
int max, min;
|
|
|
|
int ret;
|
|
|
|
int curtype;
|
|
|
|
|
|
|
|
max = __sched_get_priority_max(policy);
|
|
|
|
if (max == -1)
|
|
|
|
return (-1);
|
|
|
|
min = __sched_get_priority_min(policy);
|
|
|
|
if (min == -1)
|
|
|
|
return (-1);
|
|
|
|
if (param->sched_priority > max ||
|
|
|
|
param->sched_priority < min) {
|
|
|
|
errno = EINVAL;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (policy) {
|
|
|
|
case SCHED_FIFO:
|
|
|
|
rtp.type = RTP_PRIO_FIFO;
|
|
|
|
rtp.prio = p4prio_to_rtpprio (param->sched_priority);
|
|
|
|
return (rtprio (RTP_SET, pid, &rtp));
|
|
|
|
|
|
|
|
case SCHED_RR:
|
|
|
|
rtp.type = RTP_PRIO_REALTIME;
|
|
|
|
rtp.prio = p4prio_to_rtpprio (param->sched_priority);
|
|
|
|
return (rtprio (RTP_SET, pid, &rtp));
|
|
|
|
|
|
|
|
case SCHED_OTHER:
|
|
|
|
curtype = __sched_getscheduler (pid);
|
|
|
|
if (curtype != SCHED_OTHER) {
|
|
|
|
rtp.type = RTP_PRIO_NORMAL;
|
|
|
|
rtp.prio = p4prio_to_rtpprio (0);
|
|
|
|
ret = rtprio (RTP_SET, pid, &rtp);
|
|
|
|
if (ret)
|
|
|
|
return (ret);
|
|
|
|
}
|
|
|
|
return (_setpriority (PRIO_PROCESS, pid,
|
|
|
|
p4prio_to_p_nice (param->sched_priority)));
|
|
|
|
|
|
|
|
default:
|
|
|
|
errno = EINVAL;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#pragma weak __sched_setscheduler=sched_setscheduler
|
|
|
|
|
|
|
|
int sched_getscheduler(pid_t pid)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
struct rtprio rtp;
|
|
|
|
|
|
|
|
ret = rtprio (RTP_LOOKUP, pid, &rtp);
|
|
|
|
if (!ret) {
|
|
|
|
switch (rtp.type) {
|
|
|
|
case RTP_PRIO_FIFO:
|
|
|
|
ret = SCHED_FIFO;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RTP_PRIO_REALTIME:
|
|
|
|
ret = SCHED_RR;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ret = SCHED_OTHER;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (ret);
|
|
|
|
}
|
|
|
|
#pragma weak __sched_getscheduler=sched_getscheduler
|
|
|
|
|
|
|
|
int sched_get_priority_max(int policy)
|
|
|
|
{
|
|
|
|
switch (policy)
|
|
|
|
{
|
|
|
|
case SCHED_FIFO:
|
|
|
|
case SCHED_RR:
|
|
|
|
return (P1B_PRIO_MAX);
|
|
|
|
|
|
|
|
case SCHED_OTHER:
|
|
|
|
return(P_NICE_PRIO_MAX);
|
|
|
|
|
|
|
|
default:
|
|
|
|
errno = EINVAL;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#pragma weak __sched_get_priority_max=sched_get_priority_max
|
|
|
|
|
|
|
|
int sched_get_priority_min(int policy)
|
|
|
|
{
|
|
|
|
switch (policy)
|
|
|
|
{
|
|
|
|
case SCHED_FIFO:
|
|
|
|
case SCHED_RR:
|
|
|
|
return (P1B_PRIO_MIN);
|
|
|
|
|
|
|
|
case SCHED_OTHER:
|
|
|
|
return(P_NICE_PRIO_MIN);
|
|
|
|
|
|
|
|
default:
|
|
|
|
errno = EINVAL;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#pragma weak __sched_get_priority_min=sched_get_priority_min
|
|
|
|
|
|
|
|
|
|
|
|
int sched_getparam(pid_t pid, struct sched_param *param)
|
|
|
|
{
|
|
|
|
int ret = 0;
|
|
|
|
struct rtprio rtp;
|
|
|
|
|
|
|
|
ret = rtprio (RTP_LOOKUP, pid, &rtp);
|
|
|
|
if (!ret) {
|
|
|
|
switch (rtp.type) {
|
|
|
|
case RTP_PRIO_FIFO:
|
|
|
|
case RTP_PRIO_REALTIME:
|
|
|
|
param->sched_priority = rtpprio_to_p4prio(rtp.prio);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
errno = 0;
|
|
|
|
ret = _getpriority (PRIO_PROCESS, pid);
|
|
|
|
if (ret == -1 && errno != 0)
|
|
|
|
return (-1);
|
|
|
|
|
|
|
|
param->sched_priority = p_nice_to_p4prio(ret);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (ret);
|
|
|
|
|
|
|
|
}
|
|
|
|
#pragma weak __sched_getparam=sched_getparam
|
|
|
|
|
|
|
|
int sched_rr_get_interval(pid_t pid, struct timespec *interval)
|
|
|
|
{
|
|
|
|
if (_posix_priority_scheduling)
|
|
|
|
return (_sched_rr_get_interval(pid, interval));
|
|
|
|
else {
|
|
|
|
errno = ENOSYS;
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#pragma weak __sched_rr_get_interval=sched_rr_get_interval
|
|
|
|
|
|
|
|
#endif
|