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