Commit 4beb554d authored by Philippe Gerum's avatar Philippe Gerum
Browse files

cobalt/posix/sched: add support for sched_getscheduler(2)

parent 08fde446
......@@ -49,6 +49,7 @@ __COBALT_CALL32emu_THUNK(sched_weightprio)
__COBALT_CALL32emu_THUNK(sched_setconfig_np)
__COBALT_CALL32emu_THUNK(sched_getconfig_np)
__COBALT_CALL32emu_THUNK(sched_setscheduler_ex)
__COBALT_CALL32emu_THUNK(sched_getscheduler_ex)
__COBALT_CALL32emu_THUNK(timer_create)
__COBALT_CALL32x_THUNK(timer_create)
__COBALT_CALL32emu_THUNK(timer_settime)
......
......@@ -785,6 +785,47 @@ COBALT_SYSCALL(sched_setscheduler_ex, conforming,
u_winoff, u_promoted);
}
int cobalt_sched_getscheduler_ex(pid_t pid,
int *policy_r,
struct sched_param_ex *param_ex)
{
struct cobalt_thread *thread;
spl_t s;
trace_cobalt_sched_getscheduler(pid);
if (pid) {
xnlock_get_irqsave(&nklock, s);
thread = cobalt_thread_find(pid);
xnlock_put_irqrestore(&nklock, s);
} else
thread = cobalt_current_thread();
if (thread == NULL)
return -ESRCH;
return __cobalt_thread_getschedparam_ex(thread, policy_r, param_ex);
}
COBALT_SYSCALL(sched_getscheduler_ex, current,
(pid_t pid,
int __user *u_policy,
struct sched_param_ex __user *u_param))
{
struct sched_param_ex param_ex;
int ret, policy;
ret = cobalt_sched_getscheduler_ex(pid, &policy, &param_ex);
if (ret)
return ret;
if (cobalt_copy_to_user(u_param, &param_ex, sizeof(param_ex)) ||
cobalt_copy_to_user(u_policy, &policy, sizeof(policy)))
return -EFAULT;
return 0;
}
void cobalt_sched_reclaim(struct cobalt_process *process)
{
struct cobalt_resources *p = &process->resources;
......
......@@ -63,6 +63,10 @@ int cobalt_sched_setscheduler_ex(pid_t pid,
__u32 __user *u_winoff,
int __user *u_promoted);
int cobalt_sched_getscheduler_ex(pid_t pid,
int *policy_r,
struct sched_param_ex *param_ex);
struct xnsched_class *
cobalt_sched_policy_param(union xnsched_policy_param *param,
int u_policy, const struct sched_param_ex *param_ex,
......@@ -91,10 +95,15 @@ COBALT_SYSCALL_DECL(sched_getconfig_np,
COBALT_SYSCALL_DECL(sched_setscheduler_ex,
(pid_t pid,
int policy,
const struct sched_param_ex *param_ex,
const struct sched_param_ex __user *u_param,
__u32 __user *u_winoff,
int __user *u_promoted));
COBALT_SYSCALL_DECL(sched_getscheduler_ex,
(pid_t pid,
int __user *u_policy,
struct sched_param_ex __user *u_param));
void cobalt_sched_reclaim(struct cobalt_process *process);
#endif /* !_COBALT_POSIX_SCHED_H */
......@@ -77,13 +77,15 @@ COBALT_SYSCALL32emu(thread_getschedparam_ex, current,
struct compat_sched_param_ex __user *u_param))
{
struct sched_param_ex param_ex;
int policy;
int ret, policy;
policy = __cobalt_thread_getschedparam_ex(pth, u_policy, &param_ex);
if (policy < 0)
return policy;
ret = cobalt_thread_getschedparam_ex(pth, &policy, &param_ex);
if (ret)
return ret;
return sys32_put_param_ex(policy, u_param, &param_ex);
ret = cobalt_copy_to_user(u_policy, &policy, sizeof(policy));
return ret ?: sys32_put_param_ex(policy, u_param, &param_ex);
}
static inline int sys32_fetch_timeout(struct timespec *ts,
......@@ -448,6 +450,23 @@ COBALT_SYSCALL32emu(sched_setscheduler_ex, conforming,
u_winoff, u_promoted);
}
COBALT_SYSCALL32emu(sched_getscheduler_ex, current,
(compat_pid_t pid,
int __user *u_policy,
struct compat_sched_param_ex __user *u_param))
{
struct sched_param_ex param_ex;
int ret, policy;
ret = cobalt_sched_getscheduler_ex(pid, &policy, &param_ex);
if (ret)
return ret;
ret = cobalt_copy_to_user(u_policy, &policy, sizeof(policy));
return ret ?: sys32_put_param_ex(policy, u_param, &param_ex);
}
COBALT_SYSCALL32emu(timer_create, current,
(clockid_t clock,
const struct compat_sigevent __user *u_sev,
......
......@@ -121,6 +121,11 @@ COBALT_SYSCALL32emu_DECL(sched_setscheduler_ex,
__u32 __user *u_winoff,
int __user *u_promoted));
COBALT_SYSCALL32emu_DECL(sched_getscheduler_ex,
(compat_pid_t pid,
int __user *u_policy,
struct compat_sched_param_ex __user *u_param));
COBALT_SYSCALL32emu_DECL(timer_create,
(clockid_t clock,
const struct compat_sigevent __user *u_sev,
......
......@@ -276,9 +276,9 @@ out:
return ret;
}
static inline int
pthread_getschedparam_ex(struct cobalt_thread *thread,
int *policy_r, struct sched_param_ex *param_ex)
int __cobalt_thread_getschedparam_ex(struct cobalt_thread *thread,
int *policy_r,
struct sched_param_ex *param_ex)
{
struct xnsched_class *base_class;
struct xnthread *base_thread;
......@@ -289,13 +289,14 @@ pthread_getschedparam_ex(struct cobalt_thread *thread,
if (!cobalt_obj_active(thread, COBALT_THREAD_MAGIC,
struct cobalt_thread)) {
xnlock_put_irqrestore(&nklock, s);
return ESRCH;
return -ESRCH;
}
base_thread = &thread->threadbase;
base_class = base_thread->base_class;
param_ex->sched_priority = xnthread_base_priority(base_thread);
*policy_r = base_class->policy;
param_ex->sched_priority = xnthread_base_priority(base_thread);
if (param_ex->sched_priority == 0) /* SCHED_FIFO/SCHED_WEAK */
*policy_r = SCHED_NORMAL;
......@@ -304,14 +305,14 @@ pthread_getschedparam_ex(struct cobalt_thread *thread,
ns2ts(&param_ex->sched_rr_quantum, base_thread->rrperiod);
*policy_r = SCHED_RR;
}
goto unlock_and_exit;
goto out;
}
#ifdef CONFIG_XENO_OPT_SCHED_WEAK
if (base_class == &xnsched_class_weak) {
if (*policy_r != SCHED_WEAK)
param_ex->sched_priority = -param_ex->sched_priority;
goto unlock_and_exit;
goto out;
}
#endif
#ifdef CONFIG_XENO_OPT_SCHED_SPORADIC
......@@ -320,25 +321,24 @@ pthread_getschedparam_ex(struct cobalt_thread *thread,
ns2ts(&param_ex->sched_ss_repl_period, base_thread->pss->param.repl_period);
ns2ts(&param_ex->sched_ss_init_budget, base_thread->pss->param.init_budget);
param_ex->sched_ss_max_repl = base_thread->pss->param.max_repl;
goto unlock_and_exit;
goto out;
}
#endif
#ifdef CONFIG_XENO_OPT_SCHED_TP
if (base_class == &xnsched_class_tp) {
param_ex->sched_tp_partition =
base_thread->tps - base_thread->sched->tp.partitions;
goto unlock_and_exit;
goto out;
}
#endif
#ifdef CONFIG_XENO_OPT_SCHED_QUOTA
if (base_class == &xnsched_class_quota) {
param_ex->sched_quota_group = base_thread->quota->tgid;
goto unlock_and_exit;
goto out;
}
#endif
unlock_and_exit:
out:
xnlock_put_irqrestore(&nklock, s);
return 0;
......@@ -500,13 +500,13 @@ COBALT_SYSCALL(thread_setschedparam_ex, conforming,
u_winoff, u_promoted);
}
int __cobalt_thread_getschedparam_ex(unsigned long pth,
int __user *u_policy,
struct sched_param_ex *param_ex)
int cobalt_thread_getschedparam_ex(unsigned long pth,
int *policy_r,
struct sched_param_ex *param_ex)
{
struct cobalt_local_hkey hkey;
struct cobalt_thread *thread;
int policy, ret;
int ret;
hkey.u_pth = pth;
hkey.mm = current->mm;
......@@ -514,34 +514,30 @@ int __cobalt_thread_getschedparam_ex(unsigned long pth,
if (thread == NULL)
return -ESRCH;
ret = pthread_getschedparam_ex(thread, &policy, param_ex);
ret = __cobalt_thread_getschedparam_ex(thread, policy_r, param_ex);
if (ret)
return ret;
trace_cobalt_pthread_getschedparam(pth, policy, param_ex);
if (cobalt_copy_to_user(u_policy, &policy, sizeof(int)))
return -EFAULT;
trace_cobalt_pthread_getschedparam(pth, *policy_r, param_ex);
return policy;
return 0;
}
/*
* NOTE: there is no cobalt_thread_getschedparam syscall defined by
* the Cobalt ABI. Useland retrieves scheduling parameters only via
* the extended cobalt_thread_getschedparam_ex syscall.
*/
COBALT_SYSCALL(thread_getschedparam_ex, current,
(unsigned long pth,
int __user *u_policy,
struct sched_param_ex __user *u_param))
{
struct sched_param_ex param_ex;
int policy;
int ret, policy;
ret = cobalt_thread_getschedparam_ex(pth, &policy, &param_ex);
if (ret)
return ret;
policy = __cobalt_thread_getschedparam_ex(pth, u_policy, &param_ex);
if (policy < 0)
return policy;
ret = cobalt_copy_to_user(u_policy, &policy, sizeof(policy));
if (ret)
return ret;
return cobalt_copy_to_user(u_param, &param_ex, sizeof(param_ex));
}
......
......@@ -131,8 +131,12 @@ int cobalt_thread_setschedparam_ex(unsigned long pth,
__u32 __user *u_winoff,
int __user *u_promoted);
int __cobalt_thread_getschedparam_ex(unsigned long pth,
int __user *u_policy,
int cobalt_thread_getschedparam_ex(unsigned long pth,
int *policy_r,
struct sched_param_ex *param_ex);
int __cobalt_thread_getschedparam_ex(struct cobalt_thread *thread,
int *policy_r,
struct sched_param_ex *param_ex);
struct cobalt_thread *cobalt_thread_find(pid_t pid);
......
......@@ -400,6 +400,11 @@ DEFINE_EVENT(cobalt_posix_scheduler, cobalt_sched_setscheduler,
TP_ARGS(pid, policy, param_ex)
);
DEFINE_EVENT(cobalt_posix_pid, cobalt_sched_getscheduler,
TP_PROTO(pid_t pid),
TP_ARGS(pid)
);
DECLARE_EVENT_CLASS(cobalt_posix_prio_bound,
TP_PROTO(int policy, int prio),
TP_ARGS(policy, prio),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment