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

Author: Jan Kiszka <jan.kis...@siemens.com>
Date:   Wed Nov 20 19:49:38 2013 +0100

cobalt/thread: Provide uninterruptible xnthread_join for RTDM use cases

The semantics of rtdm_task_destroy and rtdm_task_join mandate that the
specified task is truly history by the time these functions return. And
that has to include the case that the caller has a Linux signal pending.
Thus, we need a variant of xnthread_join that waits unconditionally for
thread termination.

This fixes rare crashes when terminating switchtest early.

Signed-off-by: Jan Kiszka <jan.kis...@siemens.com>

---

 include/cobalt/kernel/rtdm/driver.h |    2 +-
 include/cobalt/kernel/thread.h      |    2 +-
 kernel/cobalt/posix/thread.c        |    2 +-
 kernel/cobalt/rtdm/drvlib.c         |    2 +-
 kernel/cobalt/thread.c              |    7 +++++--
 5 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/driver.h 
b/include/cobalt/kernel/rtdm/driver.h
index 0f690d6..3e1795c 100644
--- a/include/cobalt/kernel/rtdm/driver.h
+++ b/include/cobalt/kernel/rtdm/driver.h
@@ -1088,7 +1088,7 @@ void rtdm_task_busy_sleep(nanosecs_rel_t delay);
 static inline void rtdm_task_destroy(rtdm_task_t *task)
 {
        xnthread_cancel(task);
-       xnthread_join(task);
+       xnthread_join(task, true);
 }
 
 static inline int rtdm_task_should_stop(void)
diff --git a/include/cobalt/kernel/thread.h b/include/cobalt/kernel/thread.h
index 5c5e391..76c4ca1 100644
--- a/include/cobalt/kernel/thread.h
+++ b/include/cobalt/kernel/thread.h
@@ -421,7 +421,7 @@ int xnthread_set_slice(struct xnthread *thread,
 
 void xnthread_cancel(struct xnthread *thread);
 
-int xnthread_join(struct xnthread *thread);
+int xnthread_join(struct xnthread *thread, bool uninterruptible);
 
 #ifdef CONFIG_SMP
 int xnthread_migrate(int cpu);
diff --git a/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c
index f8b0e3b..0691bde 100644
--- a/kernel/cobalt/posix/thread.c
+++ b/kernel/cobalt/posix/thread.c
@@ -1120,7 +1120,7 @@ int cobalt_thread_join(unsigned long pth)
        if (thread == NULL)
                return -ESRCH;
 
-       return xnthread_join(&thread->threadbase);
+       return xnthread_join(&thread->threadbase, false);
 }
 
 int cobalt_thread_stat(pid_t pid,
diff --git a/kernel/cobalt/rtdm/drvlib.c b/kernel/cobalt/rtdm/drvlib.c
index c4e2e83..17178ee 100644
--- a/kernel/cobalt/rtdm/drvlib.c
+++ b/kernel/cobalt/rtdm/drvlib.c
@@ -445,7 +445,7 @@ void rtdm_task_join_nrt(rtdm_task_t *task, unsigned int 
poll_delay)
        trace_mark(xn_rtdm, task_joinnrt, "thread %p poll_delay %u",
                   task, poll_delay);
 
-       xnthread_join(task);
+       xnthread_join(task, true);
 }
 
 EXPORT_SYMBOL_GPL(rtdm_task_join_nrt);
diff --git a/kernel/cobalt/thread.c b/kernel/cobalt/thread.c
index 0b61380..9bf2506 100644
--- a/kernel/cobalt/thread.c
+++ b/kernel/cobalt/thread.c
@@ -1508,7 +1508,7 @@ EXPORT_SYMBOL_GPL(xnthread_cancel);
  *
  * @remark Tags: might-switch.
  */
-int xnthread_join(struct xnthread *thread)
+int xnthread_join(struct xnthread *thread, bool uninterruptible)
 {
        unsigned int tag;
        spl_t s;
@@ -1541,7 +1541,10 @@ int xnthread_join(struct xnthread *thread)
                 * wait queue is quite unlikely. In any case, we run in
                 * secondary mode.
                 */
-               if (wait_event_interruptible(nkjoinq, thread->idtag != tag)) {
+               if (uninterruptible)
+                       wait_event(nkjoinq, thread->idtag != tag);
+               else if (wait_event_interruptible(nkjoinq,
+                                                 thread->idtag != tag)) {
                        xnlock_get_irqsave(&nklock, s);
                        if (thread->idtag == tag)
                                xnthread_clear_state(thread, XNJOINED);


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

Reply via email to