mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2025-01-11 17:04:19 +01:00
Add syscalls thr_setscheduler, thr_getscheduler, and thr_setschedparam,
these syscalls are designed to set thread's scheduling parameters and policy, because each syscall contains a size parameter, it is possible to support future scheduling option, e.g SCHED_SPORADIC, this option needs other fields in structure sched_param, current they are not avaiblable.
This commit is contained in:
parent
4b14416350
commit
60088160c9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=160319
@ -27,6 +27,7 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "opt_posix.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
@ -44,6 +45,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/thr.h>
|
||||
#include <sys/rtprio.h>
|
||||
#include <posix4/sched.h>
|
||||
#include <posix4/posix4.h>
|
||||
#include <sys/umtx.h>
|
||||
#include <sys/limits.h>
|
||||
|
||||
@ -89,8 +91,11 @@ thr_new(struct thread *td, struct thr_new_args *uap)
|
||||
if ((error = copyin(uap->param, ¶m, sizeof(param))))
|
||||
return (error);
|
||||
sched = NULL;
|
||||
if (param.sched != NULL) {
|
||||
error = copyin(param.sched, &sched_param,
|
||||
if (param.sched_param != NULL) {
|
||||
if (param.sched_param_size != sizeof(struct thr_sched_param))
|
||||
return (EINVAL);
|
||||
|
||||
error = copyin(param.sched_param, &sched_param,
|
||||
sizeof(sched_param));
|
||||
if (error)
|
||||
return (error);
|
||||
@ -431,3 +436,154 @@ thr_set_name(struct thread *td, struct thr_set_name_args *uap)
|
||||
PROC_UNLOCK(p);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
thr_setscheduler(struct thread *td, struct thr_setscheduler_args *uap)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *ttd;
|
||||
struct rtprio rtp;
|
||||
struct sched_param param;
|
||||
int ret;
|
||||
|
||||
if (uap->param_size != sizeof(struct sched_param))
|
||||
return (EINVAL);
|
||||
|
||||
ret = copyin(uap->param, ¶m, sizeof(struct sched_param));
|
||||
if (ret)
|
||||
return (ret);
|
||||
|
||||
switch(uap->policy) {
|
||||
case SCHED_FIFO:
|
||||
if (suser(td) != 0)
|
||||
return (EPERM);
|
||||
rtp.type = PRI_FIFO;
|
||||
break;
|
||||
case SCHED_RR:
|
||||
if (suser(td) != 0)
|
||||
return (EPERM);
|
||||
rtp.type = PRI_REALTIME;
|
||||
break;
|
||||
case SCHED_OTHER:
|
||||
rtp.type = PRI_TIMESHARE;
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
rtp.prio = param.sched_priority;
|
||||
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
ret = p_cansched(td, p);
|
||||
if (ret != 0) {
|
||||
PROC_UNLOCK(p);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
ttd = thread_find(p, uap->id);
|
||||
if (ttd == NULL) {
|
||||
PROC_UNLOCK(p);
|
||||
return (ESRCH);
|
||||
}
|
||||
mtx_lock_spin(&sched_lock);
|
||||
ret = rtp_to_pri(&rtp, ttd->td_ksegrp);
|
||||
if (ret == 0) {
|
||||
if (TD_IS_RUNNING(ttd))
|
||||
ttd->td_flags |= TDF_NEEDRESCHED;
|
||||
else if (ttd->td_priority > ttd->td_ksegrp->kg_user_pri)
|
||||
sched_prio(ttd, ttd->td_ksegrp->kg_user_pri);
|
||||
}
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
PROC_UNLOCK(p);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
thr_getscheduler(struct thread *td, struct thr_getscheduler_args *uap)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *ttd;
|
||||
struct rtprio rtp;
|
||||
struct sched_param param;
|
||||
int policy;
|
||||
int ret;
|
||||
|
||||
if (uap->param_size != sizeof(struct sched_param))
|
||||
return (EINVAL);
|
||||
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
ttd = thread_find(p, uap->id);
|
||||
if (ttd == NULL) {
|
||||
PROC_UNLOCK(p);
|
||||
return (ESRCH);
|
||||
}
|
||||
mtx_lock_spin(&sched_lock);
|
||||
switch(ttd->td_ksegrp->kg_pri_class) {
|
||||
case PRI_TIMESHARE:
|
||||
policy = SCHED_OTHER;
|
||||
break;
|
||||
case PRI_FIFO:
|
||||
policy = SCHED_FIFO;
|
||||
break;
|
||||
case PRI_REALTIME:
|
||||
policy = SCHED_RR;
|
||||
break;
|
||||
default:
|
||||
policy = SCHED_OTHER; /* XXX SCHED_IDLE */
|
||||
}
|
||||
pri_to_rtp(ttd->td_ksegrp, &rtp);
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
param.sched_priority = rtp.prio;
|
||||
ret = copyout(&policy, uap->policy, sizeof(policy));
|
||||
if (ret == 0)
|
||||
ret = copyout(¶m, uap->param, sizeof(param));
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
thr_setschedparam(struct thread *td, struct thr_setschedparam_args *uap)
|
||||
{
|
||||
struct proc *p;
|
||||
struct thread *ttd;
|
||||
struct rtprio rtp;
|
||||
struct sched_param param;
|
||||
int ret;
|
||||
|
||||
if (uap->param_size != sizeof(struct sched_param))
|
||||
return (EINVAL);
|
||||
|
||||
ret = copyin(uap->param, ¶m, sizeof(struct sched_param));
|
||||
if (ret)
|
||||
return (ret);
|
||||
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
ret = p_cansched(td, p);
|
||||
if (ret != 0) {
|
||||
PROC_UNLOCK(p);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
ttd = thread_find(p, uap->id);
|
||||
if (ttd == NULL) {
|
||||
PROC_UNLOCK(p);
|
||||
return (ESRCH);
|
||||
}
|
||||
|
||||
mtx_lock_spin(&sched_lock);
|
||||
pri_to_rtp(ttd->td_ksegrp, &rtp);
|
||||
rtp.prio = param.sched_priority;
|
||||
ret = rtp_to_pri(&rtp, ttd->td_ksegrp);
|
||||
if (ret == 0) {
|
||||
if (TD_IS_RUNNING(ttd))
|
||||
ttd->td_flags |= TDF_NEEDRESCHED;
|
||||
else if (ttd->td_priority > ttd->td_ksegrp->kg_user_pri)
|
||||
sched_prio(ttd, ttd->td_ksegrp->kg_user_pri);
|
||||
}
|
||||
mtx_unlock_spin(&sched_lock);
|
||||
PROC_UNLOCK(p);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -822,5 +822,14 @@
|
||||
463 AUE_NULL MSTD { int abort2(const char *why, int nargs, void **args); }
|
||||
464 AUE_NULL MSTD { int thr_set_name(long id, const char *name); }
|
||||
465 AUE_NULL MNOSTD { int aio_fsync(int op, struct aiocb *aiocbp); }
|
||||
466 AUE_NULL MSTD { int thr_setscheduler(long id, int policy,\
|
||||
const struct sched_param *param, \
|
||||
int param_size); }
|
||||
467 AUE_NULL MSTD { int thr_getscheduler(long id, int *policy,\
|
||||
struct sched_param *param, \
|
||||
int param_size); }
|
||||
468 AUE_NULL MSTD { int thr_setschedparam(long id, \
|
||||
const struct sched_param *param, \
|
||||
int param_size); }
|
||||
; Please copy any additions and changes to the following compatability tables:
|
||||
; sys/compat/freebsd32/syscalls.master
|
||||
|
@ -52,8 +52,9 @@ struct thr_param {
|
||||
long *child_tid; /* address to store new TID. */
|
||||
long *parent_tid; /* parent accesses the new TID here. */
|
||||
int flags; /* thread flags. */
|
||||
struct thr_sched_param *sched; /* POSIX scheduler parameters .*/
|
||||
void *spare[3]; /* TODO: cpu affinity mask etc. */
|
||||
struct thr_sched_param *sched_param; /* POSIX scheduler parameters .*/
|
||||
long sched_param_size; /* scheduler parameter size */
|
||||
void *spare[2]; /* TODO: cpu affinity mask etc. */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -69,6 +70,12 @@ int thr_kill(long id, int sig);
|
||||
int thr_suspend(const struct timespec *timeout);
|
||||
int thr_wake(long id);
|
||||
int thr_set_name(long id, const char *name);
|
||||
int thr_setscheduler(long id, int policy, const struct sched_param *param,
|
||||
int param_size);
|
||||
int thr_getscheduler(long id, int *policy, struct sched_param *param,
|
||||
int param_size);
|
||||
int thr_setschedparam(long id, const struct sched_param *param,
|
||||
int param_size);
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
#endif /* ! _SYS_THR_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user