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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Wed Sep  4 11:42:18 2013 +0200

cobalt/shadow: introduce xnshadow_yield()

This service synchronizes with the linux scheduler, allowing to wait
for the next linux-originated schedule event from primary mode.

It can be used for implementing features aimed at throttling a
real-time activity.

---

 include/cobalt/kernel/shadow.h |    5 +++--
 kernel/cobalt/shadow.c         |   34 ++++++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/include/cobalt/kernel/shadow.h b/include/cobalt/kernel/shadow.h
index 8f5b4cb..b786120 100644
--- a/include/cobalt/kernel/shadow.h
+++ b/include/cobalt/kernel/shadow.h
@@ -21,6 +21,7 @@
 #define _COBALT_KERNEL_SHADOW_H
 
 #include <asm/xenomai/syscall.h>
+#include <cobalt/uapi/kernel/types.h>
 
 struct xnthread;
 struct xnthread_user_window;
@@ -99,8 +100,6 @@ int xnshadow_register_personality(struct xnpersonality 
*personality);
 
 int xnshadow_unregister_personality(int muxid);
 
-void xnshadow_reset_shield(void);
-
 void xnshadow_send_sig(struct xnthread *thread,
                       int sig,
                       int arg);
@@ -122,6 +121,8 @@ xnshadow_push_personality(struct xnthread *thread,
 void xnshadow_pop_personality(struct xnthread *thread,
                              struct xnpersonality *prev);
 
+int xnshadow_yield(xnticks_t timeout);
+
 extern struct xnpersonality xenomai_personality;
 
 #endif /* !_COBALT_KERNEL_SHADOW_H */
diff --git a/kernel/cobalt/shadow.c b/kernel/cobalt/shadow.c
index d711620..ab72f70 100644
--- a/kernel/cobalt/shadow.c
+++ b/kernel/cobalt/shadow.c
@@ -80,6 +80,8 @@ static DEFINE_SEMAPHORE(registration_mutex);
 
 static void *mayday_page;
 
+static struct xnsynch yield_sync;
+
 static struct list_head *ppd_hash;
 #define PPD_HASH_SIZE 13
 
@@ -2253,12 +2255,40 @@ static int handle_taskexit_event(struct task_struct *p) 
/* p == current */
        return EVENT_PROPAGATE;
 }
 
+int xnshadow_yield(xnticks_t timeout)
+{
+       int ret;
+
+       ret = xnsynch_sleep_on(&yield_sync, timeout, XN_RELATIVE);
+       if (ret & XNBREAK)
+               return -EINTR;
+
+       return 0;
+}
+
+static inline void signal_yield(void)
+{
+       spl_t s;
+
+       if (!xnsynch_pended_p(&yield_sync))
+               return;
+
+       xnlock_get_irqsave(&nklock, s);
+       if (xnsynch_pended_p(&yield_sync)) {
+               xnsynch_flush(&yield_sync, 0);
+               xnsched_run();
+       }
+       xnlock_put_irqrestore(&nklock, s);
+}
+
 static int handle_schedule_event(struct task_struct *next_task)
 {
        struct task_struct *prev_task;
        struct xnthread *prev, *next;
        sigset_t pending;
 
+       signal_yield();
+
        prev_task = current;
        prev = xnshadow_thread(prev_task);
        next = xnshadow_thread(next_task);
@@ -2603,6 +2633,8 @@ int xnshadow_mount(void)
        unsigned int i, size;
        int ret;
 
+       xnsynch_init(&yield_sync, XNSYNCH_FIFO, NULL);
+
        ret = xndebug_init();
        if (ret)
                return ret;
@@ -2649,6 +2681,8 @@ void xnshadow_cleanup(void)
        mayday_cleanup_page();
 
        xndebug_cleanup();
+
+       xnsynch_destroy(&yield_sync);
 }
 
 /* Xenomai's generic personality. */


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

Reply via email to