Hi, I'm creating my RT threads using the native API and I'm creating mqueues, wrapped to the pthread_rt library. I can read and write the mqueue (and it goes through Xenomai), but when I select() on a receiving mqd_t, the select() calls returns that there is data available on the mq (it fills in the FD_SET), but keeps doing so even when it's empty (the select() is in a loop). Also, it's modeswitching like nuts.
I found out that the __wrap_select is correctly called, but returns -EPERM. Kernel sources indicate that this is caused by pse51_current_thread() alias thread2pthread() returning null. Since EPERM is returned to userspace, the __real_select is called from user space, causing the mode switches and bad behaviour. This is almost certainly the thing that native + RTDM + select() is seeing too. My mqueues-only work probably because mq.c only uses pse51_current_thread() in the mq_notify function. I'm guessing that mq_notify would also not work in combination with native skin. I had two options in fixing this: add a xnselector to the native task struct or to the nucleus xnthread_t. I choose the latter, such that every skin kan use select() + RTDM and migrate gradualy to the RTDM and/or Posix skin. I needed to free the xnselector structure in xnpod_delete_thread() , I chose a spot, but it causes a segfault in my native thread (which did the select) during program cleanup. Any advice ? Also, maybe we should separate select() from the posix skin and put it in a separate place (in RTDM as rtdm_select() ?), such that we can start building around it (posix just forwards to rtdm_select() then). A second patch was necessary to return the timeout case properly to userspace (independent of first patch). Tested with native + posix loaded and mq. If you never quit your application, this works :-) (maybe we discuss this better further on xenomai-core) Thanks for the wonderful XUM-2009 experience btw ! Peter
From 0380298181f2926e6abe05e6b3d0b02389892a7c Mon Sep 17 00:00:00 2001 From: Peter Soetens <[email protected]> Date: Thu, 1 Oct 2009 15:57:54 +0200 Subject: [PATCH] Move posix selector in nucleus for every skin to use. This patch makes the select implementation in syscall.c independent of the posix skin. --- include/nucleus/thread.h | 3 +++ ksrc/nucleus/pod.c | 6 ++++++ ksrc/nucleus/thread.c | 2 ++ ksrc/skins/posix/syscall.c | 6 +++--- ksrc/skins/posix/thread.c | 7 ------- ksrc/skins/posix/thread.h | 4 ---- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/nucleus/thread.h b/include/nucleus/thread.h index 3eefb53..88a14cc 100644 --- a/include/nucleus/thread.h +++ b/include/nucleus/thread.h @@ -142,6 +142,7 @@ struct xnthread; struct xnsched; struct xnsynch; struct xnrpi; +struct xnselector; typedef struct xnthrops { @@ -208,6 +209,8 @@ typedef struct xnthread { xnstat_exectime_t lastperiod; /* Interval marker for execution time reports */ } stat; + struct xnselector *selector;/* For select. */ + int errcode; /* Local errno */ xnasr_t asr; /* Asynchronous service routine */ diff --git a/ksrc/nucleus/pod.c b/ksrc/nucleus/pod.c index 9348ce1..2dd08ca 100644 --- a/ksrc/nucleus/pod.c +++ b/ksrc/nucleus/pod.c @@ -41,6 +41,7 @@ #include <nucleus/registry.h> #include <nucleus/module.h> #include <nucleus/stat.h> +#include <nucleus/select.h> #include <asm/xenomai/bits/pod.h> /* debug support */ @@ -1204,6 +1205,11 @@ void xnpod_delete_thread(xnthread_t *thread) xntimer_destroy(&thread->rtimer); xntimer_destroy(&thread->ptimer); + if (thread->selector) { + xnselector_destroy(thread->selector); + thread->selector = NULL; + } + if (xnthread_test_state(thread, XNPEND)) xnsynch_forget_sleeper(thread); diff --git a/ksrc/nucleus/thread.c b/ksrc/nucleus/thread.c index 5fceaec..ed9722e 100644 --- a/ksrc/nucleus/thread.c +++ b/ksrc/nucleus/thread.c @@ -95,6 +95,8 @@ int xnthread_init(xnthread_t *thread, thread->asr = XNTHREAD_INVALID_ASR; thread->asrlevel = 0; + thread->selector = NULL; + thread->iprio = prio; thread->bprio = prio; thread->cprio = prio; diff --git a/ksrc/skins/posix/syscall.c b/ksrc/skins/posix/syscall.c index d936f21..f4afd29 100644 --- a/ksrc/skins/posix/syscall.c +++ b/ksrc/skins/posix/syscall.c @@ -2382,12 +2382,12 @@ static int __select(struct task_struct *curr, struct pt_regs *regs) xntmode_t mode = XN_RELATIVE; struct xnselector *selector; struct timeval tv; - pthread_t thread; + xnthread_t* thread; int i, err, nfds; size_t fds_size; - thread = pse51_current_thread(); - if (!thread) + thread = xnpod_current_thread(); + if ( !thread ) return -EPERM; if (__xn_reg_arg5(regs)) { diff --git a/ksrc/skins/posix/thread.c b/ksrc/skins/posix/thread.c index ad4aaa5..6e89625 100644 --- a/ksrc/skins/posix/thread.c +++ b/ksrc/skins/posix/thread.c @@ -78,12 +78,6 @@ static void thread_delete_hook(xnthread_t *xnthread) pse51_mark_deleted(thread); pse51_signal_cleanup_thread(thread); pse51_timer_cleanup_thread(thread); -#ifdef CONFIG_XENO_OPT_POSIX_SELECT - if (thread->selector) { - xnselector_destroy(thread->selector); - thread->selector = NULL; - } -#endif /* CONFIG_XENO_OPT_POSIX_SELECT */ switch (thread_getdetachstate(thread)) { case PTHREAD_CREATE_DETACHED: @@ -216,7 +210,6 @@ int pthread_create(pthread_t *tid, pse51_signal_init_thread(thread, cur); pse51_tsd_init_thread(thread); pse51_timer_init_thread(thread); - thread->selector = NULL; if (thread->attr.policy == SCHED_RR) { xnthread_time_slice(&thread->threadbase) = pse51_time_slice; diff --git a/ksrc/skins/posix/thread.h b/ksrc/skins/posix/thread.h index 33b14fd..fc8c6fe 100644 --- a/ksrc/skins/posix/thread.h +++ b/ksrc/skins/posix/thread.h @@ -21,7 +21,6 @@ #define _POSIX_THREAD_H #include <posix/internal.h> -#include <nucleus/select.h> typedef unsigned long long pse51_sigset_t; @@ -91,9 +90,6 @@ struct pse51_thread { /* For timers. */ xnqueue_t timersq; - /* For select. */ - struct xnselector *selector; - #ifdef CONFIG_XENO_OPT_PERVASIVE struct pse51_hkey hkey; #endif /* CONFIG_XENO_OPT_PERVASIVE */ -- 1.6.0.4
From c406e7ce881927c2744d60503f0710d9b91fa5f4 Mon Sep 17 00:00:00 2001 From: Peter Soetens <[email protected]> Date: Thu, 1 Oct 2009 16:20:51 +0200 Subject: [PATCH] posix: Fix __wrap_select() when timeout happens. --- src/skins/posix/select.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/src/skins/posix/select.c b/src/skins/posix/select.c index 3076d9c..2104009 100644 --- a/src/skins/posix/select.c +++ b/src/skins/posix/select.c @@ -23,9 +23,15 @@ int __wrap_select (int __nfds, fd_set *__restrict __readfds, return __real_select(__nfds, __readfds, __writefds, __exceptfds, __timeout); + /* timeout */ + if (err == 0) + return 0; + + /* success */ if (err > 0) return err; + /* failure */ errno = -err; return -1; } -- 1.6.0.4
_______________________________________________ Xenomai-help mailing list [email protected] https://mail.gna.org/listinfo/xenomai-help
