int __rtai_task_suspend(RT_TASK *task) { int err = 0; spl_t s; if (!task) { if (!xnpod_primary_p()) return -EINVAL; task = rtai_current_task(); } xnlock_get_irqsave(&nklock, s); task = rtai_h2obj_validate(task, RTAI_TASK_MAGIC, RT_TASK); if (!task) { err = -EINVAL; goto unlock_and_exit; } if (task->suspend_depth++ == 0) { xnpod_suspend_thread(&task->thread_base, XNSUSP, XN_INFINITE, XN_RELATIVE, NULL); if (xnthread_test_info(&task->thread_base, XNBREAK)) err = -EINTR; } unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }
static int __wind_msgq_send(struct pt_regs *regs) { xnhandle_t handle = __xn_reg_arg1(regs); char tmp_buf[128], *msgbuf; wind_msgq_t *msgq; int timeout, prio; unsigned nbytes; STATUS err; nbytes = __xn_reg_arg3(regs); timeout = __xn_reg_arg4(regs); prio = __xn_reg_arg5(regs); if (timeout != NO_WAIT && !xnpod_primary_p()) return -EPERM; msgq = (wind_msgq_t *)xnregistry_fetch(handle); if (!msgq) return S_objLib_OBJ_ID_ERROR; if (nbytes > msgq->msg_length) return S_msgQLib_INVALID_MSG_LENGTH; if (nbytes <= sizeof(tmp_buf)) msgbuf = tmp_buf; else { msgbuf = (char *)xnmalloc(nbytes); if (!msgbuf) return S_memLib_NOT_ENOUGH_MEMORY; } /* This is sub-optimal since we end up copying the data twice. */ if (__xn_safe_copy_from_user(msgbuf, (void __user *)__xn_reg_arg2(regs), nbytes)) err = -EFAULT; else { if (msgQSend((MSG_Q_ID)msgq, msgbuf, nbytes, timeout, prio) == ERROR) err = wind_errnoget(); else err = 0; } if (msgbuf != tmp_buf) xnfree(msgbuf); return err; }
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_setreg(u_long tid, u_long regnum, u_long regvalue) { u_long err = SUCCESS; psostask_t *task; spl_t s; xnlock_get_irqsave(&nklock, s); if (tid == 0) { if (!xnpod_primary_p()) return -EPERM; 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 (regnum >= PSOSTASK_NOTEPAD_REGS) { err = ERR_REGNUM; goto unlock_and_exit; } task->notepad[regnum] = regvalue; unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }