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, 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