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

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

Reply via email to