Module: xenomai-3
Branch: next
Commit: 4beb554db716acad7f5998e56ce2c1350146d98b
URL:    
http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=4beb554db716acad7f5998e56ce2c1350146d98b

Author: Philippe Gerum <r...@xenomai.org>
Date:   Tue Sep 22 10:41:09 2015 +0200

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

---

 .../arch/x86/include/asm/xenomai/syscall32-table.h |    1 +
 kernel/cobalt/posix/sched.c                        |   41 ++++++++++++++
 kernel/cobalt/posix/sched.h                        |   11 +++-
 kernel/cobalt/posix/syscall32.c                    |   29 ++++++++--
 kernel/cobalt/posix/syscall32.h                    |    5 ++
 kernel/cobalt/posix/thread.c                       |   58 +++++++++-----------
 kernel/cobalt/posix/thread.h                       |    8 ++-
 kernel/cobalt/trace/cobalt-posix.h                 |    5 ++
 8 files changed, 119 insertions(+), 39 deletions(-)

diff --git a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h 
b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h
index 53aa131..7484c3a 100644
--- a/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h
+++ b/kernel/cobalt/arch/x86/include/asm/xenomai/syscall32-table.h
@@ -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)
diff --git a/kernel/cobalt/posix/sched.c b/kernel/cobalt/posix/sched.c
index ff4fdc9..b73d531 100644
--- a/kernel/cobalt/posix/sched.c
+++ b/kernel/cobalt/posix/sched.c
@@ -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;
diff --git a/kernel/cobalt/posix/sched.h b/kernel/cobalt/posix/sched.h
index 4ccef3c..2b23be0 100644
--- a/kernel/cobalt/posix/sched.h
+++ b/kernel/cobalt/posix/sched.h
@@ -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 */
diff --git a/kernel/cobalt/posix/syscall32.c b/kernel/cobalt/posix/syscall32.c
index fda93a9..d0af2cc 100644
--- a/kernel/cobalt/posix/syscall32.c
+++ b/kernel/cobalt/posix/syscall32.c
@@ -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,
diff --git a/kernel/cobalt/posix/syscall32.h b/kernel/cobalt/posix/syscall32.h
index 045e6be..64f0958 100644
--- a/kernel/cobalt/posix/syscall32.h
+++ b/kernel/cobalt/posix/syscall32.h
@@ -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,
diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c
index 0fe2088..5886ceb 100644
--- a/kernel/cobalt/posix/thread.c
+++ b/kernel/cobalt/posix/thread.c
@@ -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));
 }
diff --git a/kernel/cobalt/posix/thread.h b/kernel/cobalt/posix/thread.h
index 1894774..abbb203 100644
--- a/kernel/cobalt/posix/thread.h
+++ b/kernel/cobalt/posix/thread.h
@@ -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);
diff --git a/kernel/cobalt/trace/cobalt-posix.h 
b/kernel/cobalt/trace/cobalt-posix.h
index 9c2ae22..536108d 100644
--- a/kernel/cobalt/trace/cobalt-posix.h
+++ b/kernel/cobalt/trace/cobalt-posix.h
@@ -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),


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://xenomai.org/mailman/listinfo/xenomai-git

Reply via email to