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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Fri Aug 30 15:07:15 2013 +0200

cobalt/posix/thread: force sched_yield() to relinquish the CPU

If the round-robin move does not beget any context switch from the
calling thread running in primary mode, then force a domain transition
through secondary mode.

Rationale: it is most probably unexpected that sched_yield() does not
cause any context switch, since this service is commonly used for
implementing a poor man's cooperative scheduling. By forcing a
migration through the secondary mode then back, we guarantee that the
CPU has been relinquished for a while.

Typically, this behavior allows a thread running in primary mode to
effectively yield the CPU to a thread of same/higher priority stuck in
secondary mode.

---

 kernel/cobalt/posix/thread.c |   29 ++++++++++++++++++++++-------
 lib/cobalt/thread.c          |    2 +-
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c
index 342c044..205d4eb 100644
--- a/kernel/cobalt/posix/thread.c
+++ b/kernel/cobalt/posix/thread.c
@@ -1217,16 +1217,31 @@ int cobalt_sched_max_prio(int policy)
 
 int cobalt_sched_yield(void)
 {
-       struct sched_param_ex param;
-       struct cobalt_thread *curr;
-       int policy = SCHED_NORMAL;
+       struct cobalt_thread *curr = cobalt_current_thread();
 
-       curr = cobalt_current_thread();
-       pthread_getschedparam_ex(curr, &policy, &param);
        xnthread_resume(&curr->threadbase, 0);
-       xnsched_run();
+       if (xnsched_run())
+               return 0;
+
+       /*
+        * If the round-robin move did not beget any context switch to
+        * a thread running in primary mode, then force a domain
+        * transition through secondary mode.
+        *
+        * Rationale: it is most probably unexpected that
+        * sched_yield() does not cause any context switch, since this
+        * service is commonly used for implementing a poor man's
+        * cooperative scheduling. By forcing a migration through the
+        * secondary mode then back, we guarantee that the CPU has
+        * been relinquished for a while.
+        *
+        * Typically, this behavior allows a thread running in primary
+        * mode to effectively yield the CPU to a thread of
+        * same/higher priority stuck in secondary mode.
+        */
+       xnshadow_relax(0, 0);
 
-       return policy == SCHED_NORMAL;
+       return xnshadow_harden();
 }
 
 #ifdef CONFIG_XENO_OPT_SCHED_TP
diff --git a/lib/cobalt/thread.c b/lib/cobalt/thread.c
index 19f57a8..15a665d 100644
--- a/lib/cobalt/thread.c
+++ b/lib/cobalt/thread.c
@@ -164,7 +164,7 @@ COBALT_IMPL(int, sched_yield, (void))
        int ret;
 
        ret = -XENOMAI_SKINCALL0(__cobalt_muxid, sc_cobalt_sched_yield);
-       if (ret == -1)
+       if (ret == EPERM)
                ret = __STD(sched_yield());
 
        return ret;


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

Reply via email to