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, gw...@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.


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

Reply via email to