Module: xenomai-forge Branch: next Commit: fd8b9b51a8ee11e02df0e9839cd43bf3a25e050e URL: http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=fd8b9b51a8ee11e02df0e9839cd43bf3a25e050e
Author: Philippe Gerum <r...@xenomai.org> Date: Tue May 6 19:42:23 2014 +0200 copperplate/threadobj: enable signaling remote processes When shared multi-processing is enabled for Copperplate, we may end up signaling threads running in sibling processes from the same session. Make sure to invoke the proper signaling service for this purpose. Copperplate requires thread-directed semantics for all signals used internally: - over Cobalt, sending a pseudo-signal - e.g. SIGRELS, SIGSUSP, SIGRESM - is always considered as a thread-specific operation by the core, and won't fall back as a best-effort, group-directed call even with the kill(2) replacement. - over Mercury, we use the low-level syscall() interface for issuing tkill() to threads which belong to a remote process, since the native kernel performs group-oriented signal delivery with the regular kill(2) and sigqueue(2) interfaces. --- lib/copperplate/internal.c | 14 ++++++++++++-- lib/copperplate/internal.h | 2 ++ lib/copperplate/threadobj.c | 22 +++++++++++++--------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/lib/copperplate/internal.c b/lib/copperplate/internal.c index 86e69af..16513e9 100644 --- a/lib/copperplate/internal.c +++ b/lib/copperplate/internal.c @@ -17,6 +17,7 @@ */ #include <sys/types.h> +#include <sys/syscall.h> #include <stdio.h> #include <stdlib.h> #include <stdarg.h> @@ -25,7 +26,6 @@ #include <signal.h> #include <errno.h> #include <limits.h> -#include <linux/unistd.h> #include <boilerplate/ancillaries.h> #include <copperplate/clockobj.h> #include <copperplate/threadobj.h> @@ -41,7 +41,7 @@ static void *thread_trampoline(void *arg); pid_t copperplate_get_tid(void) { /* - * XXX: The nucleus maintains a hash table indexed on + * The nucleus maintains a hash table indexed on * task_pid_vnr() values for mapped shadows. This is what * __NR_gettid retrieves as well in Cobalt mode. */ @@ -120,6 +120,11 @@ static inline int finish_wait_corespec(struct corethread_attributes *cta) return __bt(copperplate_renice_thread(pthread_self(), cta->prio)); } +int copperplate_kill_tid(pid_t tid, int sig) +{ + return __RT(kill(tid, sig)) ? -errno : 0; +} + #else /* CONFIG_XENO_MERCURY */ int copperplate_probe_node(unsigned int id) @@ -127,6 +132,11 @@ int copperplate_probe_node(unsigned int id) return kill((pid_t)id, 0) == 0; } +int copperplate_kill_tid(pid_t tid, int sig) +{ + return syscall(__NR_tkill, tid, sig) ? -errno : 0; +} + int copperplate_create_thread(struct corethread_attributes *cta, pthread_t *tid) { diff --git a/lib/copperplate/internal.h b/lib/copperplate/internal.h index 9146d31..d195ac0 100644 --- a/lib/copperplate/internal.h +++ b/lib/copperplate/internal.h @@ -77,6 +77,8 @@ extern "C" { pid_t copperplate_get_tid(void); +int copperplate_kill_tid(pid_t tid, int sig); + int copperplate_probe_node(unsigned int id); int copperplate_create_thread(struct corethread_attributes *cta, diff --git a/lib/copperplate/threadobj.c b/lib/copperplate/threadobj.c index 9a4cf0b..8f76618 100644 --- a/lib/copperplate/threadobj.c +++ b/lib/copperplate/threadobj.c @@ -142,27 +142,29 @@ static inline void threadobj_cancel_corespec(struct threadobj *thobj) /* thobj-> * than the caller of threadobj_cancel()), but will receive * the following cancellation request asap. */ - __RT(pthread_kill(thobj->tid, SIGDEMT)); + __RT(kill(thobj->pid, SIGDEMT)); } int threadobj_suspend(struct threadobj *thobj) /* thobj->lock held */ { - pthread_t tid = thobj->tid; + pid_t pid = thobj->pid; int ret; __threadobj_check_locked(thobj); thobj->status |= __THREAD_S_SUSPENDED; - threadobj_unlock(thobj); - ret = __RT(pthread_kill(tid, SIGSUSP)); - threadobj_lock(thobj); + if (thobj == threadobj_current()) { + threadobj_unlock(thobj); + ret = __RT(kill(pid, SIGSUSP)); + threadobj_lock(thobj); + } else + ret = __RT(kill(pid, SIGSUSP)); return __bt(-ret); } int threadobj_resume(struct threadobj *thobj) /* thobj->lock held */ { - pthread_t tid = thobj->tid; int ret; __threadobj_check_locked(thobj); @@ -171,9 +173,7 @@ int threadobj_resume(struct threadobj *thobj) /* thobj->lock held */ return 0; thobj->status &= ~__THREAD_S_SUSPENDED; - threadobj_unlock(thobj); - ret = __RT(pthread_kill(tid, SIGRESM)); - threadobj_lock(thobj); + ret = __RT(kill(thobj->pid, SIGRESM)); return __bt(-ret); } @@ -1255,6 +1255,10 @@ int threadobj_unblock(struct threadobj *thobj) /* thobj->lock held */ } /* Remove standalone DELAY condition. */ + + if (!threadobj_local_p(thobj)) + return __bt(-copperplate_kill_tid(thobj->pid, SIGRELS)); + return __bt(-__RT(pthread_kill(thobj->tid, SIGRELS))); } _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://www.xenomai.org/mailman/listinfo/xenomai-git