u_long t_mode(u_long mask, u_long newmask, u_long *oldmode) { psostask_t *task; if (!xnpod_primary_p()) return -EPERM; task = psos_current_task(); /* We have no error case here: just clear out any unwanted bit. */ mask &= T_MODE_MASK; newmask &= T_MODE_MASK; *oldmode = xeno_mode_to_psos(xnthread_state_flags(&task->threadbase) & XNTHREAD_MODE_BITS); *oldmode |= ((task->threadbase.imask & 0x7) << 8); if (mask & T_TSLICE) { if (newmask & T_TSLICE) xnpod_set_thread_tslice(&task->threadbase, psos_time_slice); else xnpod_set_thread_tslice(&task->threadbase, XN_INFINITE); mask &= ~T_TSLICE; } if (mask == 0) return SUCCESS; xnpod_set_thread_mode(&task->threadbase, psos_mode_to_xeno(mask), psos_mode_to_xeno(newmask)); /* Reschedule in case the scheduler has been unlocked. */ xnpod_schedule(); return SUCCESS; }
u_long t_start(u_long tid, u_long mode, void (*startaddr) (u_long, u_long, u_long, u_long), u_long targs[]) { u_long err = SUCCESS; xnflags_t xnmode; psostask_t *task; spl_t s; int n; /* We have no error case here: just clear out any unwanted bit. */ mode &= ~T_START_MASK; xnlock_get_irqsave(&nklock, s); 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_ACTIVE; /* Task already started */ goto unlock_and_exit; } xnmode = psos_mode_to_xeno(mode); task->entry = startaddr; #ifdef CONFIG_XENO_OPT_PERVASIVE if (xnthread_test_state(&task->threadbase, XNSHADOW)) { memset(task->args, 0, sizeof(task->args)); /* The shadow will be returned the exact values passed * to t_start(), since the trampoline is performed at * user-space level. We just relay the information * from t_create() to t_start() here.*/ xnpod_start_thread(&task->threadbase, xnmode, (int)((mode >> 8) & 0x7), XNPOD_ALL_CPUS, (void (*)(void *))startaddr, targs); }
u_long t_start(u_long tid, u_long mode, void (*startaddr) (u_long, u_long, u_long, u_long), u_long targs[]) { struct xnthread_start_attr attr; u_long err = SUCCESS; xnflags_t xnmode; psostask_t *task; spl_t s; /* We have no error case here: just clear out any unwanted bit. */ mode &= ~T_START_MASK; xnlock_get_irqsave(&nklock, s); 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_ACTIVE; /* Task already started */ goto unlock_and_exit; } xnmode = psos_mode_to_xeno(mode); if (xnmode & XNRRB) { xnpod_set_thread_tslice(&task->threadbase, psos_time_slice); xnmode &= ~XNRRB; } task->entry = startaddr; attr.mode = xnmode; attr.imask = (int)((mode >> 8) & 0x7); attr.affinity = XNPOD_ALL_CPUS; if (targs) memcpy(task->args, targs, sizeof(task->args)); else memset(task->args, 0, sizeof(task->args)); #ifdef CONFIG_XENO_OPT_PERVASIVE if (xnthread_test_state(&task->threadbase, XNSHADOW)) { attr.entry = (void (*)(void *))startaddr; attr.cookie = (void *)xnthread_handle(&task->threadbase); } else #endif /* CONFIG_XENO_OPT_PERVASIVE */ { attr.entry = psostask_trampoline; attr.cookie = task; } xnpod_start_thread(&task->threadbase, &attr); unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }