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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed Dec 18 10:01:24 2013 +0100

cobalt/sched: properly handle side-effects of xnsched_pick() in debug mode

In debug mode, we unconditionally pick the next runnable thread in
order to check for consistency with XNRESCHED (i.e. XNRESCHED shall be
raised if the scheduler state has changed).

Since xnsched_pick() may change the scheduler state - either directly,
or indirectly via the policy module, we must collect need_resched
_after_ the new current thread was picked.

---

 kernel/cobalt/sched.c |   15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/kernel/cobalt/sched.c b/kernel/cobalt/sched.c
index a70151f..d26908c 100644
--- a/kernel/cobalt/sched.c
+++ b/kernel/cobalt/sched.c
@@ -252,6 +252,7 @@ struct xnthread *xnsched_pick_next(struct xnsched *sched)
                if (!xnthread_test_state(curr, XNREADY)) {
                        xnsched_requeue(curr);
                        xnthread_set_state(curr, XNREADY);
+                       xnsched_set_self_resched(sched);
                }
        }
 
@@ -770,12 +771,24 @@ int __xnsched_run(struct xnsched *sched)
        xntrace_pid(xnthread_host_pid(curr), xnthread_current_priority(curr));
 reschedule:
        switched = 0;
-       need_resched = test_resched(sched);
 #if !XENO_DEBUG(NUCLEUS)
+       need_resched = test_resched(sched);
        if (!need_resched)
                goto signal_unlock_and_exit;
 #endif /* !XENO_DEBUG(NUCLEUS) */
        next = xnsched_pick_next(sched);
+#if XENO_DEBUG(NUCLEUS)
+       /*
+        * CAUTION: in debug mode, we unconditionally pick the next
+        * runnable thread in order to check for consistency with
+        * XNRESCHED (i.e. XNRESCHED shall be raised if the scheduler
+        * state has changed). Since xnsched_pick() may change the
+        * scheduler state - either directly, or indirectly via the
+        * policy plugin, we must collect need_resched _after_ the new
+        * current thread was picked.
+        */
+       need_resched = test_resched(sched);
+#endif
        if (next == curr) {
                if (unlikely(xnthread_test_state(next, XNROOT))) {
                        if (sched->lflags & XNHTICK)


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

Reply via email to