On Fri, 2009-11-13 at 15:11 +0100, Alexandre Coffignal wrote:
> Hello,
> 
> Please find attached a new patch that should take into account your 
> latest remarks.
> This patch has been created using 'git diff -p' command and applies on 
> 2.4.10 revision.
> I'm not sure I fully understand your remark on missing critical section. 
> Indeed, this code is similar to __t_delete routine that doesn't seem to 
> have critical section enforcement?
> Should a critical section be added to it as well ?

No, __t_delete() is safe because it does not directly dereference the
task pointer fetched from the registry, but simply passes it to the
actual t_delete() syscall, which will revalidate that pointer before
doing anything silly with it.

__t_get_pthread() on the other hand, does dereference the task pointer
to fetch the opaque handle, which is unsafe unless this is done within a
critical section.

> Anyway, I tried to replicate __t_ident mechanism as you mentioned.
> 
> Please let me know your feeling about this.
> 
> Fabrice
> 
> > -------- Message original --------
> > Sujet:      Re: [Xenomai-help] How to fix t_delete call in psos skin?
> > Date:       Fri, 06 Nov 2009 12:28:33 +0100
> > De:         Philippe Gerum <r...@xenomai.org>
> > Organisation:       Xenomai
> > Pour ::     Alexandre Coffignal <alexandre.coffig...@cenosys.com>
> > Copie à ::  xenomai-core@gna.org
> > Références:         <4af1474c.7000...@cenosys.com>
> > <1257331856.2210.85.ca...@redshift.xenomai.org>
> > <4af2aef9.2050...@cenosys.com>
> >
> >
> >
> > On Thu, 2009-11-05 at 11:54 +0100, Alexandre Coffignal wrote:
> >
> >   
> >> Does this fix seem more suitable to you?
> >> Do you see someting else missing?
> >>
> >>     
> >
> > The logic is fine, but the implementation should get closer to what is
> > being done in the -head branch.
> >
> > Preliminary remarks:
> >
> > - Please follow the kernel CodingStyle guidelines for anything that is
> > Xenomai-related, including userland code. Keeping a single code style
> > throughout our code makes things easier for reviewing, and keeps visual
> > pollution to the lowest possible level.
> >
> > - Please rebase your work on 2.4.10 for pushing those changes to Xenomai
> > mainline. There is no point for us to consider changes to legacy
> > releases which are not being actively maintained anymore; you can always
> > backport those changes to 2.4.7 locally if you really fancy dealing with
> > bugs solved between 2.4.7 and 2.4.10...
> >
> > - Please tell your CVS/SVN diff tool to use -p, when formatting patches.
> >  
> >   
> >> Please advice.
> >>     
> >
> >   
> >> plain text document attachment (patch_psos_t_delete)
> >> Index: xenomai-2.4.7_bugless/include/psos+/syscall.h
> >> ===================================================================
> >> --- xenomai-2.4.7_bugless.orig/include/psos+/syscall.h     2009-11-05 
> >> 09:12:29.000000000 +0100
> >> +++ xenomai-2.4.7_bugless/include/psos+/syscall.h  2009-11-05 
> >> 09:13:14.000000000 +0100
> >> @@ -73,6 +73,7 @@
> >>  #define __psos_as_send      45
> >>  /* Xenomai extension: get raw count of jiffies */
> >>  #define __psos_tm_getc      46
> >> +#define __psos_t_get_pthread              47      /* get hidden pthread_t 
> >> identifier. */
> >>     
> >
> > psos_t_getpth is enough. To be really, really pSOS-conformant when
> > introducing a routine, we should either use:
> >
> > 1) a preposterously long argument list
> >
> > or, at the very least:
> >  
> > 2) an absolutely unpronounceable C identifier
> >
> > __psos_t_getpth happily qualifies for #2.
> >
> >   
> >>  
> >>  #ifdef __KERNEL__
> >>  
> >> Index: xenomai-2.4.7_bugless/ksrc/skins/psos+/syscall.c
> >> ===================================================================
> >> --- xenomai-2.4.7_bugless.orig/ksrc/skins/psos+/syscall.c  2009-11-05 
> >> 09:16:48.000000000 +0100
> >> +++ xenomai-2.4.7_bugless/ksrc/skins/psos+/syscall.c       2009-11-05 
> >> 09:16:57.000000000 +0100
> >> @@ -67,29 +67,37 @@
> >>    xncompletion_t __user *u_completion;
> >>    u_long prio, flags, tid, err;
> >>    char name[XNOBJECT_NAME_LEN];
> >> +  struct arg_bulk5 bulk;
> >>     
> >
> > Please have a look at what is being done in the -head branch, for the
> > very same routine (in the absence of -p passed to diff, seems to be
> > __t_create). An arg bulk has been introduced there, so you just need to
> > backport this.
> >
> >   
> >>    psostask_t *task;
> >>  
> >> -  if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg1(regs), 4))
> >> +  if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg1(regs), 
> >> sizeof(bulk)))
> >> +          return -EFAULT;
> >> +
> >> +  __xn_copy_from_user(curr, &bulk, (void __user *)__xn_reg_arg1(regs),
> >> +                      sizeof(bulk));
> >> +
> >> +  if (!__xn_access_ok(curr, VERIFY_READ, bulk.a1, sizeof(name))) {
> >>            return -EFAULT;
> >> +  }
> >>  
> >>    /* Get task name. */
> >> -  __xn_strncpy_from_user(curr, name, (const char __user 
> >> *)__xn_reg_arg1(regs),
> >> +  __xn_strncpy_from_user(curr, name, (const char __user *)bulk.a1,
> >>                           sizeof(name) - 1);
> >>    name[sizeof(name) - 1] = '\0';
> >>    strncpy(curr->comm, name, sizeof(curr->comm));
> >>    curr->comm[sizeof(curr->comm) - 1] = '\0';
> >>  
> >>    if (!__xn_access_ok
> >> -      (curr, VERIFY_WRITE, __xn_reg_arg4(regs), sizeof(tid)))
> >> +          (curr, VERIFY_WRITE, bulk.a4, sizeof(tid)))
> >>            return -EFAULT;
> >>  
> >>    /* Task priority. */
> >> -  prio = __xn_reg_arg2(regs);
> >> +  prio = bulk.a2;
> >>    /* Task flags. Force FPU support in user-space. This will lead
> >>       to a no-op if the platform does not support it. */
> >> -  flags = __xn_reg_arg3(regs) | T_SHADOW | T_FPU;
> >> +  flags = bulk.a3 | T_SHADOW | T_FPU;
> >>    /* Completion descriptor our parent thread is pending on. */
> >> -  u_completion = (xncompletion_t __user *)__xn_reg_arg5(regs);
> >> +  u_completion = (xncompletion_t __user *)__xn_reg_arg2(regs);
> >>  
> >>    err = t_create(name, prio, 0, 0, flags, &tid);
> >>  
> >> @@ -99,7 +107,8 @@
> >>             * about the new thread id, so we can manipulate its
> >>             * TCB pointer freely. */
> >>            tid = xnthread_handle(&task->threadbase);
> >> -          __xn_copy_to_user(curr, (void __user *)__xn_reg_arg4(regs), 
> >> &tid,
> >> +          task->opaque2 = bulk.a5; /* hidden pthread_t identifier. */
> >> +          __xn_copy_to_user(curr, (void __user *) bulk.a4, &tid,
> >>                              sizeof(tid));
> >>            err = xnshadow_map(&task->threadbase, u_completion); /* May be 
> >> NULL */
> >>    } else {
> >> @@ -1443,6 +1452,36 @@
> >>    return as_send((u_long)task, signals);
> >>  }
> >>  
> >> +
> >> +/*
> >> + * int __t_get_pthread(u_long tid, u_long *pthread)
> >> + */
> >> +static int __t_get_pthread(struct task_struct *curr, struct pt_regs *regs)
> >> +{
> >> +  xnhandle_t handle;
> >> +  psostask_t *task;
> >> +  u_long pthread;
> >> +
> >> +  handle = __xn_reg_arg1(regs);
> >> +
> >> +  if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg2(regs), 
> >> sizeof(u_long)))
> >> +          return -EFAULT;
> >> +
> >> +  if (handle)
> >> +          task = (psostask_t *)xnregistry_fetch(handle);
> >> +  else
> >> +          task = __psos_task_current(curr);
> >> +
> >> +  if (!task)
> >> +          return ERR_OBJID;
> >>     
> >
> > Critical section enforcement is missing. What if the caller gets
> > preempted after the handle is fetched, and the non-current tid gets
> > killed by a concurrent thread right after? See t_ident for an
> > illustration.
> >
> > If the deletion happens after the critical section, well, we would just
> > have to hope that pthread_cancel() does a good job at validating its
> > handle, but at least we would not have referred to stale memory on our
> > end.
> >
> >   
> >> +
> >> +  pthread = task->opaque2; /* hidden pthread_t identifier. */
> >> +
> >> +  __xn_copy_to_user(curr, (void __user *) __xn_reg_arg2(regs), &pthread, 
> >> sizeof(u_long));
> >> +
> >> +  return SUCCESS;
> >> +}
> >> +
> >>  static void *psos_shadow_eventcb(int event, void *data)
> >>  {
> >>    struct psos_resource_holder *rh;
> >> @@ -1524,6 +1563,7 @@
> >>    [__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_get_pthread] = {&__t_get_pthread, __xn_exec_any},
> >>  };
> >>  
> >>  extern xntbase_t *psos_tbase;
> >> Index: xenomai-2.4.7_bugless/src/skins/psos+/task.c
> >> ===================================================================
> >> --- xenomai-2.4.7_bugless.orig/src/skins/psos+/task.c      2009-11-05 
> >> 09:17:31.000000000 +0100
> >> +++ xenomai-2.4.7_bugless/src/skins/psos+/task.c   2009-11-05 
> >> 09:17:56.000000000 +0100
> >> @@ -26,6 +26,15 @@
> >>  #include <memory.h>
> >>  #include <psos+/psos.h>
> >>  
> >> +struct arg_bulk5{
> >> +
> >> +    u_long a1;
> >> +    u_long a2;
> >> +    u_long a3;
> >> +    u_long a4;
> >> +    u_long a5;
> >> +};
> >>     
> >
> > Rather use psos_arg_bulk like in -head tree.
> >
> >   
> >> +
> >>  extern int __psos_muxid;
> >>  
> >>  struct psos_task_iargs {
> >> @@ -73,6 +82,7 @@
> >>    struct sched_param param;
> >>    int policy;
> >>    long err;
> >> +  struct arg_bulk5 bulk;
> >>  
> >>    policy = psos_task_set_posix_priority(iargs->prio, &param);
> >>    pthread_setschedparam(pthread_self(), policy, &param);
> >> @@ -81,10 +91,14 @@
> >>  
> >>    old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden);
> >>  
> >> -  err = XENOMAI_SKINCALL5(__psos_muxid,
> >> -                          __psos_t_create,
> >> -                          iargs->name, iargs->prio, iargs->flags,
> >> -                          iargs->tid_r, iargs->completionp);
> >> +  bulk.a1 = (u_long)iargs->name;
> >> +  bulk.a2 = (u_long)iargs->prio;
> >> +  bulk.a3 = (u_long)iargs->flags;
> >> +  bulk.a4 = (u_long)iargs->tid_r;
> >> +  bulk.a5 = (u_long)pthread_self();
> >> +
> >> +  err = XENOMAI_SKINCALL2(__psos_muxid, __psos_t_create, &bulk, 
> >> iargs->completionp);
> >> +
> >>    if (err)
> >>            goto fail;
> >>  
> >> @@ -172,14 +186,19 @@
> >>            u_long flags,
> >>            u_long *tid_r)
> >>  {
> >> +  struct arg_bulk5 bulk;
> >> +
> >>    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
> >>  
> >>    old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden);
> >>  
> >> -  return 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();
> >> +
> >> +  return XENOMAI_SKINCALL2(__psos_muxid, __psos_t_create, &bulk, NULL);
> >>  }
> >>  
> >>  u_long t_start(u_long tid,
> >> @@ -196,6 +215,18 @@
> >>  
> >>  u_long t_delete(u_long tid)
> >>  {
> >> +  long err;
> >> +  u_long pthread;
> >> +
> >> +  if(tid)
> >> +  {
> >> +          err = XENOMAI_SKINCALL2(__psos_muxid, __psos_t_get_pthread, 
> >> tid, &pthread);
> >> +          if (err)
> >> +                  return err;
> >> +          err = pthread_cancel((pthread_t)pthread);
> >> +          if (err)
> >> +                  return err;
> >> +  }
> >>     
> >
> > We should handle the self-deletion case specifically:
> >
> > +   else {
> > +           /* Silently migrate to avoid raising SIGXCPU. */
> > +           XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_LINUX_DOMAIN);
> > +           pthread_exit(NULL);
> > +   }
> >
> > Actually, we should also test for the case when a non-zero tid ends up
> > pointing at the current thread as well, e.g.
> >
> >             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 */
> >
> >             return XENOMAI_SKINCALL1(__psos_muxid, __psos_t_delete, tid);
> > self_delete:
> >              /* Silently migrate to avoid raising SIGXCPU. */ 
> >             XENOMAI_SYSCALL1(__xn_sys_migrate, XENOMAI_LINUX_DOMAIN);
> >             pthread_exit(NULL);
> >
> >             return SUCCESS; /* not reached */
> >
> >   
> >>    return XENOMAI_SKINCALL1(__psos_muxid, __psos_t_delete, tid);
> >>  }
> >>  
> >> Index: xenomai-2.4.7_bugless/include/psos+/task.h
> >> ===================================================================
> >> --- xenomai-2.4.7_bugless.orig/include/psos+/task.h        2009-11-05 
> >> 09:19:49.000000000 +0100
> >> +++ xenomai-2.4.7_bugless/include/psos+/task.h     2009-11-05 
> >> 09:19:58.000000000 +0100
> >> @@ -26,6 +26,16 @@
> >>  
> >>  #define PSOS_TASK_MAGIC 0x81810101
> >>  
> >> +struct arg_bulk5{
> >> +
> >> +    u_long a1;
> >> +    u_long a2;
> >> +    u_long a3;
> >> +    u_long a4;
> >> +    u_long a5;
> >> +};
> >> +
> >> +
> >>  typedef struct psostask {
> >>  
> >>      unsigned magic;   /* Magic code - must be first */
> >> @@ -64,6 +74,8 @@
> >>  
> >>      } waitargs;
> >>  
> >> +    u_long opaque2; /* hidden pthread_t identifier. */
> >>     
> >
> > No need to make this more opaque than required to the reviewer; besides,
> > we only need this field when user-space support is compiled in.
> >
> > -   u_long opaque2; /* hidden pthread_t identifier. */
> >
> > +   #ifdef CONFIG_XENO_OPT_PERVASIVE
> > +           u_long pthread;
> > +   #endif
> >
> >   
> >> +
> >>  } psostask_t;
> >>  
> >>  static inline psostask_t *thread2psostask (xnthread_t *t)
> >>     
> >
> >
> >   
> 
> 
> plain text document attachment (patch_psos_t_delete)
> diff --git a/include/psos+/syscall.h b/include/psos+/syscall.h
> index 55ee8a0..25c0a2d 100644
> --- a/include/psos+/syscall.h
> +++ b/include/psos+/syscall.h
> @@ -73,6 +73,16 @@
>  #define __psos_as_send      45
>  /* Xenomai extension: get raw count of jiffies */
>  #define __psos_tm_getc      46
> +#define __psos_t_getpth              47      /* get hidden pthread_t 
> identifier. */
> +
> +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 ca01573..7294f0a 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 1753901..a16cec5 100644
> --- a/ksrc/skins/psos+/syscall.c
> +++ b/ksrc/skins/psos+/syscall.c
> @@ -67,29 +67,37 @@ static int __t_create(struct task_struct *curr, struct 
> pt_regs *regs)
>       xncompletion_t __user *u_completion;
>       u_long prio, flags, tid, err;
>       char name[XNOBJECT_NAME_LEN];
> +     struct psos_arg_bulk bulk;
>       psostask_t *task;
>  
> -     if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg1(regs), 4))
> +     if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg1(regs), 
> sizeof(bulk)))
>               return -EFAULT;
>  
> +     __xn_copy_from_user(curr, &bulk, (void __user *)__xn_reg_arg1(regs),
> +                         sizeof(bulk));
> +
> +     if (!__xn_access_ok(curr, VERIFY_READ, bulk.a1, sizeof(name))) {
> +             return -EFAULT;
> +     }
> +
>       /* Get task name. */
> -     __xn_strncpy_from_user(curr, name, (const char __user 
> *)__xn_reg_arg1(regs),
> +     __xn_strncpy_from_user(curr, name, (const char __user *)bulk.a1,
>                              sizeof(name) - 1);
>       name[sizeof(name) - 1] = '\0';
>       strncpy(curr->comm, name, sizeof(curr->comm));
>       curr->comm[sizeof(curr->comm) - 1] = '\0';
>  
>       if (!__xn_access_ok
> -         (curr, VERIFY_WRITE, __xn_reg_arg4(regs), sizeof(tid)))
> +             (curr, VERIFY_WRITE, bulk.a4, sizeof(tid)))
>               return -EFAULT;
>  
>       /* Task priority. */
> -     prio = __xn_reg_arg2(regs);
> +     prio = bulk.a2;
>       /* Task flags. Force FPU support in user-space. This will lead
>          to a no-op if the platform does not support it. */
> -     flags = __xn_reg_arg3(regs) | T_SHADOW | T_FPU;
> +     flags = bulk.a3 | T_SHADOW | T_FPU;
>       /* Completion descriptor our parent thread is pending on. */
> -     u_completion = (xncompletion_t __user *)__xn_reg_arg5(regs);
> +     u_completion = (xncompletion_t __user *)__xn_reg_arg2(regs);
>  
>       err = t_create(name, prio, 0, 0, flags, &tid);
>  
> @@ -99,7 +107,10 @@ static int __t_create(struct task_struct *curr, struct 
> pt_regs *regs)
>                * about the new thread id, so we can manipulate its
>                * TCB pointer freely. */
>               tid = xnthread_handle(&task->threadbase);
> -             __xn_copy_to_user(curr, (void __user *)__xn_reg_arg4(regs), 
> &tid,
> +             #ifdef CONFIG_XENO_OPT_PERVASIVE
> +             task->pthread = bulk.a5; /* hidden pthread_t identifier. */
> +             #endif
> +             __xn_copy_to_user(curr, (void __user *) bulk.a4, &tid,
>                                 sizeof(tid));
>               err = xnshadow_map(&task->threadbase, u_completion); /* May be 
> NULL */
>       } else {
> @@ -1443,6 +1454,47 @@ static int __as_send(struct task_struct *curr, 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 task_struct *curr, struct pt_regs *regs)
> +{
> +     xnhandle_t handle;
> +     psostask_t *task;
> +     spl_t s;
> +     u_long err = SUCCESS;
> +     u_long pthread;
> +
> +     handle = __xn_reg_arg1(regs);
> +
> +     if (!__xn_access_ok(curr, VERIFY_READ, __xn_reg_arg2(regs), 
> sizeof(u_long)))
> +             return -EFAULT;
> +
> +     xnlock_get_irqsave(&nklock, s);
> +
> +     if (handle)
> +             task = (psostask_t *)xnregistry_fetch(handle);
> +     else
> +             task = __psos_task_current(curr);
> +
> +     if (!task)
> +             err = ERR_OBJID;
> +     else
> +     {
> +             #ifdef CONFIG_XENO_OPT_PERVASIVE
> +             pthread = task->pthread; /* hidden pthread_t identifier. */
> +             #endif
> +     }
> +
> +     xnlock_put_irqrestore(&nklock, s);
> +
> +     if(err == SUCCESS)
> +             __xn_copy_to_user(curr, (void __user *) __xn_reg_arg2(regs), 
> &pthread, sizeof(u_long));
> +
> +     return err;
> +}
> +
>  static void *psos_shadow_eventcb(int event, void *data)
>  {
>       struct psos_resource_holder *rh;
> @@ -1524,6 +1576,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 9358ea8..62e2419 100644
> --- a/src/skins/psos+/task.c
> +++ b/src/skins/psos+/task.c
> @@ -73,6 +73,7 @@ static void *psos_task_trampoline(void *cookie)
>       struct sched_param param;
>       int policy;
>       long err;
> +     struct psos_arg_bulk bulk;
>  
>       policy = psos_task_set_posix_priority(iargs->prio, &param);
>       pthread_setschedparam(pthread_self(), policy, &param);
> @@ -81,10 +82,14 @@ static void *psos_task_trampoline(void *cookie)
>  
>       old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden);
>  
> -     err = XENOMAI_SKINCALL5(__psos_muxid,
> -                             __psos_t_create,
> -                             iargs->name, iargs->prio, iargs->flags,
> -                             iargs->tid_r, iargs->completionp);
> +     bulk.a1 = (u_long)iargs->name;
> +     bulk.a2 = (u_long)iargs->prio;
> +     bulk.a3 = (u_long)iargs->flags;
> +     bulk.a4 = (u_long)iargs->tid_r;
> +     bulk.a5 = (u_long)pthread_self();
> +
> +     err = XENOMAI_SKINCALL2(__psos_muxid, __psos_t_create, &bulk, 
> iargs->completionp);
> +
>       if (err)
>               goto fail;
>  
> @@ -172,14 +177,19 @@ u_long t_shadow(const char *name, /* Xenomai extension. 
> */
>               u_long flags,
>               u_long *tid_r)
>  {
> +     struct psos_arg_bulk bulk;
> +
>       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
>  
>       old_sigharden_handler = signal(SIGHARDEN, &psos_task_sigharden);
>  
> -     return 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();
> +
> +     return XENOMAI_SKINCALL2(__psos_muxid, __psos_t_create, &bulk, NULL);
>  }
>  
>  u_long t_start(u_long tid,
> @@ -196,7 +206,32 @@ u_long t_start(u_long tid,
>  
>  u_long t_delete(u_long tid)
>  {
> +     long err;
> +     u_long ptid;
> +
> +     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 */
> +
>       return XENOMAI_SKINCALL1(__psos_muxid, __psos_t_delete, tid);
> +
> +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-core mailing list
> Xenomai-core@gna.org
> https://mail.gna.org/listinfo/xenomai-core


-- 
Philippe.



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

Reply via email to