Module: xenomai-forge Branch: next 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