All of lore.kernel.org
 help / color / mirror / Atom feed
* [Xenomai-help] 回复:Re:  How to add "t_restart" to pSoS emulator
@ 2010-09-23  7:15 gwysu
  2010-09-23  8:21 ` Philippe Gerum
  0 siblings, 1 reply; 2+ messages in thread
From: gwysu @ 2010-09-23  7:15 UTC (permalink / raw)
  To: Philippe Gerum; +Cc: Xenomai-help

[-- Attachment #1: Type: text/plain, Size: 8201 bytes --]

Yes, the t_restart have been available, but it doesn't work and will crash. Below is the code of t_restart
 
 
u_long t_restart(u_long tid, u_long targs[])
{
 u_long err = SUCCESS;
 psostask_t *task;
 spl_t s;
 int n;
 if (xnpod_unblockable_p())
  return -EPERM;
 xnlock_get_irqsave(&nklock, s);
 if (tid == 0)
  task = psos_current_task();
 else {
  task = psos_h2obj_active(tid, PSOS_TASK_MAGIC, psostask_t);
  if (!task) {
   err = psos_handle_error(tid, PSOS_TASK_MAGIC, psostask_t);
   goto unlock_and_exit;
  }
  if (xnthread_test_state(&task->threadbase, XNDORMANT)) {
   err = ERR_NACTIVE;
   goto unlock_and_exit;
  }
 }
&nbsp;for (n = 0; n < 4; n++)
&nbsp;&nbsp;task->args[n] = targs ? targs[n] : 0;
&nbsp;xnpod_restart_thread(&task->threadbase);
unlock_and_exit:
&nbsp;xnlock_put_irqrestore(&nklock, s);
&nbsp;return err;
}
&nbsp;
&nbsp;
The t_restart will call xnpod_restart_thread and furthermore call "xnarch_init_thread" in the&nbsp;/asm-powerpc/bit/pod.h for powerpc arch. And&nbsp;will&nbsp;crash&nbsp;when&nbsp;" memset(childregs, 0, sizeof(*childregs));" is excuted. which&nbsp;because the value of the tcb->stackbase&nbsp;&nbsp;is NULL. We can explain the reasion by analysis of the "t_create" later.
&nbsp;
&nbsp;
&nbsp;
static inline void xnarch_init_thread(xnarchtcb_t * tcb,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void (*entry) (void *),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *cookie,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int imask,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct xnthread *thread, char *name)
{
&nbsp;struct pt_regs *childregs;
&nbsp;unsigned long flags;
&nbsp;rthal_local_irq_flags_hw(flags);
&nbsp;childregs = (struct pt_regs *)((unsigned long)tcb->stackbase +
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tcb->stacksize - RTHAL_SWITCH_FRAME_SIZE);
&nbsp;memset(childregs, 0, sizeof(*childregs));
&nbsp;childregs->gpr[14] = flags & ~(MSR_EE | MSR_FP);
&nbsp;tcb->ts.ksp = (unsigned long)childregs - STACK_FRAME_OVERHEAD;
&nbsp;tcb->entry = entry;
&nbsp;tcb->cookie = cookie;
&nbsp;tcb->self = thread;
&nbsp;tcb->imask = imask;
&nbsp;tcb->name = name;
#ifdef CONFIG_PPC64
&nbsp;childregs->nip = ((unsigned long *)&rthal_thread_trampoline)[0];
&nbsp;childregs->gpr[2] = ((unsigned long *)&rthal_thread_trampoline)[1];
&nbsp;childregs->gpr[15] = ((unsigned long *)&xnarch_thread_trampoline)[0];&nbsp;/* lr = entry addr. */
&nbsp;childregs->gpr[16] = ((unsigned long *)&xnarch_thread_trampoline)[1];&nbsp;/* r2 = TOC base. */
&nbsp;childregs->gpr[17] = (unsigned long)tcb;
&nbsp;if (cpu_has_feature(CPU_FTR_SLB))
&nbsp;&nbsp;tcb->ts.ksp_vsid = get_stack_vsid(tcb->ts.ksp);
#else /* !CONFIG_PPC64 */
&nbsp;childregs->nip = (unsigned long)&rthal_thread_trampoline;
&nbsp;childregs->gpr[15] = (unsigned long)&xnarch_thread_trampoline;
&nbsp;childregs->gpr[16] = (unsigned long)tcb;
#endif
}
&nbsp;
&nbsp;
&nbsp;
&nbsp;
Below is the code of t_create:
&nbsp;
&nbsp;
&nbsp;
u_long t_create(const char *name,
&nbsp;&nbsp;u_long prio,
&nbsp;&nbsp;u_long sstack, u_long ustack, u_long flags, u_long *tid_r)
{
&nbsp;union xnsched_policy_param param;
&nbsp;struct xnthread_init_attr attr;
&nbsp;xnflags_t bflags = 0;
&nbsp;psostask_t *task;
&nbsp;u_long err;
&nbsp;spl_t s;
&nbsp;int n;
&nbsp;/* Xenomai extension: we accept priority level #0 for creating
&nbsp;&nbsp;&nbsp; non-RT tasks (i.e. underlaid by SCHED_NORMAL pthreads),
&nbsp;&nbsp;&nbsp; which are allowed to call into the pSOS emulator, usually
&nbsp;&nbsp;&nbsp; for synchronization services. */
&nbsp;if (prio > 255)
&nbsp;&nbsp;return ERR_PRIOR;
&nbsp;task = (psostask_t *)xnmalloc(sizeof(*task));
&nbsp;if (!task)
&nbsp;&nbsp;return ERR_NOTCB;
&nbsp;if (flags & T_FPU)
&nbsp;&nbsp;bflags |= XNFPU;
#ifdef CONFIG_XENO_OPT_PERVASIVE
&nbsp;if (flags & T_SHADOW)
&nbsp;&nbsp;bflags |= XNSHADOW;
#endif /* CONFIG_XENO_OPT_PERVASIVE */
&nbsp;ustack += sstack;
&nbsp;if (!(flags & T_SHADOW) && ustack < 1024) {
&nbsp;&nbsp;xnfree(task);
&nbsp;&nbsp;return ERR_TINYSTK;
&nbsp;}
&nbsp;if (name && *name)
&nbsp;&nbsp;xnobject_copy_name(task->name, name);
&nbsp;else
&nbsp;&nbsp;/* i.e. Anonymous object which must be accessible from
&nbsp;&nbsp;&nbsp;&nbsp; user-space. */
&nbsp;&nbsp;sprintf(task->name, "anon_task%lu", psos_task_ids++);
&nbsp;attr.tbase = psos_tbase;
&nbsp;attr.name = task->name;
&nbsp;attr.flags = bflags;
&nbsp;attr.ops = &psos_task_ops;
&nbsp;attr.stacksize = ustack;
&nbsp;param.rt.prio = prio;
&nbsp;if (xnpod_init_thread(&task->threadbase,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &attr, &xnsched_class_rt, &param) != 0) {
&nbsp;&nbsp;xnfree(task);
&nbsp;&nbsp;return ERR_NOSTK;&nbsp;/* Assume this is the only possible failure */
&nbsp;}
&nbsp;xnthread_time_slice(&task->threadbase) = psos_time_slice;
&nbsp;taskev_init(&task->evgroup);
&nbsp;inith(&task->link);
&nbsp;for (n = 0; n < PSOSTASK_NOTEPAD_REGS; n++)
&nbsp;&nbsp;task->notepad[n] = 0;
&nbsp;initgq(&task->alarmq,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &xnmod_glink_queue,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xnmod_alloc_glinks,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XNMOD_GHOLDER_THRESHOLD);
&nbsp;task->magic = PSOS_TASK_MAGIC;
&nbsp;xnlock_get_irqsave(&nklock, s);
&nbsp;appendq(&psostaskq, &task->link);
&nbsp;*tid_r = (u_long)task;
&nbsp;xnlock_put_irqrestore(&nklock, s);
&nbsp;err = xnthread_register(&task->threadbase, task->name);
&nbsp;if (err) {
&nbsp;&nbsp;t_delete((u_long)task);
&nbsp;&nbsp;return err;
&nbsp;}
&nbsp;xnarch_create_display(&task->threadbase, task->name, psostask);
&nbsp;return SUCCESS;
}
&nbsp;
&nbsp;
Let's analysize the code of "t_create":
Because CONFIG_XENO_OPT_PERVASIVE must be defined for pSoS mulator, the "t_create" will call "xnpod_init_thread" defined in the /nucleus/pod.c, and furthermore call "xnthread_init" defined in /nucleus/thread.c,
&nbsp;
int xnthread_init(struct xnthread *thread,
&nbsp;&nbsp;&nbsp; const struct xnthread_init_attr *attr,
&nbsp;&nbsp;&nbsp; struct xnsched *sched,
&nbsp;&nbsp;&nbsp; struct xnsched_class *sched_class,
&nbsp;&nbsp;&nbsp; const union xnsched_policy_param *sched_param)
{
&nbsp;
...................
&nbsp;
if (flags & (XNSHADOW|XNROOT))
&nbsp;&nbsp;stacksize = 0;
&nbsp;else {
&nbsp;&nbsp;if (stacksize == 0) /* Pick a reasonable default. */
&nbsp;&nbsp;&nbsp;stacksize = XNARCH_THREAD_STACKSZ;
&nbsp;&nbsp;/* Align stack size on a natural word boundary */
&nbsp;&nbsp;stacksize &= ~(sizeof(long) - 1);
&nbsp;}

......................
&nbsp;
Because "if (flags & (XNSHADOW|XNROOT))" &nbsp;is true, the stacksize is 0 and so&nbsp; tcb->stackbase&nbsp;&nbsp;is NULL. So "t_restart" will crash.

&nbsp;

&nbsp;
&nbsp;


On Thu, 2010-09-23 at 09:38 +0800, gwysu@sina.com wrote:
> Hi all, 
> 
> 
> 
> Currenly, the pSoS emulator doesn't support the syscall "t_restart",
> Is it difficulty to add it to the pSoS emulator? Does anyone have a
> idea about it? Thanks.

Doable, but not trivial from user-space; you would need support from the
in-kernel emulator to reset the tcb properly, before playing the
setjmp/longjmp game in userland to emulate the code restart. The
t_restart() call already available from kernel space does most of the
first part, but the second one would require some work.

pSOS introduced t_restart() mainly as a way to force the target task to
run some cleanup code before self-deleting, because this call could
unblock that task from any syscall it was pending on. If this matches
your current use case, then you have other ways to emulate this in a
linux/Xenomai environment - typically sending a thread-directed linux
signal to the target task, running the cleanup code in the signal
handler, and issuing t_delete(0) to finish there.

> 
> 
> 
> 
> 
> 
> 
> 
> 
> Best regards
> 
> Wenyi Gao
> 
> _______________________________________________
> Xenomai-help mailing list
> Xenomai-help@gna.org
> https://mail.gna.org/listinfo/xenomai-help

-- 
Philippe.



[-- Attachment #2: Type: text/html, Size: 9510 bytes --]

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [Xenomai-help] 回复:Re:  How to add "t_restart" to pSoS emulator
  2010-09-23  7:15 [Xenomai-help] 回复:Re: How to add "t_restart" to pSoS emulator gwysu
@ 2010-09-23  8:21 ` Philippe Gerum
  0 siblings, 0 replies; 2+ messages in thread
