Module: xenomai-jki Branch: for-forge Commit: 7f28f772c97b72b5a6c6c6051aa8009bfd7fa4a8 URL: http://git.xenomai.org/?p=xenomai-jki.git;a=commit;h=7f28f772c97b72b5a6c6c6051aa8009bfd7fa4a8
Author: Jan Kiszka <jan.kis...@siemens.com> Date: Wed Nov 20 19:49:38 2013 +0100 cobalt/kernel: 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/thread.h | 2 +- include/rtdm/rtdm_driver.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/thread.h b/include/cobalt/kernel/thread.h index aa2fd46..6328049 100644 --- a/include/cobalt/kernel/thread.h +++ b/include/cobalt/kernel/thread.h @@ -417,7 +417,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/include/rtdm/rtdm_driver.h b/include/rtdm/rtdm_driver.h index 3c8c270..71a03ab 100644 --- a/include/rtdm/rtdm_driver.h +++ b/include/rtdm/rtdm_driver.h @@ -1094,7 +1094,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/kernel/cobalt/posix/thread.c b/kernel/cobalt/posix/thread.c index 7ba91fc..75fc1f1 100644 --- a/kernel/cobalt/posix/thread.c +++ b/kernel/cobalt/posix/thread.c @@ -1108,7 +1108,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 30ea6a3..bd35f9a 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 a6cb852..76a2443 100644 --- a/kernel/cobalt/thread.c +++ b/kernel/cobalt/thread.c @@ -1583,7 +1583,7 @@ EXPORT_SYMBOL_GPL(xnthread_cancel); * Rescheduling: always if @a thread did not terminate yet at the time * of the call. */ -int xnthread_join(struct xnthread *thread) +int xnthread_join(struct xnthread *thread, bool uninterruptible) { unsigned int tag; spl_t s; @@ -1616,7 +1616,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