static int __ui_twai_flg(struct pt_regs *regs) { UINT flgptn, waiptn, wfmode; TMO tmout; ID flgid; ER err; flgid = __xn_reg_arg2(regs); waiptn = __xn_reg_arg3(regs); wfmode = __xn_reg_arg4(regs); tmout = __xn_reg_arg5(regs); err = twai_flg(&flgptn, flgid, waiptn, wfmode, tmout); if (err == E_OK) { if (__xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &flgptn, sizeof(flgptn))) return -EFAULT; } else if (err == E_RLWAI) { uitask_t *task = ui_current_task(); if (!xnthread_test_info(&task->threadbase, uITRON_TASK_RLWAIT)) err = -EINTR; } return err; }
static int __ui_slp_tsk(struct pt_regs *regs) { ER err = slp_tsk(); if (err == E_RLWAI) { uitask_t *task = ui_current_task(); if (!xnthread_test_info(&task->threadbase, uITRON_TASK_RLWAIT)) err = -EINTR; } return err; }
static int __ui_wai_sem(struct pt_regs *regs) { ID semid = __xn_reg_arg1(regs); ER err; err = wai_sem(semid); if (err == E_RLWAI) { uitask_t *task = ui_current_task(); if (!xnthread_test_info(&task->threadbase, uITRON_TASK_RLWAIT)) err = -EINTR; } return err; }
static int __ui_tslp_tsk(struct pt_regs *regs) { TMO tmout = __xn_reg_arg1(regs); ER err; err = tslp_tsk(tmout); if (err == E_RLWAI) { uitask_t *task = ui_current_task(); if (!xnthread_test_info(&task->threadbase, uITRON_TASK_RLWAIT)) err = -EINTR; } return err; }
static int __ui_rcv_msg(struct pt_regs *regs) { ID mbxid = __xn_reg_arg2(regs); T_MSG *pk_msg; ER err; err = rcv_msg(&pk_msg, mbxid); if (err == E_OK) { if (__xn_safe_copy_to_user((void __user *)__xn_reg_arg1(regs), &pk_msg, sizeof(pk_msg))) return -EFAULT; } else if (err == E_RLWAI) { uitask_t *task = ui_current_task(); if (!xnthread_test_info(&task->threadbase, uITRON_TASK_RLWAIT)) err = -EINTR; } return err; }
static ER wai_flg_helper(UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode, TMO tmout) { xnticks_t timeout; uitask_t *task; uiflag_t *flag; ER err = E_OK; spl_t s; if (xnpod_unblockable_p()) return E_CTX; if (flgid <= 0 || flgid > uITRON_MAX_FLAGID) return E_ID; if (waiptn == 0) return E_PAR; if (tmout == TMO_FEVR) timeout = XN_INFINITE; else if (tmout == 0) timeout = XN_NONBLOCK; else if (tmout < TMO_FEVR) return E_PAR; else timeout = (xnticks_t)tmout; xnlock_get_irqsave(&nklock, s); flag = xnmap_fetch(ui_flag_idmap, flgid); if (!flag) { err = E_NOEXS; goto unlock_and_exit; } if (((wfmode & TWF_ORW) && (waiptn & flag->flgvalue) != 0) || (!(wfmode & TWF_ORW) && ((waiptn & flag->flgvalue) == waiptn))) { *p_flgptn = flag->flgvalue; if (wfmode & TWF_CLR) flag->flgvalue = 0; goto unlock_and_exit; } if (timeout == XN_NONBLOCK) { err = E_TMOUT; goto unlock_and_exit; } else if (xnsynch_pended_p(&flag->synchbase) && !(flag->flgatr & TA_WMUL)) { err = E_OBJ; goto unlock_and_exit; } task = ui_current_task(); xnthread_clear_info(&task->threadbase, uITRON_TASK_RLWAIT); task->wargs.flag.wfmode = wfmode; task->wargs.flag.waiptn = waiptn; xnsynch_sleep_on(&flag->synchbase, timeout, XN_RELATIVE); if (xnthread_test_info(&task->threadbase, XNRMID)) err = E_DLT; /* Flag deleted while pending. */ else if (xnthread_test_info(&task->threadbase, XNTIMEO)) err = E_TMOUT; /* Timeout. */ else if (xnthread_test_info(&task->threadbase, XNBREAK)) err = E_RLWAI; /* rel_wai() or signal received while waiting. */ else *p_flgptn = task->wargs.flag.waiptn; unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }
static ER rcv_msg_helper(T_MSG ** ppk_msg, ID mbxid, TMO tmout) { xnticks_t timeout; uitask_t *task; ER err = E_OK; uimbx_t *mbx; spl_t s; if (xnpod_unblockable_p()) return E_CTX; if (tmout == TMO_FEVR) timeout = XN_INFINITE; else if (tmout == 0) timeout = XN_NONBLOCK; else if (tmout < TMO_FEVR) return E_PAR; else timeout = (xnticks_t)tmout; if (mbxid <= 0 || mbxid > uITRON_MAX_MBXID) return E_ID; xnlock_get_irqsave(&nklock, s); mbx = xnmap_fetch(ui_mbx_idmap, mbxid); if (!mbx) { err = E_NOEXS; goto unlock_and_exit; } if (mbx->mcount > 0) { *ppk_msg = mbx->ring[mbx->rdptr]; mbx->rdptr = (mbx->rdptr + 1) % mbx->bufcnt; mbx->mcount--; goto unlock_and_exit; } if (timeout == XN_NONBLOCK) { err = E_TMOUT; goto unlock_and_exit; } task = ui_current_task(); xnthread_clear_info(&task->threadbase, uITRON_TASK_RLWAIT); xnsynch_sleep_on(&mbx->synchbase, timeout, XN_RELATIVE); if (xnthread_test_info(&task->threadbase, XNRMID)) err = E_DLT; /* Flag deleted while pending. */ else if (xnthread_test_info(&task->threadbase, XNTIMEO)) err = E_TMOUT; /* Timeout. */ else if (xnthread_test_info(&task->threadbase, XNBREAK)) err = E_RLWAI; /* rel_wai() or signal received while waiting. */ else *ppk_msg = task->wargs.msg; unlock_and_exit: xnlock_put_irqrestore(&nklock, s); return err; }