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;
}
}
for (n = 0; n < 4; n++)
task->args[n] = targs ? targs[n] : 0;
xnpod_restart_thread(&task->threadbase);
unlock_and_exit:
xnlock_put_irqrestore(&nklock, s);
return err;
}
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;
rthal_local_irq_flags_hw(flags);
childregs = (struct pt_regs *)((unsigned long)tcb->stackbase +
tcb->stacksize -
RTHAL_SWITCH_FRAME_SIZE);
memset(childregs, 0, sizeof(*childregs));
childregs->gpr[14] = flags & ~(MSR_EE | MSR_FP);
tcb->ts.ksp = (unsigned long)childregs - STACK_FRAME_OVERHEAD;
tcb->entry = entry;
tcb->cookie = cookie;
tcb->self = thread;
tcb->imask = imask;
tcb->name = name;
#ifdef CONFIG_PPC64
childregs->nip = ((unsigned long *)&rthal_thread_trampoline)[0];
childregs->gpr[2] = ((unsigned long *)&rthal_thread_trampoline)[1];
childregs->gpr[15] = ((unsigned long
*)&xnarch_thread_trampoline)[0]; /* lr = entry addr. */
childregs->gpr[16] = ((unsigned long
*)&xnarch_thread_trampoline)[1]; /* r2 = TOC base. */
childregs->gpr[17] = (unsigned long)tcb;
if (cpu_has_feature(CPU_FTR_SLB))
tcb->ts.ksp_vsid = get_stack_vsid(tcb->ts.ksp);
#else /* !CONFIG_PPC64 */
childregs->nip = (unsigned long)&rthal_thread_trampoline;
childregs->gpr[15] = (unsigned long)&xnarch_thread_trampoline;
childregs->gpr[16] = (unsigned long)tcb;
#endif
}
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;
/* Xenomai extension: we accept priority level #0 for creating
non-RT tasks (i.e. underlaid by SCHED_NORMAL pthreads),
which are allowed to call into the pSOS emulator, usually
for synchronization services. */
if (prio > 255)
return ERR_PRIOR;
task = (psostask_t *)xnmalloc(sizeof(*task));
if (!task)
return ERR_NOTCB;
if (flags & T_FPU)
bflags |= XNFPU;
#ifdef CONFIG_XENO_OPT_PERVASIVE
if (flags & T_SHADOW)
bflags |= XNSHADOW;
#endif /* CONFIG_XENO_OPT_PERVASIVE */
ustack += sstack;
if (!(flags & T_SHADOW) && ustack < 1024) {
xnfree(task);
return ERR_TINYSTK;
}
if (name && *name)
xnobject_copy_name(task->name, name);
else
/* i.e. Anonymous object which must be accessible from
user-space. */
sprintf(task->name, "anon_task%lu", psos_task_ids++);
attr.tbase = psos_tbase;
attr.name = task->name;
attr.flags = bflags;
attr.ops = &psos_task_ops;
attr.stacksize = ustack;
param.rt.prio = prio;
if (xnpod_init_thread(&task->threadbase,
&attr, &xnsched_class_rt,
¶m) != 0) {
xnfree(task);
return ERR_NOSTK; /* Assume this is the only possible failure
*/
}
xnthread_time_slice(&task->threadbase) = psos_time_slice;
taskev_init(&task->evgroup);
inith(&task->link);
for (n = 0; n < PSOSTASK_NOTEPAD_REGS; n++)
task->notepad[n] = 0;
initgq(&task->alarmq,
&xnmod_glink_queue,
xnmod_alloc_glinks,
XNMOD_GHOLDER_THRESHOLD);
task->magic = PSOS_TASK_MAGIC;
xnlock_get_irqsave(&nklock, s);
appendq(&psostaskq, &task->link);
*tid_r = (u_long)task;
xnlock_put_irqrestore(&nklock, s);
err = xnthread_register(&task->threadbase, task->name);
if (err) {
t_delete((u_long)task);
return err;
}
xnarch_create_display(&task->threadbase, task->name, psostask);
return SUCCESS;
}
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,
int xnthread_init(struct xnthread *thread,
const struct xnthread_init_attr *attr,
struct xnsched *sched,
struct xnsched_class *sched_class,
const union xnsched_policy_param *sched_param)
{
...................
if (flags & (XNSHADOW|XNROOT))
stacksize = 0;
else {
if (stacksize == 0) /* Pick a reasonable default. */
stacksize = XNARCH_THREAD_STACKSZ;
/* Align stack size on a natural word boundary */
stacksize &= ~(sizeof(long) - 1);
}
......................
Because "if (flags & (XNSHADOW|XNROOT))" is true, the stacksize is 0 and
so tcb->stackbase is NULL. So "t_restart" will crash.
On Thu, 2010-09-23 at 09:38 +0800, [email protected] 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
> [email protected]
> https://mail.gna.org/listinfo/xenomai-help
--
Philippe.
_______________________________________________
Xenomai-help mailing list
[email protected]
https://mail.gna.org/listinfo/xenomai-help