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

Author: Philippe Gerum <r...@xenomai.org>
Date:   Sun Jun  9 18:18:39 2013 +0200

cobalt: do thread cleanup over the unmap_thread() handler

---

 kernel/cobalt/nucleus/pod.c    |    6 +-----
 kernel/cobalt/nucleus/sched.c  |    5 +----
 kernel/cobalt/nucleus/shadow.c |   29 ++++++++++++-----------------
 kernel/cobalt/syscall.c        |    1 +
 kernel/cobalt/thread.c         |    6 +-----
 kernel/cobalt/thread.h         |    2 ++
 6 files changed, 18 insertions(+), 31 deletions(-)

diff --git a/kernel/cobalt/nucleus/pod.c b/kernel/cobalt/nucleus/pod.c
index 25cf5d2..117091d 100644
--- a/kernel/cobalt/nucleus/pod.c
+++ b/kernel/cobalt/nucleus/pod.c
@@ -812,7 +812,6 @@ static inline int moving_target(struct xnsched *sched, 
struct xnthread *thread)
 
 static void cleanup_thread(struct xnthread *thread) /* nklock held, irqs off */
 {
-       struct xnpersonality *personality = thread->personality;
        struct xnsched *sched = thread->sched;
 
        trace_mark(xn_nucleus, thread_cleanup, "thread %p thread_name %s",
@@ -847,11 +846,8 @@ static void cleanup_thread(struct xnthread *thread) /* 
nklock held, irqs off */
        __xnpod_giveup_fpu(sched, thread);
 
        if (!moving_target(sched, thread)) {
-               if (personality->ops.unmap_thread)
-                       personality->ops.unmap_thread(thread);
-
+               xnshadow_unmap(thread);
                xnpod_run_hooks(&nkpod->tdeleteq, thread, "DELETE");
-
                xnsched_forget(thread);
                /*
                 * Note: the thread control block must remain
diff --git a/kernel/cobalt/nucleus/sched.c b/kernel/cobalt/nucleus/sched.c
index a45be88..db21bfa 100644
--- a/kernel/cobalt/nucleus/sched.c
+++ b/kernel/cobalt/nucleus/sched.c
@@ -246,8 +246,6 @@ struct xnthread *xnsched_pick_next(struct xnsched *sched)
 /* Must be called with nklock locked, interrupts off. */
 void xnsched_zombie_hooks(struct xnthread *thread)
 {
-       struct xnpersonality *personality = thread->personality;
-
        XENO_BUGON(NUCLEUS, thread->sched->zombie != NULL);
        thread->sched->zombie = thread;
 
@@ -255,8 +253,7 @@ void xnsched_zombie_hooks(struct xnthread *thread)
                   "thread_out %p thread_out_name %s",
                   thread, xnthread_name(thread));
 
-       if (personality->ops.unmap_thread)
-               personality->ops.unmap_thread(thread);
+       xnshadow_unmap(thread);
 
        xnpod_run_hooks(&nkpod->tdeleteq, thread, "DELETE");
 
diff --git a/kernel/cobalt/nucleus/shadow.c b/kernel/cobalt/nucleus/shadow.c
index dc0e66f..0ce58b1 100644
--- a/kernel/cobalt/nucleus/shadow.c
+++ b/kernel/cobalt/nucleus/shadow.c
@@ -1062,31 +1062,24 @@ EXPORT_SYMBOL_GPL(xnshadow_map_kernel);
 
 void xnshadow_unmap(struct xnthread *thread)
 {
+       struct xnpersonality *personality;
        struct xnsys_ppd *sys_ppd;
-       spl_t s;
-
-       if (XENO_DEBUG(NUCLEUS) &&
-           !testbits(xnpod_current_sched()->status, XNKCOUT))
-               xnpod_fatal("xnshadow_unmap() called from invalid context");
 
        trace_mark(xn_nucleus, shadow_unmap,
                   "thread %p thread_name %s pid %d",
                   thread, xnthread_name(thread), xnthread_host_pid(thread));
 
-       xnthread_clear_state(thread, XNMAPPED);
-
-       if (!xnthread_test_state(thread, XNUSER))
-               return;
+       personality = thread->personality;
+       if (personality->ops.unmap_thread)
+               personality->ops.unmap_thread(thread);
 
-       xnlock_get_irqsave(&nklock, s);
-       sys_ppd = xnsys_ppd_get(0);
-       xnlock_put_irqrestore(&nklock, s);
+       xnthread_clear_state(thread, XNMAPPED);
 
-       xnheap_free(&sys_ppd->sem_heap, thread->u_window);
-       thread->u_window = NULL;
-       xnarch_atomic_dec(&sys_ppd->refcnt);
+       if (xnthread_test_state(thread, XNUSER)) {
+               sys_ppd = xnsys_ppd_get(0);
+               xnarch_atomic_dec(&sys_ppd->refcnt);
+       }
 }
-EXPORT_SYMBOL_GPL(xnshadow_unmap);
 
 static int xnshadow_sys_migrate(int domain)
 {
@@ -2188,13 +2181,15 @@ static int handle_taskexit_event(struct task_struct *p) 
/* p == current */
        if (personality->ops.exit_thread)
                personality->ops.exit_thread(thread);
 
-       /* __xnpod_cleanup_thread() -> hook -> xnshadow_unmap() */
+       /* __xnpod_cleanup_thread() -> ... -> xnshadow_unmap() */
        __xnpod_cleanup_thread(thread);
 
        if (xnthread_test_state(thread, XNUSER)) {
                xnlock_get_irqsave(&nklock, s);
                sys_ppd = xnsys_ppd_get(0);
                xnlock_put_irqrestore(&nklock, s);
+               xnheap_free(&sys_ppd->sem_heap, thread->u_window);
+               thread->u_window = NULL;
                mm = xnshadow_current_mm();
                if (!xnarch_atomic_get(&sys_ppd->refcnt))
                        ppd_remove_mm(mm, detach_ppd);
diff --git a/kernel/cobalt/syscall.c b/kernel/cobalt/syscall.c
index c048b66..3c96470 100644
--- a/kernel/cobalt/syscall.c
+++ b/kernel/cobalt/syscall.c
@@ -356,6 +356,7 @@ struct xnpersonality cobalt_personality = {
        .ops = {
                .attach_process = cobalt_process_attach,
                .detach_process = cobalt_process_detach,
+               .unmap_thread = cobalt_thread_unmap,
        },
 };
 EXPORT_SYMBOL_GPL(cobalt_personality);
diff --git a/kernel/cobalt/thread.c b/kernel/cobalt/thread.c
index f02919e..5a4ef74 100644
--- a/kernel/cobalt/thread.c
+++ b/kernel/cobalt/thread.c
@@ -190,7 +190,7 @@ static void thread_destroy(pthread_t thread)
        xnheap_schedule_free(&kheap, thread, &thread->link);
 }
 
-static void thread_delete_hook(struct xnthread *thread)
+void cobalt_thread_unmap(struct xnthread *thread)
 {
        pthread_t tid = thread2pthread(thread);
 
@@ -200,10 +200,7 @@ static void thread_delete_hook(struct xnthread *thread)
        cobalt_mark_deleted(tid);
        cobalt_timer_cleanup_thread(tid);
        thread_destroy(tid);
-
        cobalt_thread_unhash(&tid->hkey);
-       if (xnthread_test_state(thread, XNMAPPED))
-               xnshadow_unmap(thread);
 }
 
 /**
@@ -1372,7 +1369,6 @@ void cobalt_thread_pkg_init(u_long rrperiod)
 {
        initq(&cobalt_global_kqueues.threadq);
        cobalt_time_slice = rrperiod;
-       xnpod_add_hook(XNHOOK_THREAD_DELETE, thread_delete_hook);
 }
 
 /*@}*/
diff --git a/kernel/cobalt/thread.h b/kernel/cobalt/thread.h
index c184633..2bae1c7 100644
--- a/kernel/cobalt/thread.h
+++ b/kernel/cobalt/thread.h
@@ -122,6 +122,8 @@ int cobalt_sched_setconfig_np(int cpu,
                              union sched_config __user *u_config,
                              size_t len);
 
+void cobalt_thread_unmap(struct xnthread *thread);
+
 void cobalt_thread_pkg_init(u_long rrperiod);
 
 /* round-robin period. */


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

Reply via email to