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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sat Sep  7 09:58:35 2013 +0200

cobalt/shadow: introduce personality handlers for tracking domain migrations

The new ->harden_thread() and ->relax_thread() handlers may be
installed by personalities, so that each domain transition ends with a
call to the relevant handler for the target mode (i.e. ->harden_thread()
for a secondary -> primary mode switch, or ->relax_thread() in the
opposite direction).

Each handler is invoked with hw IRQs off, nklock held.

---

 include/cobalt/kernel/shadow.h |    2 ++
 kernel/cobalt/shadow.c         |   30 +++++++++++++++++-------------
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/include/cobalt/kernel/shadow.h b/include/cobalt/kernel/shadow.h
index b786120..71205e7 100644
--- a/include/cobalt/kernel/shadow.h
+++ b/include/cobalt/kernel/shadow.h
@@ -42,6 +42,8 @@ struct xnpersonality {
                struct xnshadow_ppd *(*attach_process)(void);
                void (*detach_process)(struct xnshadow_ppd *ppd);
                struct xnpersonality *(*map_thread)(struct xnthread *thread);
+               struct xnpersonality *(*relax_thread)(struct xnthread *thread);
+               struct xnpersonality *(*harden_thread)(struct xnthread *thread);
                struct xnpersonality *(*exit_thread)(struct xnthread *thread);
                struct xnpersonality *(*finalize_thread)(struct xnthread 
*thread);
        } ops;
diff --git a/kernel/cobalt/shadow.c b/kernel/cobalt/shadow.c
index 2fb0b42..c8d5d5f 100644
--- a/kernel/cobalt/shadow.c
+++ b/kernel/cobalt/shadow.c
@@ -501,7 +501,13 @@ void ipipe_migration_hook(struct task_struct *p) /* hw 
IRQs off */
 {
        struct xnthread *thread = xnshadow_thread(p);
 
+       /*
+        * We fire the handler before the thread is migrated, so that
+        * thread->sched does not change between paired invocations of
+        * relax_thread/harden_thread handlers.
+        */
        xnlock_get(&nklock);
+       xnthread_run_handler(thread, harden_thread);
        check_affinity(p);
        xnthread_resume(thread, XNRELAX);
        xnlock_put(&nklock);
@@ -611,37 +617,35 @@ void xnshadow_relax(int notify, int reason)
 
        /*
         * If you intend to change the following interrupt-free
-        * sequence, /first/ make sure to:
-        *
-        * - read commit #d3242401b8
-        *
-        * - check the special handling of XNRELAX in
-        * xnthread_suspend() when switching out the current thread,
-        * not to break basic assumptions we do there.
+        * sequence, /first/ make sure to check the special handling
+        * of XNRELAX in xnthread_suspend() when switching out the
+        * current thread, not to break basic assumptions we make
+        * there.
         *
         * We disable interrupts during the migration sequence, but
         * xnthread_suspend() has an interrupts-on section built in.
         */
        splmax();
        post_wakeup(p);
-
        /*
-        * Task nklock to synchronize the Linux task state
-        * manipulation with do_sigwake_event. nklock will be released
-        * by xnthread_suspend().
+        * Grab the nklock to synchronize the Linux task state
+        * manipulation with handle_sigwake_event. This lock will be
+        * dropped by xnthread_suspend().
         */
        xnlock_get(&nklock);
        set_task_state(p, p->state & ~TASK_NOWAKEUP);
+       xnthread_run_handler(thread, relax_thread);
        xnthread_suspend(thread, XNRELAX, XN_INFINITE, XN_RELATIVE, NULL);
-
        splnone();
+
        if (XENO_DEBUG(NUCLEUS) && !ipipe_root_p)
                xnsys_fatal("xnshadow_relax() failed for thread %s[%d]",
                            thread->name, xnthread_host_pid(thread));
 
        __ipipe_reenter_root();
 
-       xnstat_counter_inc(&thread->stat.ssw);  /* Account for secondary mode 
switch. */
+       /* Account for secondary mode switch. */
+       xnstat_counter_inc(&thread->stat.ssw);
 
        if (xnthread_test_state(thread, XNUSER) && notify) {
                xndebug_notify_relax(thread, reason);


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

Reply via email to