Module: xenomai-head
Branch: master
Commit: 486afd15219af66362028ad787e3321bdc729212
URL:    
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=486afd15219af66362028ad787e3321bdc729212

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Sun Sep 18 17:42:11 2011 +0200

sched: fix shadows sched policy changes to non real-time

Add the XNOTHER bit when a thread switches to priority 0, to disable
auto switch-back to secondary mode when holding a mutex.

In case we detect a thread which switched to priority 0 while holding
a mutex, send a SIGDEBUG signal.

---

 include/nucleus/sched-idle.h  |    2 ++
 include/nucleus/sched-rt.h    |    6 ++++++
 ksrc/nucleus/pod.c            |   10 ----------
 ksrc/nucleus/sched-sporadic.c |    2 ++
 ksrc/nucleus/sched-tp.c       |    2 ++
 ksrc/nucleus/shadow.c         |    5 ++++-
 ksrc/nucleus/synch.c          |   10 +++++++---
 7 files changed, 23 insertions(+), 14 deletions(-)

diff --git a/include/nucleus/sched-idle.h b/include/nucleus/sched-idle.h
index 6399a17..417170f 100644
--- a/include/nucleus/sched-idle.h
+++ b/include/nucleus/sched-idle.h
@@ -39,6 +39,8 @@ extern struct xnsched_class xnsched_class_idle;
 static inline void __xnsched_idle_setparam(struct xnthread *thread,
                                           const union xnsched_policy_param *p)
 {
+       if (xnthread_test_state(thread, XNSHADOW))
+               xnthread_clear_state(thread, XNOTHER);
        thread->cprio = p->idle.prio;
 }
 
diff --git a/include/nucleus/sched-rt.h b/include/nucleus/sched-rt.h
index 71f655c..cc1cefa 100644
--- a/include/nucleus/sched-rt.h
+++ b/include/nucleus/sched-rt.h
@@ -86,6 +86,12 @@ static inline void __xnsched_rt_setparam(struct xnthread 
*thread,
                                         const union xnsched_policy_param *p)
 {
        thread->cprio = p->rt.prio;
+       if (xnthread_test_state(thread, XNSHADOW)) {
+               if (thread->cprio)
+                       xnthread_clear_state(thread, XNOTHER);
+               else
+                       xnthread_set_state(thread, XNOTHER);
+       }
 }
 
 static inline void __xnsched_rt_getparam(struct xnthread *thread,
diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c
index 9a02e80..d19999f 100644
--- a/ksrc/nucleus/pod.c
+++ b/ksrc/nucleus/pod.c
@@ -1896,16 +1896,6 @@ int __xnpod_set_thread_schedparam(struct xnthread 
*thread,
                xnsched_putback(thread);
 
 #ifdef CONFIG_XENO_OPT_PERVASIVE
-       /*
-        * A non-real-time shadow may upgrade to real-time FIFO
-        * scheduling, but the latter may never downgrade to
-        * SCHED_NORMAL Xenomai-wise. In the valid case, we clear
-        * XNOTHER to reflect the change. Note that we keep handling
-        * non real-time shadow specifics in higher code layers, not
-        * to pollute the core scheduler with peculiarities.
-        */
-       if (sched_class == &xnsched_class_rt && sched_param->rt.prio > 0)
-               xnthread_clear_state(thread, XNOTHER);
        if (propagate) {
                if (xnthread_test_state(thread, XNRELAX))
                        xnshadow_renice(thread);
diff --git a/ksrc/nucleus/sched-sporadic.c b/ksrc/nucleus/sched-sporadic.c
index fd37c21..ffc9bab 100644
--- a/ksrc/nucleus/sched-sporadic.c
+++ b/ksrc/nucleus/sched-sporadic.c
@@ -258,6 +258,8 @@ static void xnsched_sporadic_setparam(struct xnthread 
*thread,
                }
        }
 
+       if (xnthread_test_state(thread, XNSHADOW))
+               xnthread_clear_state(thread, XNOTHER);
        thread->cprio = p->pss.current_prio;
 }
 
diff --git a/ksrc/nucleus/sched-tp.c b/ksrc/nucleus/sched-tp.c
index 43a548e..a2af1d3 100644
--- a/ksrc/nucleus/sched-tp.c
+++ b/ksrc/nucleus/sched-tp.c
@@ -100,6 +100,8 @@ static void xnsched_tp_setparam(struct xnthread *thread,
 {
        struct xnsched *sched = thread->sched;
 
+       if (xnthread_test_state(thread, XNSHADOW))
+               xnthread_clear_state(thread, XNOTHER);
        thread->tps = &sched->tp.partitions[p->tp.ptid];
        thread->cprio = p->tp.prio;
 }
diff --git a/ksrc/nucleus/shadow.c b/ksrc/nucleus/shadow.c
index 21cc191..7fe44a1 100644
--- a/ksrc/nucleus/shadow.c
+++ b/ksrc/nucleus/shadow.c
@@ -2756,9 +2756,12 @@ static inline void do_setsched_event(struct task_struct 
*p, int priority)
        union xnsched_policy_param param;
        struct xnsched *sched;
 
-       if (!thread || p->policy != SCHED_FIFO)
+       if (!thread || (p->policy != SCHED_FIFO && p->policy != SCHED_OTHER))
                return;
 
+       if (p->policy == SCHED_OTHER)
+               priority = 0;
+
        /*
         * Linux's priority scale is a subset of the core pod's
         * priority scale, so there is no need to bound the priority
diff --git a/ksrc/nucleus/synch.c b/ksrc/nucleus/synch.c
index b956e46..47bc0c5 100644
--- a/ksrc/nucleus/synch.c
+++ b/ksrc/nucleus/synch.c
@@ -684,9 +684,13 @@ xnsynch_release_thread(struct xnsynch *synch, struct 
xnthread *lastowner)
 
        XENO_BUGON(NUCLEUS, !testbits(synch->status, XNSYNCH_OWNER));
 
-       if (xnthread_test_state(lastowner, XNOTHER))
-               xnthread_dec_rescnt(lastowner);
-       XENO_BUGON(NUCLEUS, xnthread_get_rescnt(lastowner) < 0);
+       if (xnthread_test_state(lastowner, XNOTHER)) {
+               if (xnthread_get_rescnt(lastowner) == 0)
+                       xnshadow_send_sig(lastowner, SIGDEBUG,
+                                         SIGDEBUG_MIGRATE_PRIOINV, 1);
+               else
+                       xnthread_dec_rescnt(lastowner);
+       }
        lastownerh = xnthread_handle(lastowner);
 
        if (use_fastlock &&


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to