Module: xenomai-head
Branch: master
Commit: e67d12938bc7544ef8eb91ae62dc16370eef1276
URL:    
http://git.xenomai.org/?p=xenomai-head.git;a=commit;h=e67d12938bc7544ef8eb91ae62dc16370eef1276

Author: Philippe Gerum <r...@xenomai.org>
Date:   Tue Dec 22 12:21:52 2009 +0100

psos: send pthread_cancel() upon t_delete

This is a forward port of commit b8e0d499 from the 2.4.x branch.

---

 include/psos+/syscall.h    |    4 ++-
 include/psos+/task.h       |    4 +++
 ksrc/skins/psos+/syscall.c |   38 ++++++++++++++++++++++++++++++++++
 src/skins/psos+/task.c     |   49 ++++++++++++++++++++++++++++++++++++-------
 4 files changed, 86 insertions(+), 9 deletions(-)

diff --git a/include/psos+/syscall.h b/include/psos+/syscall.h
index e53a970..86cc998 100644
--- a/include/psos+/syscall.h
+++ b/include/psos+/syscall.h
@@ -73,13 +73,15 @@
 #define __psos_as_send      45
 /* Xenomai extension: get raw count of jiffies */
 #define __psos_tm_getc      46
+/* Xenomai internal: get hidden pthread_t identifier. */
+#define __psos_t_getpth     47
 
 struct psos_arg_bulk {
-
     u_long a1;
     u_long a2;
     u_long a3;
     u_long a4;
+    u_long a5;
 };
 
 #ifdef __KERNEL__
diff --git a/include/psos+/task.h b/include/psos+/task.h
index d8ab5b9..e5f903a 100644
--- a/include/psos+/task.h
+++ b/include/psos+/task.h
@@ -64,6 +64,10 @@ typedef struct psostask {
 
     } waitargs;
 
+#ifdef CONFIG_XENO_OPT_PERVASIVE
+       u_long pthread; /* hidden pthread_t identifier. */
+#endif
+
 } psostask_t;
 
 static inline psostask_t *thread2psostask (xnthread_t *t)
diff --git a/ksrc/skins/psos+/syscall.c b/ksrc/skins/psos+/syscall.c
index a05d231..31661f4 100644
--- a/ksrc/skins/psos+/syscall.c
+++ b/ksrc/skins/psos+/syscall.c
@@ -68,6 +68,7 @@ static psostask_t *__psos_task_current(struct task_struct *p)
  * a2: u_long prio;
  * a3: u_long flags;
  * a4: unsigned long *mode;
+ * a5: unsigned long ptid;
  */
 
 static int __t_create(struct pt_regs *regs)
@@ -108,6 +109,7 @@ static int __t_create(struct pt_regs *regs)
                 * about the new thread id, so we can manipulate its
                 * TCB pointer freely. */
                tid = xnthread_handle(&task->threadbase);
+               task->pthread = bulk.a5; /* hidden pthread_t identifier. */
                if (__xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs), 
&tid,
                                           sizeof(tid)))
                        return -EFAULT;
@@ -1340,6 +1342,41 @@ static int __as_send(struct pt_regs *regs)
        return as_send((u_long)task, signals);
 }
 
+
+/*
+ * int __t_getpth(u_long tid, u_long *pthread)
+ */
+static int __t_getpth(struct pt_regs *regs)
+{
+       u_long ret = SUCCESS, pthread;
+       xnhandle_t handle;
+       psostask_t *task;
+       spl_t s;
+
+       handle = __xn_reg_arg1(regs);
+
+       xnlock_get_irqsave(&nklock, s);
+
+       if (handle)
+               task = __psos_task_lookup(handle);
+       else
+               task = __psos_task_current(current);
+
+       if (task == NULL)
+               ret = ERR_OBJID;
+       else
+               pthread = task->pthread; /* hidden pthread_t identifier. */
+
+       xnlock_put_irqrestore(&nklock, s);
+
+       if (ret == SUCCESS &&
+           __xn_safe_copy_to_user((void __user *)__xn_reg_arg2(regs),
+                                  &pthread, sizeof(pthread)))
+                       ret = -EFAULT;
+
+       return ret;
+}
+
 static void *psos_shadow_eventcb(int event, void *data)
 {
        struct psos_resource_holder *rh;
@@ -1422,6 +1459,7 @@ static xnsysent_t __systab[] = {
        [__psos_tm_signal] = {&__tm_signal, __xn_exec_primary},
        [__psos_as_send] = {&__as_send, __xn_exec_conforming},
        [__psos_tm_getc] = {&__tm_getc, __xn_exec_any},
+       [__psos_t_getpth] = {&__t_getpth, __xn_exec_any},
 };
 
 extern xntbase_t *psos_tbase;
diff --git a/src/skins/psos+/task.c b/src/skins/psos+/task.c
index 1bf3565..d9b0a1e 100644
--- a/src/skins/psos+/task.c
+++ b/src/skins/psos+/task.c
@@ -72,6 +72,7 @@ static void *psos_task_trampoline(void *cookie)
        bulk.a2 = (u_long)iargs->prio;
        bulk.a3 = (u_long)iargs->flags;
        bulk.a4 = (u_long)xeno_init_current_mode();
+       bulk.a5 = (u_long)pthread_self();
 
        if (!bulk.a4) {
                err = -ENOMEM;
@@ -170,20 +171,23 @@ u_long t_shadow(const char *name, /* Xenomai extension. */
                u_long flags,
                u_long *tid_r)
 {
-       int err;
+       struct psos_arg_bulk bulk;
+       int ret;
 
        pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
        sigshadow_install_once();
 
-       err = XENOMAI_SKINCALL5(__psos_muxid,
-                               __psos_t_create,
-                               name, prio, flags,
-                               tid_r, NULL);
+       bulk.a1 = (u_long)name;
+       bulk.a2 = (u_long)prio;
+       bulk.a3 = (u_long)flags;
+       bulk.a4 = (u_long)tid_r;
+       bulk.a5 = (u_long)pthread_self();
 
-       if (!err)
+       ret = XENOMAI_SKINCALL2(__psos_muxid, __psos_t_create, &bulk, NULL);
+       if (!ret)
                xeno_set_current();
 
-       return err;
+       return ret;
 }
 
 u_long t_start(u_long tid,
@@ -200,7 +204,36 @@ u_long t_start(u_long tid,
 
 u_long t_delete(u_long tid)
 {
-       return XENOMAI_SKINCALL1(__psos_muxid, __psos_t_delete, tid);
+       u_long ptid;
+       long err;
+
+       if (tid == 0)
+               goto self_delete;
+
+       err = XENOMAI_SKINCALL2(__psos_muxid, __psos_t_getpth, tid, &ptid);
+       if (err)
+               return err;
+
+       if ((pthread_t)ptid == pthread_self())
+               goto self_delete;
+
+       err = pthread_cancel((pthread_t)ptid);
+       if (err)
+               return -err; /* differentiate from pSOS codes */
+
+       err = XENOMAI_SKINCALL1(__psos_muxid, __psos_t_delete, tid);
+       if (err == ERR_OBJID)
+               return SUCCESS;
+
+       return err;
+
+self_delete:
+
+        /* Silently migrate to avoid raising SIGXCPU. */
+       XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_LINUX_DOMAIN);
+       pthread_exit(NULL);
+
+       return SUCCESS; /* not reached */
 }
 
 u_long t_suspend(u_long tid)


_______________________________________________
Xenomai-git mailing list
Xenomai-git@gna.org
https://mail.gna.org/listinfo/xenomai-git

Reply via email to