From: Philippe Gerum @ 2010-09-23  8:21 UTC (permalink / raw)
  To: gwysu; +Cc: Xenomai-help

On Thu, 2010-09-23 at 15:15 +0800, gwysu@domain.hid wrote:
> Yes, the t_restart have been available, but it doesn't work and will
> crash. Below is the code of t_restart

> 
>  
> 
> u_long t_restart(u_long tid, u_long targs[])
> {
>  u_long err = SUCCESS;
>  psostask_t *task;
>  spl_t s;
>  int n;
> 

<snip>

Well, thanks. But I think I have a copy of this one somewhere on my
laptop...

>  
> 
> The t_restart will call xnpod_restart_thread and furthermore call
> "xnarch_init_thread" in the /asm-powerpc/bit/pod.h for powerpc arch.
> And will crash when " memset(childregs, 0, sizeof(*childregs));" is
> excuted. which because the value of the tcb->stackbase  is NULL. We
> can explain the reasion by analysis of the "t_create" later.
> 
>  
> 
>  
> 
>  
> 
> static inline void xnarch_init_thread(xnarchtcb_t * tcb,
>           void (*entry) (void *),
>           void *cookie,
>           int imask,
>           struct xnthread *thread, char *name)
> {
>  struct pt_regs *childregs;
>  unsigned long flags;
> 

Oh, yep. I have this one too...

>  
> 
> Below is the code of t_create:
> 
>  
> 
>  
> 
>  
> 
> u_long t_create(const char *name,
>   u_long prio,
>   u_long sstack, u_long ustack, u_long flags, u_long *tid_r)
> {
>  union xnsched_policy_param param;
>  struct xnthread_init_attr attr;
>  xnflags_t bflags = 0;
>  psostask_t *task;
>  u_long err;
>  spl_t s;
>  int n;
> 

And I can find this one in the Xenomai tree as well. Good.

> 
> Let's analysize the code of "t_create":
> 

Sure, let's do this.

> Because CONFIG_XENO_OPT_PERVASIVE must be defined for pSoS mulator,
> the "t_create" will call "xnpod_init_thread" defined in
> the /nucleus/pod.c, and furthermore call "xnthread_init" defined
> in /nucleus/thread.c,
> 

Any pSOS task would call xnpod_init_thread actually. Any task running in
a Xenomai system in fact. That is how a Xenomai thread is created,
regardless of the skin being used, or user-space/pervasive support being
enabled or not.

> 
> Because "if (flags & (XNSHADOW|XNROOT))"  is true, the stacksize is 0
> and so  tcb->stackbase  is NULL. So "t_restart" will crash.
> 

Yes, it will, precisely because t_restart() is not currently supported
for user-space tasks. So you are observing a crash while using
t_restart() in kernel space, called from an invalid context. Hence my
comment below:

> The
> t_restart() call already available from kernel space does most of the
> first part, but the second one would require some work.
> 

Meaning: t_restart() currently illustrates how to reset a TCB, which is
most of what you need to implement the kernel-side of that feature.
Most, not all. Handling shadow threads is what is missing.

It seems you did not care that much about my observation regarding
whether you really want to emulate a call like t_restart(). Maybe you
should consider it.

PS: please, don't top post.

-- 
Philippe.




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-09-23  8:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-23  7:15 [Xenomai-help] 回复:Re: How to add "t_restart" to pSoS emulator gwysu
2010-09-23  8:21 ` Philippe Gerum

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.