static int __sc_delay(struct task_struct *curr, struct pt_regs *regs) { vrtxtask_t *task = vrtx_current_task(); sc_delay(__xn_reg_arg1(regs)); if (xnthread_test_info(&task->threadbase, XNBREAK)) return -EINTR; return 0; }
void sc_spend(int semid, long timeout, int *errp) { vrtxtask_t *task; vrtxsem_t *sem; spl_t s; xnlock_get_irqsave(&nklock, s); sem = xnmap_fetch(vrtx_sem_idmap, semid); if (sem == NULL) { *errp = ER_ID; goto unlock_and_exit; } *errp = RET_OK; if (sem->count > 0) sem->count--; else { if (xnpod_unblockable_p()) { *errp = -EPERM; goto unlock_and_exit; } task = vrtx_current_task(); task->vrtxtcb.TCBSTAT = TBSSEMA; if (timeout) task->vrtxtcb.TCBSTAT |= TBSDELAY; xnsynch_sleep_on(&sem->synchbase, timeout, XN_RELATIVE); if (xnthread_test_info(&task->threadbase, XNBREAK)) *errp = -EINTR; else if (xnthread_test_info(&task->threadbase, XNRMID)) *errp = ER_DEL; /* Semaphore deleted while pending. */ else if (xnthread_test_info(&task->threadbase, XNTIMEO)) *errp = ER_TMO; /* Timeout. */ } unlock_and_exit: xnlock_put_irqrestore(&nklock, s); }